Научит вас правильной позе для чтения исходного кода vue

Vue.js
Научит вас правильной позе для чтения исходного кода vue

Кратко представьте, как читать исходный код vue. Если у вас есть какие-либо предложения, не стесняйтесь добавлять их в область комментариев~

Во-первых, поза чтения исходного кода

1. Сначала все, подробности потом

  • Во-первых, выясните, на какие модули разделен исходный код, и как весь процесс соединяет модули.
  • Затем уточните, чтобы понять основные принципы каждого модуля.

2. Стоять на плечах других

  • Вам не нужно немного копаться в хранилище исходного кода, это очень неэффективно и подходит для людей, которые больше знают об исходном коде.
  • Рекомендуется прочитать вводную часть исходного кода других людей и анализ исходного кода (рекомендуется:Демистификация технологии Vue.js), выяснить контекст, а также примерные функции и основные процессы каждой части. Я смотрю на реализацию исходного кода с идеей в сердце.
  • В большинстве случаев вам не нужно изучать код построчно, но вам необходимо изучить реализацию некоторых основных функций, таких как виртуальный дом, алгоритм сравнения, управляемая данными, адаптивная реализация и компонентизация. рекомендуется использовать основные функции.

3. Прочтите несколько раз

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

2. Шаги

  • Сборка анализа зависимостей: маршрутизация, иерархия родительских и дочерних компонентов
  • Компиляция шаблона: анализ в синтаксическом дереве AST, а затем построение виртуального дерева dom
  • Загрузка страницы: виртуальный дом полностью превращается в настоящий
  • Локальное обновление: реагирующие данные отслеживают изменения, diff сравнивает различия в виртуальном дереве DOM до и после изменения данных и локально обновляет DOM.
  • Уничтожить: разрушить виртуальный дом, удалить дом

В-третьих, руководство по исходному коду vue

Краткое описание принципа работы основной части исходного кода vue:Анализ исходного кода Vue и понимание принципа

  • стиль шаблона, стиль конфигурации объекта
  • Идея виртуального дома (операция с объектом js вместо операции с домом)
  • Идея алгоритма Diff (сравнение на одном уровне, добавление, перемещение, удаление)
  • Идея компонентизации (компиляция компонентов, связь компонентов)
  • Реагирование на данные (сбор зависимостей, отправка обновлений, публикация подписки)

В-четвертых, разберитесь с новыми функциями vue3.

Болевые точки vue2.x:

  • ремонтопригодность самого исходного кода;
  • Проблемы с производительностью рендеринга и обновления, вызванные большим объемом данных;
  • Некоторые безвкусные API, от которых я хочу отказаться, но которые были сохранены для совместимости;
  • поддержка TypeScript;

Точки оптимизации Vue3.0:

  • Во-первых, использование монорепозитория управления исходным кодом.
  • 2. Используйте TypeScript для разработки исходного кода
  • 3. Оптимизация производительности 1. Оптимизация объема исходного кода 2. Оптимизация захвата данных Прокси 3. Скомпилируйте и оптимизируйте 4. Оптимизация алгоритма сравнения
  • В-четвертых, оптимизация API синтаксиса: API композиции

Подробнее см.:Узнайте, что нового в Vue3

В-пятых, присмотритесь к алгоритму diff

разница vue2

Суть обновления компонента заключается в отслеживании изменений данных в ответных данных, регенерации виртуального дерева DOM, а затем вычислении разницы между виртуальным деревом DOM до и после с помощью алгоритма сравнения и обновлении только измененной части при обновлении DOM. Быстрый вопрос и быстрый ответ:

1. Почему разница?

Ответ: O(n^3) означает, что если вы хотите отобразить 1000 узлов, вам придется последовательно выполнять миллиарды сравнений, что не выдерживает сравнения больших объемов данных.

Почему сложность прямого сравнения и изменения двух деревьев равна n^3?

Ответ: Каждый узел старого дерева пересекает узлы нового дерева, пока не будет найден соответствующий узел нового дерева. Тогда этот процесс равен O (n ^ 2), а затем, найдя разницу, вычислить кратчайшее расстояние модификации, а затем изменить узел, здесь O (n ^ 3).

2. Какова стратегия diff? На каком основании?

отвечать: 1. Операций перемещения узлов DOM по слоям в веб-интерфейсе очень мало и их можно игнорировать, поэтому выполняется только одно и то же сравнение слоев. 2. Если родительский узел отличается, отказаться от сравнения дочерних узлов, удалить старый узел напрямую и добавить новый узел для повторного рендеринга; 3. Если дочерний узел меняется, Virtual DOM не вычисляет, что изменилось, а перерисовывает его. 4. Несколько узлов на одном уровне могут сравнивать сходства и различия с помощью уникального ключа;

3. Что такое процесс сравнения?

отвечать: Старый и новый узлы отличаются: создать новый узел ➜ обновить родительский узел-заполнитель ➜ удалить старый узел; Старый и новый узлы одинаковы и не имеют потомков: без изменений; Старый и новый узлы одинаковы и имеют дочерние узлы: пройдитесь по дочерним узлам для сравнения на том же уровне и выполните три операции: переместить, добавить и удалить, как показано на рисунке ниже;

разница vue3.0

Глубинный рекурсивный обход дерева vnode, если метка и ключ узла совпадают, он будет обновлен, если он считается одним и тем же узлом, а если он отличается, он будет удален, а затем дочерние узлы будет обработан. В этих случаях обрабатываются дочерние узлы: обычный текст, массив vnode и пустой

Пустой часто означает добавление или удаление; Если обычный текст такой же, то innerText будет обновляться напрямую, а если другой, то он будет удален; Все новые и старые дочерние узлы представляют собой массивы vnode, и для их обработки используется алгоритм diff;

Идея алгоритма сравнения vue3.0

  • Выполнять статический анализ при компиляции шаблона, отмечать динамические узлы и сравнивать динамические узлы только тогда, когда diff сравнивает различия (улучшение производительности очевидно);
  • Алгоритм diff сначала удаляет голову и хвост, тем самым сокращая длину обхода и сравнения массива (очевидно, оптимизирует производительность операций вставки и удаления массива);
  • Создавая таблицу сопоставления для массивов подузлов до и после обновления, сложность обхода O (n ^ 2) снижается до O (n);
  • Массив подузлов до и после diff получается методом наибольшей возрастающей подпоследовательности для уменьшения количества операций перемещения;

Для реализации алгоритма сравнения vue3.0 см.:Демонстрация алгоритма Diff

Реализация алгоритма самой длинной возрастающей подпоследовательности:

Алгоритм самой длинной возрастающей подпоследовательности leetcode

/*
 * 寻找最长递增子序列
 * 使用动态规划思想,a -> c = a -> b + b -> c
 * 其中p数组存储的是从p[p[i]] 到 p[i] 的最长递增子序列索引,也就是前一个b的索引;
 * r数组存储最后一个元素也就是c的索引
 */
 function getSequenceOfLIS(arr) {
    const p = [0];
    const result = [0];
    for (let i = 0; i < arr.length; i ++) {
        const val = arr[i];
        const top = result[result.length - 1];
        if (arr[top] < val) {
            p[i] = top;
            result.push(i);
            continue;
        }
        // 二分法搜索
        let l = 0, r = result.length - 1;
        while(l < r) {
            const c = (l + r) >> 1;
            if (arr[result[c]] < val) {
                l = c + 1;
            } else {
                r = c;
            }
        }
        if (val < arr[result[l]]) {
            if (l > 0) {
                p[i] = result[l - 1]
            }
            result[l] = i;
        }
    }
    // 回朔p数组,找出最长递增子序列
    let preIndex = result[result.length - 1];
    for (let i = result.length - 1; i > 0; i --) {
        result[i] = preIndex;
        preIndex = p[preIndex]
    }
    return result;
}