Учебник по Vue3: где Vue 3.x быстр?

Vue.js внешний фреймворк
Учебник по Vue3: где Vue 3.x быстр?

quote

Следование тому, что говорят другие, не сделает вас лучше, но сделает вас все больше и больше в толпе.

Когда вы и другие разработчики говорите об основных моментах выпуска Vue 3.0, один из ваших ответов должен быть «он быстрее, в 1,2–2 раза быстрее по производительности».

Тогда я хочу спросить вас, что делает Vue быстрее, Ю Да дал нам ответ в бета-версии онлайн-трансляции.

PatchFlag (статический флаг)

Виртуальный DOM в Vue 2.x — это полноценный режим сравнения, а начиная с Vue 3.0 добавлен статический тег (PatchFlag).

При сравнении узлов до обновления сравниваются только узлы со статическими тегами. А перечисление PatchFlag определяет более десятка типов для более точного позиционирования типов узлов, которые необходимо сравнивать. Ниже мы разберем процесс этого сравнения на графических примерах.

Предположим, у нас есть следующий фрагмент кода:

<div>
  <p>老八食堂</p>
  <p>{{ message }}</p>
</div>

В режиме полного сравнения Vue 2.x, как показано ниже:

diff (2).png

На приведенном выше рисунке мы обнаружили, что алгоритм сравнения Vue 2.x сравнивает каждый тег один раз, и, наконец, обнаружили, что{{ message }}Метка переменной — это метка, которую нужно обновить, очевидно, еще есть место для оптимизации.

В Vue 3.0 оптимизирован алгоритм diff.При создании виртуального DOM, в зависимости от того, изменится ли содержимое DOM, дается статический тег (PatchFlag) соответствующего типа, как показано на следующем рисунке:

diff (3).png

Глядя на приведенный выше рисунок, нетрудно обнаружить, что при попытке обновления сравниваются (diff) только теги, отмеченные флажком, поэтому выполняется только 1 сравнение, в то время как в том же случае Vue 2.x выполняет 3 сравнения. Это первая причина, по которой Vue 3.0 работает лучше, чем Vue2.x.

Затем мы проверяем правильность нашего приведенного выше анализа, переводя код шаблона в виртуальный DOM. Мы можем включить преобразование шаблоновВеб-сайт, чтобы перевести приведенный выше код:

laoba.png

Синее поле на приведенном выше рисунке — это переведенный виртуальный узел DOM.Первый тег P — это статический текст, записанный до смерти, а второй тег P — связанная переменная, поэтому отмечен тег 1, который представляет ТЕКСТ (литерал), обозначив тип перечисления следующим образом:

export const enum PatchFlags {
  
  TEXT = 1,// 动态的文本节点
  CLASS = 1 << 1,  // 2 动态的 class
  STYLE = 1 << 2,  // 4 动态的 style
  PROPS = 1 << 3,  // 8 动态属性,不包括类名和样式
  FULL_PROPS = 1 << 4,  // 16 动态 key,当 key 变化时需要完整的 diff 算法做比较
  HYDRATE_EVENTS = 1 << 5,  // 32 表示带有事件监听器的节点
  STABLE_FRAGMENT = 1 << 6,   // 64 一个不会改变子节点顺序的 Fragment
  KEYED_FRAGMENT = 1 << 7, // 128 带有 key 属性的 Fragment
  UNKEYED_FRAGMENT = 1 << 8, // 256 子节点没有 key 的 Fragment
  NEED_PATCH = 1 << 9,   // 512
  DYNAMIC_SLOTS = 1 << 10,  // 动态 solt
  HOISTED = -1,  // 特殊标志是负整数表示永远不会用作 diff
  BAIL = -2 // 一个特殊的标志,指代差异算法
}

hoistStatic (статическое продвижение)

Когда мы обычно пишем функции в процессе разработки, когда мы определяем некоторые жестко закодированные переменные, мы продвигаем переменные, которые должны быть определены, как показано ниже:

const PAGE_SIZE = 10
function getData () {
	$.get('/data', {
  	data: {
    	page: PAGE_SIZE
    },
    ...
  })
}

Например, приведенный выше код, еслиPAGE_SIZE = 10 написать наgetDataметод, каждый вызовgetDataпереопределит переменную один раз.

Vue 3.0 сделал ту же оптимизацию в этом отношении.Продолжайте использовать код, написанный в нашем предыдущем примере, чтобы наблюдать за виртуальной структурой DOM после компиляции, как показано ниже:

Перед выполнением статического продвижения:

hoist.png

Выберите в разделе «Опция»hoistStatic:

optionh.png

После статического повышения:

hoist2.png

Внимательные студенты увидят, что老八食堂упоминалосьrenderВне функции вам нужно только получать каждый раз, когда вы рендерите_hoisted_1переменная может быть. Студенты, внимательно прочитавшие статью, найдут еще одну деталь,_hoisted_1мыть егоPatchFlag, значение статического флага равно -1 , а специальный флаг представляет собой отрицательное целое число, которое никогда не будет использоваться в качестве Diff. То есть те, которые отмечены -1, больше не будут участвовать в алгоритме Diff, который повышает производительность Vue.

cacheHandler (кэш прослушивателя событий)

по умолчанию@clickСобытия считаются динамическими переменными, поэтому их изменения отслеживаются при каждом обновлении представления. Но обычно наши@clickСобытие — это одно и то же событие до и после рендеринга представления, и в принципе нет необходимости отслеживать его изменения, поэтому Vue 3.0 сделал для этого соответствующую оптимизацию, называемую кешем прослушивания событий, Добавим к приведенному выше коду абзац:

<div>
  <p @click="handleClick">屋里一giao</p>
</div>

После компиляции это показано на следующем рисунке (cacheHandler не был открыт):

giao.png

В случае, когда кеш прослушивания событий не включен, мы видим, что эта строка кода после компиляции статически помечена как 8. Статически помеченные теги будут извлечены для сравнения, как объяснялось ранее, а статический тег 8 соответствует «динамическому атрибуты". , за исключением имен классов и стилей".@clickЭто свойство считается динамическим, поэтому нам нужно включить параметры в разделеcacheHandlerсвойства, как показано на следующем рисунке:

giao1.png

Внимательные одноклассники снова найдут, откроютcacheHandlerПосле этого скомпилированный код не имеет статического флага (PatchFlag), что означает, что тег P на рисунке больше не отслеживается и не изменяется, что повышает производительность Vue.

Рендеринг SSR на стороне сервера

Когда вы используете разработку SSR в разработке, Vue 3.0 будет напрямую преобразовывать статические теги в текст.По сравнению с React, который сначала преобразует jsx в виртуальный DOM, а затем преобразует виртуальный DOM в HTML, Vue 3.0 победил.

ssr.jpg

StaticNode (статический узел)

Приведенный выше рендеринг SSR на стороне сервера будет напрямую преобразовывать статические теги в текст. При рендеринге на стороне клиента, если теги достаточно вложены, они также будут преобразованы в строки HTML во время компиляции, как показано на следующем рисунке:

staticnode.jpg

Необходимо включить hoistStatic в разделе «Параметры».

Суммировать

Выше приведена оптимизация производительности Vue3.0 для виртуального DOM во время компиляции, что делает Vue 3.0 в 1,2-2 раза быстрее, чем Vue 2.x по производительности.

Создан учебный репозиторий Vue3.vue3-examples,Адрес склада: г.GitHub.com/новый Bee-Ltd/…, Этот репозиторий будет время от времени обновлять различные знания, связанные с Vue3.0, и различные советы по интеграции Demo и Vue3. Вы можете обратить на это внимание. Если у вас есть какие-либо предложения, вы можете оставить мне сообщение.

Если не указана перепечатка/источник, все они являются оригинальными автором.Перепечатки приветствуются, но это утверждение должно быть сохранено без согласия автора, а ссылка на исходный текст дается в видном месте на странице статьи. , в противном случае сохраняется право на юридическую ответственность.