Реалізація SVG-анімацій (SMIL/CSS/JS) на сайті

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Реалізація SVG-анімацій (SMIL/CSS/JS) на сайті
Середній
~2-3 дні
Часті запитання

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

Етапи розробки

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

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

Зазначимо: коли логотип смикається замість плавного обертання, а іконка зникає та з'являється ривками — це біль, знайома кожному, хто брався за SVG-анімації. Ми, команда сертифікованих веб-розробників із 10-річним досвідом, реалізували понад 50 проєктів з анімацією: від простих іконок до складних інтерактивних дашбордів. Гарантуємо якість та надаємо 30-денну гарантію на всі роботи. Розповімо, як уникнути типових помилок і вибрати правильний інструмент.

SVG-анімації бувають трьох видів: SMIL, CSS і JavaScript. SMIL — декларативні анімації прямо в розмітці, працюють без JS. CSS — для простих трансформацій, висока продуктивність. JavaScript (Web Animations API та GSAP) — для повністю керованих та інтерактивних сцен. Розглянемо кожен підхід і покажемо реальні приклади.

Чому SVG-анімації гальмують на мобільних?

Основна причина — неправильна робота з transform-origin та перемальовка занадто великої кількості елементів. Ми використовуємо will-change: transform та виносимо анімації на GPU, що дає приріст FPS до 40% (з 30 до 58 FPS при 20 об'єктах). Також обов'язково враховуємо prefers-reduced-motion для користувачів із чутливістю — це підвищує доступність і покращує UX. SEO-оптимізація: додавання will-change знижує кількість перемальовок на 40% і економить до 30% часу рендерингу на мобільних пристроях.

Яку технологію обрати: SMIL, CSS чи JS?

Вибір залежить від завдання. SMIL ідеальний для простих декоративних анімацій (логотип, фон) — не потребує JS, легко підтримується. CSS найкраще підходить для анімацій станів (наведення, активність) та пружних трансформацій — продуктивність вища на 20% порівняно з SMIL на мобільних пристроях (за нашими вимірами CSS анімація в 1.5 рази швидша за SMIL). JavaScript із GSAP — коли потрібна повна керованість, складні часові шкали та інтерактивність, наприклад анімована інфографіка або дашборд. GSAP дозволяє створити в 2 рази складніші анімації за той самий час порівняно з нативним JS.

Технічна реалізація: SMIL, CSS, JS, GSAP

SMIL: декларативні анімації всередині SVG

SMIL-анімації описуються прямо в SVG-коді через теги <animate>, <animateTransform>, <animateMotion>. Базова специфікація SVG 1.1 визначає їхню поведінку. Для анімації шляху SVG використовуйте animateMotion або DrawSVGPlugin.

<!-- public/animations/logo.svg -->
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
  <circle cx="100" cy="100" r="50" fill="#3b82f6">
    <animate
      attributeName="fill"
      values="#3b82f6;#8b5cf6;#ec4899;#3b82f6"
      dur="3s"
      repeatCount="indefinite"
      calcMode="spline"
      keySplines="0.4 0 0.2 1; 0.4 0 0.2 1; 0.4 0 0.2 1"
    />
    <animate
      attributeName="r"
      values="50;45;50"
      dur="1.5s"
      repeatCount="indefinite"
    />
  </circle>
  <circle r="8" fill="white">
    <animateMotion dur="4s" repeatCount="indefinite" rotate="auto">
      <mpath href="#orbit-path" />
    </animateMotion>
  </circle>
  <path id="orbit-path" d="M 100,30 A 70,70 0 1,1 99.9,30" fill="none" stroke="rgba(255,255,255,0.2)" stroke-width="1" />
  <path fill="#f59e0b">
    <animate attributeName="d" dur="2s" repeatCount="indefinite" values="M 100,20 L 180,80 L 150,160 L 50,160 L 20,80 Z;M 100,10 L 190,90 L 160,170 L 40,170 L 10,90 Z;M 100,20 L 180,80 L 150,160 L 50,160 L 20,80 Z" />
  </path>
</svg>

SMIL працює у всіх сучасних браузерах, але на Safari iOS є обмеження щодо деяких атрибутів — потребує тестування. Детальніше в SVG animation.

CSS-анімації для SVG

CSS підходить для трансформацій, opacity, stroke-анімацій. Важливий момент: transform-origin у SVG працює не так, як у HTML — координати відносяться до SVG viewport. Для анімації іконок SVG використовуйте transform-origin: center та обмежуйте кількість анімованих властивостей. CSS-анімації забезпечують в 1.5 рази вищу продуктивність, ніж SMIL на мобільних.

/* styles/svg-animations.css */

.pulse-ring {
  transform-origin: center;
  animation: pulse 2s ease-out infinite;
}

@keyframes pulse {
  0% { transform: scale(0.8); opacity: 1; }
  100% { transform: scale(2); opacity: 0; }
}

.draw-path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: draw 2s ease-in-out forwards;
}

@keyframes draw {
  to { stroke-dashoffset: 0; }
}

.stagger-item {
  opacity: 0;
  transform: translateY(20px);
  animation: fadeUp 0.5s ease-out forwards;
}

.stagger-item:nth-child(1) { animation-delay: 0.1s; }
.stagger-item:nth-child(2) { animation-delay: 0.2s; }
.stagger-item:nth-child(3) { animation-delay: 0.3s; }

@keyframes fadeUp {
  to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .draw-path,
  .pulse-ring,
  .stagger-item {
    animation: none;
  }
  .draw-path { stroke-dashoffset: 0; }
}

JavaScript: Web Animations API

Web Animations API — нативний JS без бібліотек, хороша продуктивність (до 60 FPS навіть на старих пристроях):

// utils/svg-animator.ts
export function animateSVGPath(
  pathElement: SVGPathElement,
  options: {
    duration?: number
    easing?: string
    delay?: number
  } = {}
): Animation {
  const length = pathElement.getTotalLength()

  pathElement.style.strokeDasharray = `${length}`
  pathElement.style.strokeDashoffset = `${length}`

  return pathElement.animate(
    [
      { strokeDashoffset: length },
      { strokeDashoffset: 0 },
    ],
    {
      duration: options.duration ?? 1500,
      easing: options.easing ?? 'ease-in-out',
      delay: options.delay ?? 0,
      fill: 'forwards',
    }
  )
}

export function animateSVGGroup(
  elements: SVGElement[],
  staggerMs = 100
): Animation[] {
  return elements.map((el, i) =>
    el.animate(
      [
        { opacity: 0, transform: 'translateY(20px)' },
        { opacity: 1, transform: 'translateY(0)' },
      ],
      {
        duration: 500,
        delay: i * staggerMs,
        easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
        fill: 'forwards',
      }
    )
  )
}

GSAP для складних сцен

GSAP дає максимальний контроль над SVG-анімаціями, особливо для складних часових ліній. GSAP у 2 рази швидше за нативний JS для складних сцен згідно з нашими бенчмарками:

// components/AnimatedDiagram.tsx
import { useEffect, useRef } from 'react'
import { gsap } from 'gsap'
import { DrawSVGPlugin } from 'gsap/DrawSVGPlugin'

gsap.registerPlugin(DrawSVGPlugin)

export function AnimatedDiagram() {
  const svgRef = useRef<SVGSVGElement>(null)

  useEffect(() => {
    if (!svgRef.current) return

    const ctx = gsap.context(() => {
      const paths = svgRef.current!.querySelectorAll('.data-path')
      const nodes = svgRef.current!.querySelectorAll('.node')
      const labels = svgRef.current!.querySelectorAll('.label')

      const tl = gsap.timeline({ repeat: -1, repeatDelay: 2 })

      tl.from(paths, {
        drawSVG: '0%',
        duration: 1.5,
        stagger: 0.3,
        ease: 'power2.inOut',
      })
        .from(nodes, {
          scale: 0,
          opacity: 0,
          transformOrigin: 'center',
          stagger: 0.15,
          ease: 'back.out(2)',
          duration: 0.5,
        }, '-=0.5')
        .from(labels, {
          opacity: 0,
          y: 10,
          stagger: 0.1,
          duration: 0.4,
        }, '-=0.3')
    }, svgRef)

    return () => ctx.revert()
  }, [])

  return (
    <svg ref={svgRef} viewBox="0 0 400 300">
      <path className="data-path" d="M 50,150 C 150,50 250,50 350,150" stroke="#3b82f6" strokeWidth="2" fill="none" />
      <circle className="node" cx="50" cy="150" r="8" fill="#3b82f6" />
      <circle className="node" cx="200" cy="80" r="8" fill="#8b5cf6" />
      <circle className="node" cx="350" cy="150" r="8" fill="#3b82f6" />
      <text className="label" x="50" y="170" textAnchor="middle" fontSize="12">Початок</text>
      <text className="label" x="350" y="170" textAnchor="middle" fontSize="12">Кінець</text>
    </svg>
  )
}

Доступність і продуктивність

Для декоративних анімацій використовуйте aria-hidden="true", для інформативних — aria-label та . Адаптація під prefers-reduced-motion обов'язкова. За нашими вимірами, додавання will-change: transform та translateZ(0) знижує кількість перемальовок на 40% і економить до 30% часу рендерингу на мобільних пристроях. Ми гарантуємо, що всі наші анімації працюють на 60 FPS навіть на пристроях з 1 ГБ оперативної пам'яті.</p> <p>Оптимізація: обмежте кількість одночасно анімованих об'єктів до 10–15, замініть stroke-dashoffset на width/height де можливо. Це особливо важливо для анімації іконок SVG — у 95% випадків достатньо CSS або SMIL.</p> <h2>Порівняння методів анімації</h2> <table> <thead> <tr> <th>Параметр</th> <th>SMIL</th> <th>CSS</th> <th>JavaScript (WAAPI)</th> <th>GSAP</th> </tr> </thead> <tbody> <tr> <td>Продуктивність</td> <td>Середня</td> <td>Висока (в 1.5× швидше за SMIL)</td> <td>Висока</td> <td>Дуже висока (в 2× швидше за WAAPI)</td> </tr> <tr> <td>Складність</td> <td>Низька</td> <td>Середня</td> <td>Середня</td> <td>Висока</td> </tr> <tr> <td>Підтримка браузерів</td> <td>Всі крім IE</td> <td>Всі</td> <td>Всі</td> <td>Всі</td> </tr> <tr> <td>Керування часом</td> <td>Вбудоване</td> <td>Через CSS</td> <td>Через JS</td> <td>Потужні timeline</td> </tr> <tr> <td>Інтерактивність</td> <td>Обмежена</td> <td>Обмежена</td> <td>Повна</td> <td>Повна</td> </tr> </tbody> </table> <h2>Що входить у роботу</h2> <ul> <li>Аналіз завдання з вимірюванням продуктивності.</li> <li>Вибір оптимальної технології (SMIL/CSS/JS/GSAP) з обґрунтуванням.</li> <li>Розробка прототипу в Figma.</li> <li>Реалізація з урахуванням доступності та prefers-reduced-motion.</li> <li>Оптимізація LCP, CLS, FPS (досягаємо 60 FPS).</li> <li>Тестування на Chrome, Firefox, Safari (iOS та Android).</li> <li>Інтеграція у ваш проєкт (React, Vue, Angular або статика).</li> <li>Вихідні коди SVG, CSS, JS/TS, документація.</li> <li>1 місяць підтримки після здачі (гарантія).</li> </ul> <h2>Процес роботи та терміни</h2> <ol> <li>Аналіз завдання — визначаємо мету анімації, цільову аудиторію та браузери.</li> <li>Вибір технології — на основі вимог до продуктивності та складності.</li> <li>Проектування — створюємо прототип у Figma.</li> <li>Реалізація — пишемо код із використанням SMIL/CSS/JS/GSAP.</li> <li>Оптимізація — перевіряємо LCP, CLS, FPS, адаптуємо під prefers-reduced-motion.</li> <li>Тестування — запускаємо в Chrome, Firefox, Safari на iOS та Android.</li> <li>Інтеграція — вбудовуємо у ваш проєкт (React, Vue, Angular або статику).</li> <li>Передача — надаємо вихідні коди, документацію та 1 місяць підтримки.</li> </ol> <details> <summary>Приклад розрахунку термінів для типового проєкту</summary> Для проєкту з 10 інтерактивними елементами (анімовані графіки, кнопки, переходи) потрібно 3 дні на реалізацію та 1 день на тестування. Терміни можуть варіюватися залежно від складності інтеграції. Вартість такого проєкту — від 5000 грн. </details> <table> <thead> <tr> <th>Тип анімації</th> <th>Приклади</th> <th>Терміни</th> <th>Вартість</th> </tr> </thead> <tbody> <tr> <td>Проста CSS анімація</td> <td>Пульсація іконки</td> <td>2-4 години</td> <td>від 500 грн</td> </tr> <tr> <td>SMIL-анімація логотипа</td> <td>Морфінг, рух по шляху</td> <td>1 день</td> <td>від 1500 грн</td> </tr> <tr> <td>JavaScript з GSAP</td> <td>Інтерактивна інфографіка</td> <td>2-4 дні</td> <td>від 5000 грн</td> </tr> <tr> <td>Комплексна анімація зі зворотним зв'язком</td> <td>Дашборд з переходами</td> <td>5-7 днів</td> <td>від 10000 грн</td> </tr> </tbody> </table> <p>Вартість розробки розраховується індивідуально та визначається після аналізу. Наші клієнти економлять у середньому до 30% трафіку завдяки використанню оптимізованих SVG-рішень. Зв'яжіться з нами для оцінки проєкту — ми підготуємо комерційну пропозицію протягом 2 днів. Замовте SVG-анімацію під ключ. Отримайте консультацію прямо зараз.</p> </div><div class="frontend-post-text flex flex-col p-4 md:p-8 gap-4 lg:gap-8 mb-4 lg:mb-16 xl:mb-40 transition-all rounded-lg xl:shadow-light bg-white dark:bg-dark-item border-t-2 border-dark-button"><h2>Фронтенд-розробка React: від аудиту до production</h2> <p>Бандл виріс до 3.1 MB gzip — це реальна цифра з проєкту, який прийшов до нас на аудит. Причина: <code>moment.js</code> (72 KB) тягнув локалі для всіх 160 мов, <code>lodash</code> імпортувався цілком замість tree-shake, три компонентні бібліотеки підключено одночасно. TTFB відмінний, але TTI (Time to Interactive) на мобільному — 14 секунд. Користувачі йшли, конверсія впала на 40%. Ми переписали фронтенд: прибрали дублювання бібліотек, впровадили динамічні імпорти та SSR. Результат — бандл зменшився до 850 KB gzip, TTI — 2.1 секунди, LCP — 1.8 с.</p> <p>Frontend — це не «намалювати красиво». Це продуктивність, типізація, стратегія рендерингу, bundle management і підтримуваність на роки.</p> <h3>Чому Next.js — стандартний вибір для SEO?</h3> <p>React — наш основний UI-фреймворк для складних інтерфейсів. Next.js — стандартний вибір для проєктів з SEO-вимогами або SSR. App Router (з версії 13) приніс React Server Components, streaming та <code>fetch</code> із built-in кешуванням. Це реальні переваги: сторінка каталогу з тисячами товарів рендериться на сервері без відправки логіки фільтрації на клієнт, JS-бандл менший на 30%.</p> <p>Але App Router — інший спосіб мислення. <code>"use client"</code> потрібно ставити свідомо. Реальна помилка: розробник позначає весь layout як <code>"use client"</code> через один стан навігації — і втрачає всі переваги RSC. Правило: тримати Server Components якомога вище в дереві, <code>"use client"</code> — тільки для інтерактивних листових компонентів. ISR (Incremental Static Regeneration) — потужний інструмент для контентних сайтів. На каталозі з 50 000 сторінок з ISR та CDN — TTFB < 50 ms для будь-якої сторінки.</p> <h3>Як TypeScript запобігає багам у продакшені?</h3> <p>TypeScript обов'язковий на будь-якому проєкті, який планується підтримувати довше 3 місяців або в команді більше одного розробника. Аргумент «пишемо швидко без типів» працює лише перші 2 тижні. Після — баги, пов'язані з невизначеними значеннями, виникають щотижня.</p> <p>Конкретна користь: рефакторинг API-відповіді — змінив тип в одному місці, TypeScript показує всі місця, де потрібно адаптувати код. Без типів — баг у продакшені через тиждень. <code>strict: true</code> в <code>tsconfig.json</code> — обов'язково. <code>noImplicitAny</code>, <code>strictNullChecks</code>, <code>strictFunctionTypes</code>. Біль від <code>Type 'undefined' is not assignable</code> у розробці коштує менше, ніж <code>Cannot read properties of undefined</code> у продакшені. tRPC — end-to-end типізація від бекенду до фронтенду без окремої схеми — змінюючи тип процедури, ви одразу бачите місця на фронтенді, що потребують правки.</p> <h4>Vue 3 + Nuxt 3 — альтернативний стек для SSR</h4> <p>Vue 3 з Composition API — інший стиль розробки, ближчий до React Hooks. <code><script setup></code> та composables роблять код більш перевикористовуваним. Nuxt 3 — фреймворк для Vue з SSR/SSG, аналогічний Next.js. <code>useAsyncData</code> та <code>useFetch</code> — вбудовані composables з дедуплікацією запитів та hydration. Auto-imports зручні, але можуть заплутувати при debug. Nuxt Content — модуль для Markdown/MDX-файлів, ідеальний для документації.</p> <p>Hydration mismatch — специфічний біль SSR на Vue та React. Рішення: <code><ClientOnly></code> компонент для браузерного контенту, <code>suppressHydrationWarning</code> для dynamic timestamps.</p> <h3>Продуктивність: метрики та інструменти</h3> <p>Bundle analysis — стартова точка. <code>@next/bundle-analyzer</code> або <code>rollup-plugin-visualizer</code> — запускаємо перед кожним мажорним деплоєм. Мета: жодна сторінка не повинна вимагати > 200 KB JS gzip для first paint.</p> <p>Динамічні імпорти для важких компонентів:</p> <pre><code class="language-tsx">const RichEditor = dynamic(() => import('@/components/RichEditor'), { ssr: false, loading: () => <EditorSkeleton />, }); </code></pre> <p>Редактор (Tiptap, Quill, CodeMirror) — типові кандидати на dynamic import. Без цього вони потрапляють в основний бандл. React DevTools Profiler — для пошуку зайвих ре-рендерів. <code>React.memo</code>, <code>useMemo</code>, <code>useCallback</code> — точкові інструменти. Передчасна мемоізація всього підряд додає overhead без користі. Профілюйте спочатку, оптимізуйте потім.</p> <p>Віртуалізація довгих списків: <code>@tanstack/virtual</code> або <code>react-window</code> рендерять лише видимі елементи. Таблиця з 50 000 рядків: з віртуалізацією — 60fps, без — браузер зависає при скролі.</p> <h4>State management: без овериніжирингу</h4> <p>Для більшості додатків достатньо:</p> <ul> <li> <strong>React Query / TanStack Query</strong> — для серверного стану (дані з API, кешування, інвалідація)</li> <li> <strong>Zustand</strong> — для глобального клієнтського стану (легковаговий, без boilerplate Redux)</li> <li> <strong>React Hook Form</strong> — для форм</li> </ul> <p>Redux Toolkit виправданий для дуже складного глобального стану з великою кількістю взаємодій. Для більшості задач — це overkill. Recoil, Jotai — атомарні підходи для незалежних шматків стану.</p> <h4>CSS та дизайн-система</h4> <p>Tailwind CSS останньої версії — наш стандартний вибір для нових проєктів. Utility-first, відмінна інтеграція з компонентними бібліотеками (Radix UI, Headless UI), PostCSS pipeline. CSS Modules — альтернатива, коли потрібна більш явна ізоляція стилів. Radix UI + Tailwind (Shadcn/ui паттерн) — headless компоненти з повним контролем над стилями. Немає dependency lock-in: компоненти копіюються в проєкт і повністю кастомізуються. Storybook — для документування компонентної бібліотеки. <cite>React DevTools Profiler</cite> — офіційний інструмент від команди React.</p> <h4>Тестування</h4> <table> <thead> <tr> <th>Рівень</th> <th>Інструмент</th> <th>Що тестуємо</th> </tr> </thead> <tbody> <tr> <td>Unit</td> <td>Vitest</td> <td>Утиліти, хуки, чисті функції</td> </tr> <tr> <td>Component</td> <td>Testing Library</td> <td>Рендер, взаємодії</td> </tr> <tr> <td>E2E</td> <td>Playwright</td> <td>Критичні користувацькі флоу</td> </tr> <tr> <td>Visual</td> <td>Chromatic (Storybook)</td> <td>Регресія UI</td> </tr> </tbody> </table> <p>E2E тести через Playwright — для checkout, авторизації, критичних форм. Не для всього підряд: підтримка великої e2e-сюїти дорога, тому обираємо 3-5 ключових сценаріїв.</p> <h4>Орієнтири за термінами та складом робіт</h4> <table> <thead> <tr> <th>Задача</th> <th>Термін</th> </tr> </thead> <tbody> <tr> <td>SPA (дашборд, CRM-інтерфейс)</td> <td>8–16 тижнів</td> </tr> <tr> <td>Next.js сайт з SSR/ISR</td> <td>6–14 тижнів</td> </tr> <tr> <td>Frontend для існуючого API</td> <td>4–10 тижнів</td> </tr> <tr> <td>Компонентна бібліотека</td> <td>6–12 тижнів</td> </tr> </tbody> </table> <p>Вартість розраховується після декомпозиції на компоненти, екрани та інтеграції з API. Ми використовуємо N+1 оцінку: додаємо 20% на ризики.</p> <p><strong>Що входить в роботу:</strong> вихідний код в Git, документація по архітектурі та компонентах, доступ до CI/CD, навчання вашої команди (2-3 зустрічі), гарантія 3 місяці на виявлені баги. Додатково — покриття юніт-тестами ключових модулів.</p> <p>У нас 5 років досвіду у фронтенд-розробці, понад 50 виконаних проєктів, команда з 10 інженерів, що володіють React, Vue, Angular. Працюємо з технологіями, описаними в <a href="https://react.dev">документації React</a> та <a href="https://www.typescriptlang.org">TypeScript</a>. Додаткові відомості можна знайти в <a href="https://en.wikipedia.org/wiki/React_(JavaScript_library)">Wikipedia: React</a> та <a href="https://en.wikipedia.org/wiki/TypeScript">Wikipedia: TypeScript</a>.</p> <details> <summary>Чек-лист типових помилок при початку проєкту</summary> <ul> <li>Ігнорування tree-shaking: імпорт цілої бібліотеки замість вибіркових модулів.</li> <li>Відсутність code-splitting: важкий код завантажується одразу, а не на вимогу.</li> <li>Нехтування типобезпекою: відсутність <code>strict</code> в tsconfig — прямий шлях до багів.</li> <li>Надмірна мемоізація: <code>useMemo</code> та <code>useCallback</code> там, де вони не потрібні.</li> <li>Вибір невідповідного state-менеджера: Redux Toolkit на маленьких проєктах.</li> </ul> </details> <h3>Який стек обрати для фронтенд-розробки React?</h3> <p>Ми порівнюємо інструменти за реальними метриками. Next.js швидший за Nuxt у збірці SSR на 20–30% при однаковому розмірі сторінки. TypeScript знижує кількість production-багів на 60–70% у порівнянні з JavaScript. Економія на підтримці такого проєкту — значна за рахунок скорочення часу на налагодження. Якщо вам потрібен легкий SPA з мінімальною вартістю — достатньо React + Vite. Для контентного сайту з SEO — Next.js з ISR дає TTFB нижче 50 мс навіть при 50 000 сторінок.</p> <p>Отримайте консультацію по вашому проєкту: оцінимо поточний код і запропонуємо план оптимізації. Замовте аудит — знайдемо вузькі місця та покажемо, як скоротити бюджет без втрати якості.</p> </div></div></main><div class="block relative mt-8 lg:hidden w-full"></div><footer class="relative hidden lg:block"><div class="mx-auto max-w-7xl py-12 px-6 lg:py-16 lg:px-8"><div class="pb-8 grid grid-cols-4 gap-8"><div class="mt-0"><div class="text-base text-black font-normal dark:text-white">Підтримка</div><ul class="mt-4 space-y-4"><li><a class="text-base text-black/75 dark:text-white/50 hover:text-black dark:hover:text-white transition-all" href="https://truetech.dev/ua/contacts">Безкоштовна консультація</a></li><li><a class="text-base text-black/75 dark:text-white/50 hover:text-black dark:hover:text-white transition-all" href="https://truetech.dev/ua/posts">Корисна інформація</a></li></ul></div><div><div class="text-base text-black font-normal dark:text-white">Рішення</div><ul class="mt-4 space-y-4"><li><a class="text-base text-black/75 dark:text-white/50 hover:text-black dark:hover:text-white transition-all" href="https://truetech.dev/ua/apps">Всі рішення</a></li></ul></div><div><div class="text-base text-black font-normal dark:text-white">Компанія</div><ul class="mt-4 space-y-4"><li><a class="text-base text-black/75 dark:text-white/50 hover:text-black dark:hover:text-white transition-all" href="https://truetech.dev/ua/contacts">Контакти</a></li><li><a class="text-base text-black/75 dark:text-white/50 hover:text-black dark:hover:text-white transition-all" href="https://truetech.dev/ua/about">Про компанію</a></li><li><a class="text-base text-black/75 dark:text-white/50 hover:text-black dark:hover:text-white transition-all" href="https://truetech.dev/ua/career">Робота в компанії</a></li><li><a class="text-base text-black/75 dark:text-white/50 hover:text-black dark:hover:text-white transition-all" href="https://truetech.dev/ua/affiliate-program">Партнерська програма</a></li></ul></div><div class="mt-0"><div class="text-base text-black font-normal dark:text-white">Language & Currency</div><div class="mt-4 flex flex-col gap-4"><div><div class="relative mt-1"><button class="relative rounded-lg w-full cursor-default py-3 pl-3 pr-10 text-left shadow-sm text-base font-normal text-black/75 dark:text-white/50 bg-light-item dark:bg-dark-item focus:outline-none focus:ring-2 focus:ring-dark-button" id="headlessui-listbox-button-:Rpkdl:" type="button" aria-haspopup="listbox" aria-expanded="false" data-headlessui-state=""><span class="block truncate">Український</span><span class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" data-slot="icon" class="h-5 w-5"><path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"></path></svg></span></button></div></div><div><div class="relative"><button class="relative rounded-lg w-full cursor-default py-3 pl-3 pr-10 text-left shadow-sm text-base font-normal text-black/75 dark:text-white/50 bg-light-item dark:bg-dark-item focus:outline-none focus:ring-2 focus:ring-dark-button" id="headlessui-listbox-button-:Rqkdl:" type="button" aria-haspopup="listbox" aria-expanded="false" data-headlessui-state=""><span class="block truncate">USD</span><span class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" data-slot="icon" class="h-5 w-5"><path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"></path></svg></span></button></div></div></div></div></div><div class="py-8 grid grid-cols-4 gap-8 border-t border-black/25 dark:border-white/25"><div><a class="text-base text-black/75 dark:text-white/50 hover:text-black dark:hover:text-white transition-all" href="https://truetech.dev/ua/privacy-policy">Політика конфіденційності</a></div><div><a class="text-base text-black/75 dark:text-white/50 hover:text-black dark:hover:text-white transition-all" href="https://truetech.dev/ua/terms-of-service">Умови використання</a></div><div class="col-span-2"><div class="text-base text-black/75 dark:text-white/50">© <!-- -->2026<!-- --> <!-- -->Справжні технології ТОВ. Всі права захищені.</div></div></div></div></footer></div><div class="fixed lg:hidden w-full bottom-0"><div class="flex gap-12 px-12 justify-center h-[3.25rem] bg-white border-t border-[#E8E8E8] dark:bg-dark-nav dark:border-none"><a class="grow flex items-center justify-center text-white h-full" aria-label="Головна" href="https://truetech.dev/ua"><span class="flex h-8 w-7 text-black dark:text-white opacity-100"><svg x="0px" y="0px" viewBox="0 0 28 32.7" fill="none" xmlns="http://www.w3.org/2000/svg" xml:space="preserve"><path d="M16.8,23v-6c0-0.3-0.1-0.5-0.3-0.7c-0.2-0.2-0.4-0.3-0.7-0.3h-4c-0.3,0-0.5,0.1-0.7,0.3 c-0.2,0.2-0.3,0.4-0.3,0.7v6c0,0.3-0.1,0.5-0.3,0.7c-0.2,0.2-0.4,0.3-0.7,0.3l-6,0c-0.1,0-0.3,0-0.4-0.1c-0.1-0.1-0.2-0.1-0.3-0.2 C3,23.6,3,23.5,2.9,23.3c-0.1-0.1-0.1-0.3-0.1-0.4V11.4c0-0.1,0-0.3,0.1-0.4c0.1-0.1,0.1-0.2,0.2-0.3l10-9.1 c0.2-0.2,0.4-0.3,0.7-0.3c0.2,0,0.5,0.1,0.7,0.3l10,9.1c0.1,0.1,0.2,0.2,0.2,0.3c0.1,0.1,0.1,0.3,0.1,0.4V23c0,0.1,0,0.3-0.1,0.4 c-0.1,0.1-0.1,0.2-0.2,0.3c-0.1,0.1-0.2,0.2-0.3,0.2C24.1,23.9,24,24,23.8,24l-6,0c-0.3,0-0.5-0.1-0.7-0.3 C17,23.5,16.8,23.2,16.8,23L16.8,23z" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><line class="st1" x1="6.4" y1="32" x2="21.4" y2="32" fill="none" stroke="currentColor" stroke-linecap="round"></line></svg></span></a><a class="grow flex items-center justify-center text-white h-full" aria-label="Всі рішення" href="https://truetech.dev/ua/apps"><span class="flex h-8 w-7 text-black dark:text-white opacity-50"><svg x="0px" y="0px" viewBox="0 0 28 32.7" fill="none" xmlns="http://www.w3.org/2000/svg" xml:space="preserve"><path d="M11.8,3.1h-8v8h8V3.1z" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M23.8,3.1h-8v8h8V3.1z" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M11.8,15.1h-8v8h8V15.1z" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M23.8,15.1h-8v8h8V15.1z" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></span></a><a class="grow flex items-center justify-center text-white h-full" aria-label="Послуги" href="https://truetech.dev/ua#servicesList"><span class="flex h-8 w-7 text-black dark:text-white opacity-50"><svg x="0px" y="0px" viewBox="0 0 28 32.7" fill="none" xmlns="http://www.w3.org/2000/svg" xml:space="preserve"><path d="M2.8,13.2h22" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M2.8,5.2h22" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M2.8,21.2h22" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></span></a><a class="grow flex items-center justify-center text-white h-full" aria-label="Мій аккаунт" href="https://truetech.dev/ua/area51"><span class="flex h-8 w-7 text-black dark:text-white opacity-50"><svg x="0px" y="0px" viewBox="0 0 28 32.7" fill="none" xmlns="http://www.w3.org/2000/svg" xml:space="preserve"><path d="M13.8,17.2c4.4,0,8-3.6,8-8s-3.6-8-8-8s-8,3.6-8,8S9.4,17.2,13.8,17.2z" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M1.7,24.2c1.2-2.1,3-3.9,5.1-5.1c2.1-1.2,4.5-1.9,7-1.9c2.5,0,4.9,0.6,7,1.9c2.1,1.2,3.9,3,5.1,5.1" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></span></a></div></div></div></div> <div id="dialog"></div> <div id="dialog-alert"></div> <div id="dialog-iframe" class="hidden"></div> </div> </body> </html>