Разработчик открывает проект, которому восемь лет. Внутри находят старую библиотеку для работы с разметкой, фреймворк первого поколения и новый инструмент, пришедший на замену. Все три работают одновременно, и никто не решается убрать лишнее. История фронтенда уместилась в одно приложение, и чтобы понять, откуда взялась эта мешанина, стоит проследить, как менялись подходы.
Библиотека 2006 года решала проблему несовместимости браузеров
Опубликована она была двадцать шестого августа 2006 года. Исходная задача звучала скромно: дать разработчику единый способ выбирать элементы страницы, менять их свойства и обрабатывать события, не думая о различиях между браузерами.
В те годы эти различия были мучительными. Код, работавший в одном браузере, отказывал в другом, и значительная часть времени уходила на обходные решения. Библиотека взяла эту работу на себя.
Три принципа определили её популярность. Разделение разметки и сценариев: обработчики назначаются из кода, а не через атрибуты. Краткость записи: цепочки вызовов позволяют выполнить несколько действий одной строкой. Расширяемость: любой мог добавить свою функцию и переиспользовать её.
Масштаб использования оказался огромным. По состоянию на октябрь 2026 года библиотека применяется на шестидесяти пяти процентах из десяти миллионов самых посещаемых сайтов. Это самая распространённая библиотека сценариев с большим отрывом.
Отдельное наследие это влияние на стандарты. Механизм выбора элементов, придуманный внутри библиотеки, позже вошёл в стандарт в виде отдельного программного интерфейса.
Понимание этого этапа важно для чтения старого кода. Манипуляции разметкой вручную, глобальные обработчики, отсутствие модулей. Всё это было нормой, а не признаком плохого стиля.
Приложения на одной странице перенесли логику в браузер
Следующий этап изменил представление о том, где выполняется работа. Вместо загрузки новых страниц приложение перерисовывало текущую, обмениваясь с сервером только данными.
Идея обсуждалась ещё в 2003 году, а первые реализации появились около того же времени. К середине десятилетия сформировались фреймворки, поддерживающие такой подход.
Что изменилось для разработчика.
Первое: появились маршруты на стороне браузера. Адрес меняется, но страница не перезагружается.
Второе: возникло управление состоянием. Данные, полученные из сети, хранятся в памяти приложения и отображаются в разных местах.
Третье: появилась двусторонняя привязка. Изменение данных обновляет вид, изменение вида обновляет данные. Это избавляло от ручного согласования, но создавало неожиданные эффекты.
Четвёртое: шаблоны переехали с сервера в браузер. Компиляция разметки выполнялась на клиенте.
Пятое: выросла роль сборки. Появились инструменты, объединяющие модули в один файл.
Фреймворки этого периода перечисляются легко: несколько имён, знакомых каждому, кто работал в те годы. Часть из них уже прекратила развитие, часть продолжает существовать в обновлённом виде.
Обратная сторона проявилась позже: объём загружаемого кода вырос, первая отрисовка замедлилась, а поисковые системы получили страницы без содержимого.
Компонентный подход вернул интерес к устройству интерфейса
Третий этап сместил акцент с приложения на отдельную часть интерфейса. Компонент стал единицей описания: разметка, стили и логика живут рядом и переиспользуются.
Первое следствие: декларативность. Разработчик описывает, как выглядит экран при разных состояниях, а библиотека сама решает, что обновить. Ручная работа с разметкой уходит.
Второе следствие: переиспользование. Компонент с параметрами применяется в десятках мест, и правка делается один раз.
Третье: разделение состояний. Локальное состояние компонента, состояние приложения, состояние сервера. Разные виды требуют разных инструментов.
Четвёртое: рост числа вспомогательных библиотек. Маршрутизация, работа с сетью, управление состоянием вынесены наружу и выбираются отдельно.
Пятое: обновление только изменившихся частей. Это снизило нагрузку по сравнению с полной перерисовкой.
Стандарт тоже не стоял на месте. Появился набор возможностей для создания собственных элементов разметки: определение нового тега, изоляция стилей, подготовленные фрагменты разметки. Идея была предложена ещё в 2011 году и к настоящему времени поддержана всеми основными браузерами.
Общее направление изменений можно описать несколькими линиями
Полезно увидеть закономерности, а не просто хронологию.
Первая линия это перемещение работы. Сначала страницы собирались на сервере, потом сборка переехала в браузер, затем часть работы вернулась на сервер ради скорости первой отрисовки.
Вторая линия это рост объёма кода. Библиотека 2006 года занимала десятки килобайт, современные сборки измеряются сотнями. Понимание этого привело к разделению кода на части и отложенной загрузке.
Третья линия это борьба с ручной работой. Ручное обновление разметки сменилось двусторонней привязкой, затем декларативным описанием, затем автоматическим отслеживанием зависимостей.
Четвёртая линия это возврат к стандартам. Идеи, придуманные во фреймворках, постепенно попадают в спецификации: выбор элементов, пользовательские элементы, изоляция стилей.
Пятая линия это усложнение сборки. От одного файла сценария до конвейера с проверкой типов, разбором модулей, минификацией и разбиением на части.
Шестая линия это смена единицы мышления. Модуль, затем приложение, затем компонент. Каждый переход менял способ разбиения задачи на части.
Практические выводы для проекта, который живёт долго
Из истории следуют конкретные решения.
Первое: не переписывать всё сразу. Смена подхода это не смена синтаксиса, а смена способа думать. Полная переделка занимает месяцы и почти всегда отстаёт от требований.
Второе: разделять уровни по границам. Новые экраны пишутся на новом инструменте, старые продолжают работать, общая логика выносится из обеих частей.
Третье: изолировать зависимости. Чем меньше кода завязано на конкретную библиотеку, тем дешевле замена.
Четвёртое: измерять выигрыш. Переход оправдан, если решает конкретную проблему: скорость разработки, объём загрузки, число ошибок.
Пятое: следить за стандартами. То, что сегодня доступно только в библиотеке, завтра может появиться в браузере. Тогда библиотека становится лишним слоем.
// слой-обёртка изолирует приложение от конкретной библиотеки
export function useOrderList(params) {
const { data, error, isLoading } = useQuery({
queryKey: ["orders", params],
queryFn: () => ordersApi.list(params),
});
return {
orders: data?.items ?? [],
error,
isLoading,
};
}
Такой слой выглядит избыточным, но именно он позволяет заменить внутреннюю реализацию, не переписывая сотню экранов. Через два года это свойство окупается.
Что стоит учитывать при выборе инструмента сегодня
Шестая часть размышлений касается выбора. История даёт несколько критериев.
Первый критерий это срок жизни. Инструмент, которому десять лет и который продолжает развиваться, надёжнее нового, выпущенного год назад.
Второй критерий это размер сообщества. Доступность ответов и готовых решений важнее технического превосходства.
Третий критерий это соответствие задаче. Для сайта из десяти страниц тяжёлый фреймворк не нужен, для крупного приложения он окупается.
Четвёртый критерий это стоимость найма. Распространённый инструмент проще укомплектовать специалистами.
Пятый критерий это близость к стандартам. Чем меньше уникальных понятий вводит инструмент, тем легче переход.
Шестой критерий это объём. Стоит сравнить размер сборки с потребностями, а не с модой.
Седьмой критерий это поддержка серверной отрисовки. Для страниц, которые должны быстро показываться и индексироваться, это важно.
Выводы сводятся к одному правилу
История фронтенда выглядит как череда мод, но за ней стоит последовательное движение к одной цели: описывать интерфейс так, чтобы правки были предсказуемыми, а скорость работы не страдала.
Старая библиотека для работы с разметкой решала проблему совместимости. Приложения на одной странице решали проблему переходов. Компонентный подход решил проблему переиспользования. Следующий шаг решает проблему доставки кода и согласования данных, и он уже начался.
Практический вывод простой. Выбирать инструмент стоит под задачу и срок жизни проекта, а не под свежесть публикаций. Код, написанный пять лет назад и работающий без ошибок, не заслуживает переписывания только потому, что появился новый способ делать то же самое. Переписывать стоит тогда, когда текущий подход мешает двигаться: замедляет выпуск, повышает число ошибок или упирается в возможности.
Отдельный разбор касается стоимости сопровождения
История полезна ещё и тем, что показывает, во что обходится каждая смена подхода.
Первая смена, переход от ручной работы с разметкой к библиотеке, стоила дешевле всего. Синтаксис осваивался за дни, код оставался прежним по структуре.
Вторая смена, переход к приложениям на одной странице, обошлась дороже. Понадобилось освоить маршрутизацию, управление состоянием и сборку. Многие проекты так и не завершили переход.
Третья смена, переход к компонентам, оказалась самой затратной. Изменилась единица мышления, а вместе с ней структура файлов, способ обмена данными и подход к тестированию.
Отсюда следует практический вывод: каждая следующая смена стоит дороже предыдущей. Это довод в пользу того, чтобы не спешить с переписыванием и выбирать момент осознанно.
Что происходит сейчас
Четвёртая линия изменений уже видна, и её стоит учитывать в планах.
Первое: серверная отрисовка возвращается как основной способ. Страницы собираются на сервере, а браузер лишь оживляет их.
Второе: граница между сервером и клиентом становится тоньше. Часть кода выполняется в обоих местах, и выбор делается по ситуации.
Третье: стандартные возможности браузера берут на себя то, что раньше требовало библиотек. Пользовательские элементы, изоляция стилей, готовые механизмы загрузки.
Четвёртое: снижение объёма загружаемого кода становится самостоятельной задачей. Появились инструменты, которые считают вес каждой зависимости и показывают цену решения.
Пятое: инструменты сборки и разработки переписываются на языках с более высокой скоростью, и время от правки до отображения сокращается.
Наблюдать за этими изменениями полезно, но бросаться внедрять каждое новшество не стоит. Обычно проходит два-три года, прежде чем становится ясно, что прижилось.
Короткая проверка перед сменой подхода
Первое: сформулирована ли проблема, которую решает переход. Не "устарело", а измеримое: время выпуска, число ошибок, объём загрузки.
Второе: покрыто ли текущее поведение тестами.
Третье: определена ли граница, за которой старый код остаётся как есть.
Четвёртое: оценены ли затраты на обучение команды.
Пятое: выбран ли пилотный участок и критерий успеха.
Шестое: предусмотрен ли план отката.
Седьмое: назначен ли срок, после которого решение пересматривается.
Эти семь пунктов превращают разговор о моде в разговор о плане. И тогда смена подхода перестаёт быть риском и становится обычной инженерной работой.
Сравнение старого и нового проекта на практике
Полезно сравнить, чем отличается типовой проект, начатый в разные годы.
Проект, начатый в две тысячи десятом, имеет один файл сценариев на несколько тысяч строк, разметку с обработчиками в атрибутах и стили в одном файле. Такой проект работает и легко разворачивается, но любая правка в общем файле рискованна.
Проект, начатый в две тысячи пятнадцатом, разбит на модули, использует сборку, имеет маршрутизацию на клиенте и общее хранилище состояния. Он гибче, но требует больше времени на настройку и понимание связей.
Проект, начатый в двадцать двадцатом, состоит из компонентов, использует серверную отрисовку, типизацию и разделение кода на части. Он удобен в работе, но зависимостей стало заметно больше.
Разница в скорости выпуска проявляется не сразу. Небольшой проект проще вести на простых средствах, крупный выигрывает от структуры. Граница проходит примерно по числу разработчиков и сроку жизни.
Практическое правило: сложность инструмента должна соответствовать сложности задачи. Взятый с запасом, он замедляет работу не меньше, чем взятый с недостатком.
Двадцать лет веб-разработки получились историей про смену способов думать, а не про гонку за синтаксисом. Каждый подход решал настоящую боль своего времени и добавлял новые сложности, которые решал следующий. Понять эту логику полезнее, чем выучить очередной инструмент: инструменты приходят и уходят, а причины, по которым они появляются, остаются теми же.