ГлавнаяБлогПочему стоит уйти с SPA-фреймворков на vanilla JavaScript
Алгоритмы

Почему стоит уйти с SPA-фреймворков на vanilla JavaScript

Узнайте 4 причины отказаться от React и Angular в пользу vanilla JavaScript и Web Components. Снизьте TCO, упростите найм и подготовьте код к эпохе AI. Начните миграцию сегодня.

Al
Редакция Algolitalgolit.ru
8 мин чтения13 июня 2026 г.

Почему стоит отказаться от SPA-фреймворков: 4 веские причины

Вы смотрите на свой package.json и думаете: «А не пора ли уйти с React или Angular на чистый JavaScript?» Этот вопрос мучает многих разработчиков, которые устали от бесконечных миграций на новые мажорные версии, зависимостей, которые устаревают быстрее, чем вы их устанавливаете, и сборщиков, которые меняются каждый квартал. В этой статье я разберу 4 столпа, которые делают отказ от SPA-фреймворков не просто капризом, а экономически обоснованным решением для долгоживущих проектов.

Столп первый: кривая совокупной стоимости владения (TCO)

Большинство моделей оценки стоимости ПО фокусируются на затратах на разработку, а поддержку считают множителем. Для долгоживущих приложений это ошибка: хвост поддержки — это и есть основное животное. Отраслевой опыт показывает, что затраты на поддержку в несколько раз превышают начальную разработку. И вот тут ключевое различие между фреймворком и платформой.

Код на фреймворке несёт три компонента затрат на поддержку: (а) изменения, которые вы выбираете сами (фичи, фиксы); (б) изменения, которые вам навязывает подложка (миграции версий, депрекации, обновления зависимостей из-за безопасности, смена тулинга); (в) полный переписывание, когда фундамент становится обузой. Код на платформе (vanilla JavaScript) несёт только (а). Компонент (б) стремится к нулю, потому что браузеры не ломают обратную совместимость DOM. Код, написанный против Custom Elements и CSS-кастомных свойств в 2026 году, будет работать без изменений в 2040. Компонент (в) — неизбежное переписывание — устраняется полностью. Это самая крупная статья расходов в любой честной долгосрочной модели: стоимость всего приложения заново плюс археология решений десятилетней давности.

Сравните две кривые амортизации. Фреймворковый код амортизируется как машина: он теряет ценность непрерывно из-за дрейфа экосистемы, даже если вы его не трогаете. Платформенный код амортизируется как земля с постройкой: здание (ваши фичи) требует ухода пропорционально тому, как часто вы его меняете, но фундамент не движется. На горизонте четырёх лет кривые почти не расходятся, и эргономика фреймворка в первые дни побеждает. На горизонте десяти лет плоская кривая доминирует decisively, причём пересечение наступает задолго до восьмого года даже при щедрых допущениях в пользу фреймворка.

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

Столп второй: рынок труда шире, чем кажется

Стандартное возражение: «Рынок полон React-разработчиков; ваниль и Web Components — это ниша; вы сужаете воронку найма». Это переворачивает реальную структуру рынка. Каждый фреймворковый разработчик пишет на JavaScript. Фреймворк — это диалект поверх языка, который они уже знают; DOM — это машина, которой в конечном счёте управляет их фреймворк. Ванильная кодовая база поэтому читаема, на базовом уровне, для объединения всех фреймворковых сообществ — React, Vue, Angular, Svelte — плюс значительная часть бэкенд-разработчиков, которые знают JavaScript, но никогда не специализировались на фронтенд-фреймворках. Фреймворковая кодовая база читаема для одного сегмента. Когда компания ищет кандидата с глубоким опытом в конкретном фреймворке на конкретной мажорной версии, она фильтрует рынок дважды: по диалекту и по винтажу диалекта. Измеряйте по минимальному уровню навыка: количество инженеров, которые могут стать продуктивными в хорошо структурированной ванильной кодовой базе за месяц, строго больше — в несколько раз — тех, кто может стать продуктивным в любой одной фреймворковой кодовой базе.

Вторичные эффекты все указывают в ту же сторону. Онбординг сжимается: нет диалекта фреймворка, нет собственного идиоматического управления состоянием, нет фольклора пайплайна сборки; поверхность обучения — это сама платформа, которую каждый кандидат впитывал всю карьеру, плюс ваш домен. Долговечность навыков улучшается: то, что инженеры узнают, поддерживая ванильную кодовую базу (DOM, события, инкапсуляция, реальный контракт платформы), растёт в цене в течение их карьеры, а не истекает вместе с долей рынка фреймворка. Ключевой риск снижается: вы больше не зависите от сценария, когда пул талантов вашего фреймворка истощается, когда мода уходит, оставляя вас торговаться за дефицит для поддержки стареющего стека — динамика COBOL, но с десятилетним fuse.

Честный контраргумент: среднее знакомство с тонкостями Shadow DOM (композиция слотов, перенацеливание событий, ElementInternals) действительно ниже, чем среднее знакомство с мейнстримными идиомами фреймворков. Оцените это как затраты на обучение в неделях, а не кварталах, на одного инженера, и поставьте напротив структурного расширения воронки. Это трейд, который стоит принять с энтузиазмом.

Столп третий: AI-левередж — маленький, замороженный корпус побеждает

Всё большая доля кода создаётся с помощью AI, и эта доля продолжает расти. Это меняет значение «продуктивности разработчика»: всё чаще ограничением становится не скорость написания кода человеком, а надёжность генерации модели и дешевизна проверки человеком. Выбор подложки теперь имеет AI-компоненту, и она в пользу платформы по трём структурным причинам.

Объём знаний мал. API-поверхность веб-платформы — DOM, события, Custom Elements, fetch, современный CSS — компактна и исчерпывающе специфицирована. Экосистема фреймворка — это эта поверхность плюс собственный большой API фреймворка, плюс его сателлиты управления состоянием, плюс конвенции мета-фреймворка, плюс идиомы текущей мажорной версии. Модель, которой поручено генерировать фреймворковый код, навигирует в паттерновом пространстве на порядок больше, где большая часть — конвенция, а не спецификация, и правдоподобные комбинации часто оказываются тонко неправильными.

Корпус стабилен. Модели обучаются на историческом коде. Для быстро движущегося фреймворка эта история — осадок устаревших паттернов: обучающие данные доминируются вчерашними идиомами, и модель уверенно выдает API, удалённые два мажора назад, смешивает старую парадигму с новой или импортирует пакеты, которые переименовали. Любой, кто использует AI-ассистентов на фреймворковом коде, узнаёт этот сбой: он превращает скорость генерации в нагрузку на ревью. API платформы не имеют этой проблемы, потому что правильный паттерн 2016 года всё ещё правильный паттерн 2026 года. Обучающее распределение и реальность развёртывания совпадают. Это выглядит как постоянное структурное преимущество: оно растёт каждый год, пока платформа стоит на месте, а фреймворки движутся, и никакое улучшение модели не закроет его полностью, потому что устаревание в данных, а не в модели.

Верификация дешевле. AI-сгенерированный ванильный код проверяем по публичной спецификации и наблюдаем непосредственно в отладчике; между кодом и его эффектом нет reconciler'а. AI-сгенерированный фреймворковый код нужно дополнительно проверять на семантику фреймворка — правила хуков, оговорки реактивности, ограничения гидратации — именно те нелокальные, закодированные в конвенции условия корректности, которые модели нарушают чаще всего, а ревьюеры ловят медленнее всего.

Экономический перевод: если AI-помощь производит корректный с первого раза код значительно чаще на платформенных целях — а повседневный опыт команд это подтверждает — то затраты на производство фичи на платформе падают быстрее, чем на фреймворке, по мере углубления внедрения AI. Традиционное преимущество фреймворка — эргономика для человека. В режиме, где машины пишут черновик, эргономика для машин — это метрика, и она указывает в другую сторону. Преимущество симметрично: меньшая, стабильная кодовая база без диалекта фреймворка легче читается AI-инструментами, что делает поддержку, миграцию и онбординг с помощью AI дешевле.

Столп четвёртый: это другая архитектура, и в этом суть

Фреймворковое SPA, независимо от синтаксиса компонентов, архитектурно является централизованно координируемой системой: один reconciler владеет деревом, изменения состояния проходят через глобальный планировщик, а компоненты — это функции, выполняемые внутри чужого цикла выполнения. Это покупает согласованность ценой связности — каждый компонент привязан к центральному механизму, что делает рефакторинг, тестирование и изоляцию сложными. Web Components, напротив, продвигают децентрализованную архитектуру: автономные, обменивающиеся сообщениями компоненты, которые не зависят от глобального reconciler'а. Это не просто другой синтаксис — это другая экономическая модель, где изменения дешевле, а масштабирование проще.

Если ваше приложение находится в правильном квадранте — долгоживущее, стабилизирующееся, формы и представления, а не коллаборативный canvas — мигрируйте инкрементально через паттерн strangler (удушитель) и отвергайте любую переписывание с нуля. Это позволит вам получать выгоду от каждого шага, не рискуя всем проектом.

Практический вывод: что делать прямо сейчас

Прямо сейчас откройте ваш текущий проект и оцените:

  • Как долго он живёт? Если больше 3-4 лет, вы уже платите налог на фреймворк.
  • Сколько времени уходит на миграции зависимостей? Если больше 20% времени команды — это красный флаг.
  • Как часто вы переписываете код из-за изменений в фреймворке? Если это происходит чаще раза в год, пора задуматься.

Начните с малого: выберите один изолированный компонент (например, кастомный дропдаун или модальное окно) и перепишите его на vanilla Web Components. Замерьте время разработки и поддержки. Сравните с фреймворковым аналогом. Повторите. Через несколько таких экспериментов вы увидите, где платформа выигрывает, а где фреймворк всё ещё удобен. Это и будет ваша карта миграции.

Код для старта:

// Простой Web Component на vanilla JS
class MyButton extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }

  connectedCallback() {
    this.shadowRoot.innerHTML = `
      <style>
        button { padding: 8px 16px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; }
        button:hover { background: #0056b3; }
      </style>
      <button><slot></slot></button>
    `;
    this.shadowRoot.querySelector('button').addEventListener('click', () => {
      this.dispatchEvent(new CustomEvent('my-click', { bubbles: true, composed: true }));
    });
  }
}

customElements.define('my-button', MyButton);

Используйте этот компонент в любом HTML или фреймворке — он будет работать без изменений. Это и есть сила платформы.

#vanilla JavaScript#SPA#Web Components#TCO#миграция
Al
Редакция Algolit

Пишем про алгоритмы, подготовку к собеседованиям и карьеру в IT — так, чтобы было понятно и полезно.

Хочешь закрепить знания на практике?

Решай задачи на Algolit — интерактивная платформа для обучения

Начать бесплатно →
Почему стоит уйти с SPA-фреймворков на vanilla JavaScript | Algolit