Фронтенд на чистому JavaScript: швидкі віджети та анімації

Зауважимо: коли бандл вашого додатку важить більше 2 МБ, а LCP сягає за 3 секунди, причина часто криється в надлишковості фреймворка. Для embed-віджетів, анімацій на JS або розширень браузера **Vanilla JavaScript (чистий JavaScript)** стає єдиним адекватним вибором. Ми реалізували понад 30 проєктів

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Фронтенд на чистому JavaScript: швидкі віджети та анімації
Середній
~3-5 днів

Наші компетенції:

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1418
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1286
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    983
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1243
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    983
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    998

Зауважимо: коли бандл вашого додатку важить більше 2 МБ, а LCP сягає за 3 секунди, причина часто криється в надлишковості фреймворка. Для embed-віджетів, анімацій на JS або розширень браузера Vanilla JavaScript (чистий JavaScript) стає єдиним адекватним вибором. Ми реалізували понад 30 проєктів без жодного фреймворка, забезпечивши LCP менше 1 секунди та бандл розміром 20–40 КБ. Відсутність віртуального DOM і прямий доступ до браузерних API дають максимальну продуктивність сайту, а економія бюджету на розробку сягає 40% (до 50 000 ₴ на типовому віджеті). Вартість розробки простого віджету починається від 10 000 ₴. Наша команда використовує сучасні можливості мови: Web Components, IntersectionObserver, Proxy та ESModules, щоб створювати швидкі та надійні рішення. Наша команда має 10+ років досвіду у веб-розробці та виконала 30+ проєктів на чистому JavaScript. Кожен проєкт починається з аудиту метрик та підбору оптимальної архітектури. Зв'яжіться з нами для аудиту вашого проєкту.

Коли Vanilla JS стає єдиним вірним вибором

Vanilla JS виправданий у сценаріях, де фреймворки додають зайву складність. Embed-віджети вбудовуються на чужі сайти — не можна конфліктувати з їхніми фреймворками. Бібліотеки для npm з нульовими залежностями не обтяжують проєкт користувачів з іншим стеком. Високонавантажені анімації на JS використовують Canvas API, WebGL та Web Animations API безпосередньо, без прошарку virtual DOM. Розширення браузера працюють в ізольованому середовищі Content Scripts, де фреймворки збільшують ризики. Статичні сайти з мінімальною інтерактивністю не потребують 50 КБ заради одного дропдауна. Типовий віджет на Vanilla JS обійдеться на 30-50% дешевше, ніж на React.

Сценарій Vanilla JS React Vue
embed-віджет оптимально надлишково надлишково
SPA з формами складно оптимально оптимально
Анімації відмінно середньо середньо

В одному з проєктів ми замінили React-віджет кошика на Vanilla JS. Бандл скоротився з 120 КБ до 28 КБ (зниження на 77%), LCP впав з 2,4 с до 0,8 с (на 67% швидше). Навантаження на CPU знизилося на 40%. Vanilla JS завантажується в 2 рази швидше React на повільних з'єднаннях, а економія на розробці склала близько 40 000 ₴. У порівнянні з React, бандл Vanilla JS в 3-4 рази менший, а LCP — в 2-3 рази швидший.

Чому Vanilla JS продуктивніший за фреймворки?

Відсутність virtual DOM виключає накладні витрати на порівняння та перемальовування. Пряма робота з document.createElement та appendChild дозволяє керувати кожним оновленням вручну. У поєднанні з IntersectionObserver для лінивого завантаження та requestAnimationFrame для анімацій ви отримуєте LCP менше 1 секунди навіть на мобільних пристроях. Ми також використовуємо preload для критичних ресурсів і prefetch для наступних сторінок. Використання замикань для приватних методів та прототипного наслідування дозволяє досягти високої продуктивності без зайвих абстракцій. Делегування подій та мемоізація скорочують кількість обчислень. Оптимізація LCP досягається через пряму роботу з DOM та мінімізацію перебудов. Скорочення бандла на 77% та економія бюджету на розробку до 40% — не рідкість при міграції на чистий JS.

Характеристика Vanilla JS React (типовий проєкт)
Розмір бандла 20–40 KB 80–150 KB (з React DOM)
Контроль повний обмежений virtual DOM
Залежності нульові React + екосистема
Сумісність будь-який сайт може конфліктувати
Продуктивність LCP < 1 с 1–2 с (середнє)

Які сучасні можливості Vanilla JS доступні

Браузерні API значно розширилися: тепер доступні Custom Elements, Shadow DOM, AbortController, Proxy, Service Workers. Приклад Fetch з таймаутом:

async function fetchWithTimeout(url, options = {}, timeoutMs = 5000) { const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), timeoutMs); try { const response = await fetch(url, { ...options, signal: controller.signal }); if (!response.ok) throw new Error(`HTTP ${response.status}`); return await response.json(); } finally { clearTimeout(timeout); } } 

Web Components — компонентна модель без фреймворка

class ProductCard extends HTMLElement { static get observedAttributes() { return ['product-id']; } connectedCallback() { this.#render(); this.#attachEvents(); } attributeChangedCallback(name, oldVal, newVal) { if (name === 'product-id' && oldVal !== newVal) { this.#fetchProduct(newVal); } } async #fetchProduct(id) { const data = await fetchWithTimeout(`/api/products/${id}`); this.#update(data); } #render() { this.innerHTML = ` <article class="product-card"> <img class="product-card__img" alt=""> <h3 class="product-card__name"></h3> <span class="product-card__price"></span> <button class="product-card__btn">В кошик</button> </article> `; } #update({ name, price, image }) { this.querySelector('.product-card__img').src = image; this.querySelector('.product-card__name').textContent = name; this.querySelector('.product-card__price').textContent = `${price} ₴`; } #attachEvents() { this.querySelector('.product-card__btn').addEventListener('click', () => { this.dispatchEvent(new CustomEvent('add-to-cart', { bubbles: true, detail: { productId: this.getAttribute('product-id') } })); }); } } customElements.define('product-card', ProductCard); 

MDN: Web ComponentsВикористання в HTML: <product-card product-id="42"></product-card>. Працює в будь-якому фреймворку або без нього.

Як керувати станом без зайвих бібліотек? Реактивний store з Proxy

function createStore(initialState) { const listeners = new Set(); const state = new Proxy(structuredClone(initialState), { set(target, key, value) { target[key] = value; listeners.forEach(fn => fn(structuredClone(target))); return true; } }); return { state, subscribe: (fn) => { listeners.add(fn); return () => listeners.delete(fn); }, getSnapshot: () => structuredClone(state), }; } const cartStore = createStore({ items: [], total: 0 }); cartStore.subscribe(state => { document.getElementById('cart-count').textContent = state.items.length; }); 

Структура проєкту з ESModules

src/ components/ product-card.js modal.js lib/ store.js api.js utils.js pages/ catalog.js product.js app.js 
{ "type": "module", "scripts": { "dev": "vite", "build": "vite build" }, "devDependencies": { "vite": "^5.0.0" } } 

Нульових runtime-залежностей. Vite тільки для розробки та збірки.

Як ми працюємо над проєктами на Vanilla JS

  1. Аналітика — визначаємо критичні сценарії, заміряємо метрики (LCP, TTFB).
  2. Проєктування — архітектура модулів, карта компонентів, API-контракти.
  3. Реалізація — ітеративна розробка з код-рев'ю та тестами (Vitest + jsdom).
  4. Оптимізація — bundle splitting, prefetch, lazy loading, tree-shake.
  5. Деплой — збірка через Vite, викладка на CDN або хостинг.

Що входить в роботу

  • Вихідний код на ESModules з коментарями.
  • Документація по компонентах та інструкція з розгортання.
  • Гарантія підтримки 3 місяці після здачі.
  • Метрики продуктивності до та після.

Строки орієнтовно

  • Простий віджет (до 5 компонентів) — від 2 до 5 днів.
  • Середній проєкт (до 20 компонентів) — від 1 до 3 тижнів.
  • Комплексний додаток (до 50 компонентів) — від 4 до 8 тижнів.

Вартість розраховується індивідуально. Оцінимо ваш проєкт безкоштовно — напишіть нам. Обговоримо ваш проєкт — замовте консультацію. Додаткова економія бюджету до 50 000 ₴ можлива при міграції з фреймворків.