Vue 3 стане швидше

Alex Alex 03 грудня 2019

Vue 3 стане швидше

Одним з найяскравіших подій у світі Фронтенда в цьому році стала публікація репозиторію Vue next — частини функціоналу третьої версії VueJS. У цій статті представлений огляд нових killer features VueJS. На момент публікації статті репозиторій перебував у статусі Pre-Alpha. Плани на реліз можна подивитися в Roadmap

Передісторія


У лютому 2018 Evan You, творець Vue.js поділився планами на 3 версію популярного фреймворку:

  • Розбити функціональність на пакети для ізоляції області видимості
  • У кодовій базі з'явиться TypeScript
  • Vue 3 буде мати зворотну сумісність зі 2й версією (тобто не зламає старий код)
  • Спостерігачі 3.0 версії засновані на Proxy, що збільшить швидкість рендера і зніме ряд обмежень, що накладаються Object.defineProperty
  • З'явиться можливість дебажити з допомогою нових хуків renderTracked та renderTriggered
  • Завдяки введенню tree shaking (виключення з білду невикористовуваних директив) розмір фреймворку складе менше 10kb в стислому вигляді
  • Оптимізація слотів
  • Перфоманс у vue 3 покращиться на 100%

Features such as built-in components and directive runtime helpers (v-model) are now imported on-demand and tree-shakable
Evan You
Компілятор буде відслідковувати наявність директив і включати їх в білд на стадії компіляції.

У процесі роботи над Vue 3 Еван відмовився від переписування компонентів на класи і натомість запровадив функціональне API.

Оскільки нова версія буде використовувати Proxy, які не підтримуються IE, Еван планує зробити окремий білд для IE11. Всього обіцяють 4 фази:

  1. Alpha Phase — стадія доопрацювання компілятора та ssr-рендера
  2. Beta Phase — стадія доопрацювання основних бібліотек (Vue Router, Vuex, Vue CLI, Vue DevTools)
  3. RC Phase — стадія пререлиза, що включає в себе Vue 2.0
  4. IE11 build
  5. Final Release

Фінальний реліз Еван запланував на 2019 рік, але проект все ще в стадії пре-альфа.

Vue 3 буде швидше


Завдяки ряду нововведень Vue 3 стане в 2 рази швидше попередньої версії.

Proxy-based Observation and Reactivity


Одним з великих нововведень стало зміна механізму спостереження за об'єктами з геттеров і сеттерів Object.defineProperty на Proxy. Тепер Vue може відстежувати видалення і додавання властивостей реактивних об'єктів без використання Vue.set і Vue.delete. Нововведення збільшило швидкість рендеринга і скриптинга і зменшило споживання пам'яті в 2 рази! Порівняти перфоманс Vue 2 і Vue 3 можна, скачавши репозиторій Іллі Климова

Порівняння продуктивності Vue 2 (ліворуч) і Vue 3 (стадія pre-alpha, праворуч)
Screenshot-1

Завдяки проксям не загубиться реактивність при зміні не відслідковуються у Vue 2 маніпуляцій з об'єктами. Тепер Vue не буде рекурсивно проходити за властивостями об'єкта, щоб обчислити зміни.

Що виконано з обіцянок:

  • Компоненти-нащадки і батьки перерисовываются незалежно
  • Зменшився розмір Vue 3 з 20kb до 10kb в стислому вигляді
  • Додано TypeScript

Інші оптимізації:

  • Vue 3 буде запам'ятовувати статичний контент і патчити тільки динамічні дані
  • Статичні пропсы піднімуться вгору області видимості
  • Для простоти розробки код Vue 3 розбитий на модульні пакети
  • Пакет runtime-core зроблений кросплатформним
  • Замість класів Еван додав setup функцію і хуки, завдяки яким код стає чистим, організованим і переиспользуемым*
  • Time Slicing*. Виконання PHP коду ріжеться на шматки, не блокуючи взаємодія користувача з додатком

Зірочками зазначено експериментальне API.
Update: Пізніше Еван вирішив відмовитися від time sliсing

Надихнувшись HOC Реакта Еван реалізував setup функції з переиспользуемой логікою і кастомних хуками. На відміну від миксинов хуки життєвого циклу не замінюють один одного.

Вдосконалений патч VDom


Хойстинг статичного контента

Screenshot-2

Статичний контент виноситься за межі патчінга VDom при компіляції шаблону. На це команду Vue надихнув Svelte:

<div>Hello, {}</div>

Тут передається об'єкт changed і контекст. Якщо changed містить реактивну змінну, то вона оновлюється в контексті.

p(changed, ctx) {
if(changed.name) {
set_data(t1, ctx.name);
}
}

У попередньої реалізації компілятор Vue проходився по всьому нодам, включаючи статичні:

function render(){
const children = [];
for(let i = 0; i < 5; i++) {
children.push(h (p', {
class: 'text'
}, i === 2 ? this.message : 'Lorem upsum'))
}
return h('div', { id: 'content' }, children)
}

Нова стратегія компіляції шаблонів


У новій версії шаблон розбивається на блоки:

Selection-002

  • Шаблон ділиться на блоки
  • Структура нод всередині кожного блоку повністю статична
  • Для відстеження динамічних значень в блоці потрібно тільки 1 плоский масив, куди вони поміщаються

З новою стратегією продуктивність безпосередньо залежить від кількості динамічного контенту замість розміру шаблону.

Vue 3 буде краще адаптований під великі проекти


Великі проекти стикаються з наступними проблемами при використанні Vue:

  1. Не ідеальна підтримка TypeScript
  2. Масивні, складно підтримувані компоненти
  3. Відсутність простого патерну для перевикористання коду

Спочатку для підтримки TS планувалося додати класи. Але команда Vue зіткнулася з проблемами:


Команда Евана запросила допомогу у експертів з TC39 і з'ясувала, що подібна реалізація могла б конфліктувати з плагінами, які домішують різні пропсы і атрибути до контексту Vue.

Потенційно ці проблеми могли вирішити декоратори, але вони знаходяться в розробці.

Composition API


Команда Vue надихнулася хуками Реакта і вирішила створити подібний API. Воно опціонально і перебуває в стадії розробки та обговорення, тому деякі назви можуть змінюватися.
Головна концепція цієї зміни — організувати код компонента логічніше, розбивши його на смислові блоки. Детальніше про composition API можна прочитати в документації.

Приклад використання Vue 3. Компонент розбивається на логічні функції, всередині яких можна використовувати реактивність і хуки життєвого циклу.

Імпортуємо нові хуки з composition API:

import { reactive, computed, onMounted } from '@vue/composition-api';
export default {
setup() {
const { state } = countAnimal("rabbit")
const { getType, anotherState } = anotherCount()
return {
state,
getType,
anotherState
}
}
}

У функції countAnimal є реактивні властивості count, animal і метод increment. При непарному лічильнику ім'я тварини змінюється. Лічильник запускається при монтуванні компонента.

function countAnimal(name) {
const state = reactive({
count: 0,
animal: computed(() => state.count % 2 ? name : 'bear')
})
function increment() {
setTimeout(() => {
state.count++;
increment()
}, 1000)
}
onMounted(() => {
increment()
})
return {
state
}
}

Створюємо іншу функцію anotherCount, яка теж містить метод increment state з лічильником і назвою тварини. В метод getType передається назва тварини з шаблону.

function anotherCount() {
const anotherState = reactive({
count: 0,
animal: 'fox'
})
function getType(name) {
return name == 'bear' ? 'slow' : 'fast'
}
function increment() {
setTimeout(() => {
anotherState.count+=10;
increment()
}, 1000)
}
onMounted(() => {
increment()
})
return {
getType,
anotherState
}
}

У шаблоні, виводяться 2 лічильника і 2 імені тварин. Тип бігу змінюється в залежності від імені тварини.

<template>
<div>
<div>Count {}: {{ state.count }}</div>
<div>{} runs {}</div>
<div>Another:
Count {}: {{ anotherState.count }}</div>
 </div>
</template>

Нові хуки використовуються всередині setup, не ламаючи старий API. Зверніть увагу, що onMounted посилається на єдиний хук життєвого циклу компонента.

У такого апі є ряд переваг:

  • Хуки життєвого циклу не перетирають один одного
  • Зрозумілий джерело властивостей
  • Не створюються додаткові примірники компонента

Висновок


Вище перераховані найважливіші зміни у Vue 3. Більшість поліпшень будуть приховані під капотом згенерованого компілятором коду.

Основні поліпшення:

  • Згенерований код оптимальніше для JS компілятора
  • Згенерований bundle легше
  • Компоненти батьків/нащадків перерисовываются завдяки поліпшеному алгоритмом патчінга

Vue встиг зарекомендувати себе, як один з найшвидших і оптимальних фреймворків. Нова версія стане ще швидше і легше. Vue 3 відмінно підходить для сучасного мобільно - і перфоманс-орієнтованого веба. Коментар про майбутніх змінах можна залишити в офіційному RFC (request for comments).
P. S. Дякую за виправлення помилок.

Source: habr.com

Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.