Кратко представьте, как читать исходный код 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;
}