Зачем нужны фреймворки

Зачем:Ручной код с DOM работает, пока на странице немного мест, которые надо согласовывать. После урока вы видите, где он начинает ломаться, понимаете, что решают React, Vue, Svelte и Angular и чего это стоит посетителю, и можете спокойно ответить «а нужен ли мне фреймворк вообще».

25 минут

Озвучено синтезом речи (Qwen3-TTS), голос не принадлежит человеку.

Фреймворк вроде React, Vue, Svelte или Angular собирает интерфейс из компонентов и выводит вид из состояния. Такой подход называют реактивностью.

Когда ручной код начинает сыпаться

За четыре урока вы написали для своей страницы немало: сводку, быстрый переход, меню, поиск, загрузку списка. Каждый кусок работал. Но заметили ли вы, как в уроке про fetch в быстром переходе не оказалось нового пункта? Скрипт построил его при открытии страницы, а потом список поменялся, и никто об этом не сообщил.

Это и есть главная трудность интерфейсов. Состояние (какие пункты, что введено в поиск, открыто ли меню) живёт в одном месте, а показано оно в нескольких: в списке, в счётчике, в ссылках, в атрибуте aria-expanded. Каждый раз, когда состояние меняется, надо обновить все места, которые его показывают. Пока их два, это легко. Когда их пять, а способов поменять состояние три, число сочетаний растёт, и где-нибудь обязательно забывают. Получается страница, которая показывает «3 пункта» в счётчике и пять карточек в списке.

В ручном коде это выглядит так:

function addItem(item) {
  items.push(item);
  list.append(makeCard(item));            // 1: список
  counter.textContent = items.length;     // 2: счётчик
  badge.textContent = items.length;       // 3: значок в меню
  quickNav.append(makeLink(item));        // 4: быстрый переход
  // …и ничего не напомнит, если забыть пятое
}

Что придумали вместо

Идея, к которой пришли разные команды, одна: вид выводится из состояния. Вы не пишете «найди счётчик и перепиши его», а объявляете: «счётчик равен длине списка». Всё остальное берёт на себя библиотека: когда список меняется, она сама находит, что надо обновить. Такой подход называют реактивностью.

Рядом с ним почти всегда идёт вторая идея: компонент. Кусок интерфейса (карточка, меню, форма) оформляется как самостоятельная единица со своими данными, разметкой и оформлением, и из таких кусков собирается страница. Вы видели это в уроке про дизайн-системы, а здесь она становится кодом.

Вместе с ними фреймворки обычно приносят маршрутизацию (какая страница по какому адресу), управление общим состоянием, сборку и готовую экосистему плагинов и компонентов.

Кто есть кто

Фреймворков много, и они отличаются способом реализации той же идеи.

  • React (Facebook, 2013) описывает интерфейс функциями-компонентами и записью JSX, похожей на HTML внутри JavaScript. Идея: вы всякий раз «рисуете» интерфейс заново, а библиотека сравнивает с прежним (так называемый виртуальный DOM) и меняет только отличия. Сегодня самый распространённый.
  • Vue (Эван Ю, 2014) любит шаблоны, близкие к HTML, и реактивные данные. Его считают самым мягким для входа.
  • Angular (Google; первый AngularJS в 2010, полностью переписан в 2016) полный фреймворк на TypeScript с собственной структурой проекта. Часто встречается в больших корпоративных системах.
  • Svelte (Рич Харрис, 2016) решает ту же задачу иначе: это компилятор. Он разбирает ваш компонент во время сборки и порождает минимальный обычный JavaScript, который обновляет нужные узлы напрямую, а тяжёлой библиотеки в браузере почти нет. Сам этот учебник написан на Svelte 5.
  • Над ними стоят мета-фреймворки: Next.js (над React), Nuxt (над Vue), SvelteKit (над Svelte), Astro. Они добавляют маршруты, отрисовку на сервере и выдачу готового HTML, о чём мы поговорим в части про генераторы сайтов и Jamstack.

Вокруг фреймворков в 2016 году появилось выражение «усталость от JavaScript»: новые инструменты выходили быстрее, чем люди успевали их выучить. Полезно помнить, что у всех у них один и тот же корень: вид выводится из состояния.

Посмотрите, где растёт сложность

Один и тот же счётчик пунктов показан в нескольких местах страницы. Выберите, сколько мест от него зависит, и добавляйте пункты. Сравните ручной вариант, в котором программист должен помнить каждое место, и реактивный, где число выводится из состояния:

Одно число, много мест
Вручную: строк обновления 4
список.textContent = items.length;
счётчик.textContent = items.length;
значок в меню.textContent = items.length;
быстрый переход.textContent = items.length;
список: 3счётчик: 3значок в меню: 3быстрый переход: 3

Все места совпадают, пока ничего не забыто.

Реактивно: объявлено одно значение
let items = $state(3);
список: {items}
счётчик: {items}
значок в меню: {items}
быстрый переход: {items}
список: 3счётчик: 3значок в меню: 3быстрый переход: 3

Забыть нечего: каждое место выведено из одного значения и обновляется вместе с ним.

Проверьте себя: что такое ошибка синхронизации?

Ситуация, когда состояние поменялось, а одно из мест, которые его показывают, об этом не узнало: например, счётчик говорит «3», а карточек на экране пять.

Цена

Фреймворк не бесплатен, и платит за него не только разработчик, но и посетитель.

  • Вес. Библиотека и ваш код приезжают в браузер как JavaScript. Килобайт скрипта «дороже» килобайта картинки: картинку надо только показать, а скрипт сначала скачать, потом разобрать, потом выполнить. Пока он не выполнился, страница может быть красивой, но мёртвой: кнопки не нажимаются.
  • Слабые устройства. Телефон за пятнадцать тысяч рублей разбирает тот же скрипт в разы дольше вашего ноутбука. Отчёт Web Almanac из источников показывает, сколько JavaScript обычно весят страницы.
  • Сложность. Сборка, зависимости, обновления версий, способы хранить состояние: это отдельная работа, которая должна себя окупать.
  • Поисковики и первый показ. Страница, целиком рисуемая скриптом, пуста, пока скрипт не отработал. Современные поисковики это умеют, но дороже и хуже. Поэтому мета-фреймворки отдают готовый HTML сразу и «оживляют» его скриптом позже.

Когда фреймворк нужен, а когда нет

Честные критерии, которые можно применить к любому проекту.

Скорее не нужен: сайт-визитка, лендинг, блог, страница услуг: интерактива немного (меню, форма, поиск), мест согласования три-четыре, и всё помещается в голове. Чистый JavaScript плюс несколько модулей оставят страницу лёгкой.

Скорее нужен: личный кабинет, магазин с корзиной, редактор, панель с графиками, всё, где много экранов, общее состояние и данные меняются сами. Здесь ручной код тонет в синхронизации, а фреймворк окупается.

И третье, самое важное: решение можно пересмотреть. Начать на чистом JavaScript и перейти на фреймворк, когда место согласования десятое, нормальный путь.

Практика

Вы на сайте эпохи 2019 года, где фреймворки уже давно общепринятые. Но давайте разберём не вообще, а свою страницу: сколько на ней мест, которые согласуются вручную, и нужен ли ей фреймворк.

Таблица состоит из трёх колонок: что с чем согласуется, как это сделано сейчас и как было бы при реактивном подходе. Минимум три строки: всё, что вы писали в прошлых уроках, подойдёт. Дальше вывод: «нужен» или «не нужен», с числами из вашего брифа (сколько разделов, сколько пунктов). И вес ваших скриптов: подсчитайте приблизительно по вкладке «Сеть» или по размеру кода.

Ответ «не нужен» тоже правильный и часто верный. Важнее, что он обоснован вашей страницей.

Что было не так раньше

Когда фреймворков не было, всё писали вручную, а потом на jQuery, и большие страницы превращались в «спагетти»: десятки обработчиков, которые меняют друг другу элементы, и никто не помнит, что от чего зависит. В 2010 году появились первые фреймворки (Backbone, AngularJS), потом React с идеей «интерфейс есть функция от состояния». Но и у новой эпохи был перегиб: сайт-визитку на пять страниц собирали на тяжёлом одностраничном приложении, которое на слабом телефоне открывалось десятки секунд, а поисковики видели пустую страницу.

Верным осталось главное: вид выводится из состояния, а интерфейс собирается из компонентов. А лишнее это тяжёлый инструмент там, где хватило бы лёгкого.

Практика

Готовлю вашу страницу…

Тест

Вопрос 1 из 5

Что такое реактивность в интерфейсе?

Один ответ

Карточки

Эти карточки попадут в повторение, когда вы завершите урок.

  • Какую задачу решают фреймворки?

    Ответ

    Согласование данных и экрана: вы описываете, как выглядит интерфейс при данном состоянии, а фреймворк сам обновляет нужные части. Плюс компоненты, маршруты и сборка в комплекте.

  • Что такое реактивность?

    Ответ

    Вид выводится из состояния: изменили значение, и всё, что от него зависит, обновилось само. Не надо помнить каждое место, где значение показано.

  • Чем фреймворк платит посетитель?

    Ответ

    Весом JavaScript: его надо скачать, разобрать и выполнить, а пока он не отработал, страница может быть не интерактивной. На слабом телефоне это заметно.

  • Назовите главные фреймворки и их идею

    Ответ

    React: компоненты и JSX (2013). Vue: шаблоны и реактивность (2014). Svelte: компилятор вместо тяжёлой библиотеки. Angular: полный фреймворк на TypeScript от Google. Next.js, Nuxt, SvelteKit и Astro: надстройки с маршрутами и серверным рендерингом.

  • Как решить, нужен ли фреймворк?

    Ответ

    Посчитать, сколько мест на странице надо согласовывать и как часто. Мало мест и немного интерактива: хватит чистого JavaScript. Много экранов, общее состояние, длинные списки: фреймворк.

Источники

Дальше

Теперь вы знаете: зачем нужны фреймворки, реактивность.