Stencil vs Vue

Stencil представляет собой компилятор для создания веб-компонентов, ориентированных на стандарты платформы. Он не является фреймворком в привычном понимании, как Vue. Основная задача Stencil — генерировать нативные веб-компоненты с минимальным размером и высокой производительностью, которые могут использоваться в любом окружении: Angular, React, Vue или чистом HTML.

Vue — это полноценный фреймворк для построения реактивных пользовательских интерфейсов. Он предоставляет готовую систему реактивности, управление состоянием через Composition API или Options API, маршрутизацию, управление формами и многое другое. Vue ориентирован на разработку приложений с собственным экосистемным стеком, где компоненты тесно связаны с фреймворком.

Компиляция и рендеринг

Stencil использует компиляцию в веб-компоненты на этапе сборки. В процессе компиляции:

  • Генерируются кастомные элементы (<my-component>), соответствующие стандартам HTML.
  • Минимизируются зависимости, за счёт чего итоговый пакет имеет малый размер.
  • Автоматически внедряется ленивый рендеринг и оптимизация Shadow DOM при необходимости.
  • Реализуется реактивность через @State(), @Prop() и наблюдатели, но без полноценной системы реактивного связывания, как в Vue.

Vue же работает на runtime. Его виртуальный DOM обеспечивает реактивное обновление UI в процессе работы приложения:

  • Компоненты Vue имеют встроенный механизм реактивности, который отслеживает изменения состояния.
  • Все вычисляемые свойства, watchers и реактивные эффекты обрабатываются движком фреймворка во время исполнения.
  • Размер итогового бандла зависит от используемых модулей и плагинов Vue.

Работа с компонентами

Stencil строит компоненты по принципу стандарта Web Components:

import { Component, Prop, h, State } from '@stencil/core';

@Component({
  tag: 'my-counter',
  styleUrl: 'my-counter.css',
  shadow: true
})
export class MyCounter {
  @State() count: number = 0;
  @Prop() step: number = 1;

  increment() {
    this.count += this.step;
  }

  render() {
    return (
      <button onCl ick={() => this.increment()}>
        {this.count}
      </button>
    );
  }
}

Особенности:

  • Shadow DOM обеспечивает инкапсуляцию стилей.
  • Пропсы (@Prop) могут быть переданы как атрибуты HTML.
  • Состояние (@State) автоматически вызывает повторный рендер компонента.

Vue компоненты используют декларативный синтаксис с шаблонами:

<template>
  <button @click="increment">{{ count }}</button>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const count = ref(0);
const step = 1;

function increment() {
  count.value += step;
}
</script>

<style scoped>
button {
  padding: 8px 16px;
}
</style>

Особенности Vue:

  • Полная реактивность через ref и reactive.
  • Scoped CSS для ограниченного применения стилей.
  • Система слотов и составных компонентов с удобным API.

Реактивность и управление состоянием

Stencil предоставляет легковесную реактивность, ограниченную @State и @Prop. Для более сложных сценариев необходимо использовать сторонние решения для глобального состояния (например, Redux или Zustand).

Vue из коробки предлагает:

  • Composition API с ref, reactive, computed.
  • Возможность централизованного состояния через Pinia или Vuex.
  • Автоматическое отслеживание зависимостей в шаблоне, что упрощает разработку сложных UI.

Интеграция и совместимость

Stencil ориентирован на универсальность:

  • Компоненты можно использовать в Angular, React, Vue и чистом HTML.
  • Генерация чистых веб-компонентов позволяет создавать дизайн-системы для разных проектов.
  • Не требует установки фреймворка в проект, который использует компонент.

Vue ориентирован на собственную экосистему:

  • Компоненты Vue напрямую завязаны на Vue runtime.
  • Использование в других фреймворках требует обёрток или конвертации.
  • Идеален для SPA и PWA, где Vue является основной платформой.

Размер и производительность

Stencil генерирует оптимизированный код с минимальными зависимостями:

  • Ленивая загрузка компонентов.
  • Shadow DOM минимизирует перерисовку и коллизии стилей.
  • Размер бандла обычно меньше, чем у Vue-приложений с аналогичной функциональностью.

Vue использует виртуальный DOM, что иногда увеличивает нагрузку на рендеринг, но компенсируется встроенной системой оптимизаций и возможностью tree-shaking при сборке.

Вывод по архитектурным отличиям

  • Stencil — компилятор для создания стандартных веб-компонентов с минимальным runtime и высокой совместимостью.
  • Vue — полноценный фреймворк с мощной реактивностью, шаблонами и встроенными инструментами для разработки сложных SPA.
  • Выбор между ними определяется целями: универсальные компоненты и дизайн-системы vs. полноценное приложение с управлением состоянием и маршрутизацией.

Stencil и Vue решают схожие задачи в области UI, но используют разные подходы к реактивности, компиляции и интеграции, что делает их скорее дополняющими, чем взаимозаменяемыми инструментами.