简介一下集体浏览vue源码的姿态,有倡议欢送评论区补充哈~

一、源码浏览姿态

1. 先整体 - 后细节

  • 先弄清楚源码分为哪几个模块,整套流程是怎么将各个模块串起来的。
  • 而后细化理解每个模块的外围原理。

2. 站在他人的肩膀上

  • 不必一股脑扎进源码仓库里一点点啃,这样很低效,实用于对源码较为理解的人
  • 举荐先读他人的源码简介,源码剖析,弄清楚脉络,还有每个局部的大略性能和外围流程。心里带着思路去看源码实现。
  • 少数状况不须要逐行代码的细究,但针对某些外围性能的实现须要细究,例如:虚构dom、diff算法、数据驱动、响应式实现以及组件化等外围的性能的外围实现举荐细看。

3. 读多遍

  • 一次粗读:看整体流程,看每个模块的外围性能和职责,领会平时写的代码在源码外面通过了什么步骤体现到了页面上。
  • 二次精读:看细节实现,弄清楚外围模块的实现形式(如弄懂diff算法思路,最好本人入手实现)。
  • 三次领悟:领悟源码整体架构和设计思维,领会每个模块之间如何配合合作,架构如何组织。

二、步骤

  • 依赖剖析组装:路由、父子组件层级
  • 模版编译:解析成AST语法树,进而构建虚构dom树
  • 装载页面:虚构dom整体转化为实在dom
  • 部分更新:响应式数据监控到变动,diff比拟数据变动前后的虚构dom树差别,部分更新dom
  • 销毁:销毁虚构dom,移除dom

三、vue源码导读

  • template格调、对象配置格调
  • 虚构dom思维(js对象操作代替dom操作)
  • diff算法思维(同层比拟,增加、挪动、删除)
  • 组件化思维(组件编译、组件通信)
  • 数据响应式(依赖收集、派发更新,公布订阅)

四、vue3新个性理解

vue2.x的痛点:

  • 源码本身的维护性;
  • 数据量大后带来的渲染和更新的性能问题;
  • 一些想舍弃但为了兼容始终保留的鸡肋 API 等;
  • TypeScript 反对;

vue3.0优化点:

  • 一、应用 monorepo治理源码
  • 二、应用 TypeScript 开发源码
  • 三、性能优化 1.源码体积优化 2.数据劫持优化Proxy 3.编译优化 4.diff算法优化
  • 四、语法 API 优化:Composition API

插一个题外话,小编整顿了下用 Vue 3.0 来写个小程序框架的PDF材料,感兴趣的小伙伴们请点击这里支付

五、细究一下diff算法

vue2的diff

组件更新外围是响应式数据监控到数据的扭转,从新生成了虚构dom树,而后通过diff算法计算出前后虚构dom树的差别点,更新dom时只更新变动的局部。 快问快答:

1. 为什么要diff?

答: O(n^3) 意味着如果要展现1000个节点,就要顺次执行上十亿次的比拟,无奈接受大数据量的比照。

间接比拟和批改两个树的复杂度为什么是n^3?

答: 老树的每一个节点都去遍历新树的节点,直到找到新树对应的节点。那么这个流程就是 O(n^2),再紧接着找到不同之后,再计算最短批改间隔而后批改节点,这里是 O(n^3)。

2. diff的策略是什么?有什么依据?

答: 1、Web UI 中 DOM 节点跨层级的挪动操作特地少,能够忽略不计,因而仅进行同层比拟。 2、如果父节点不同,放弃对子节点的比拟,间接删除旧节点而后增加新的节点从新渲染; 3、如果子节点有变动,Virtual DOM不会计算变动的是什么,而是从新渲染。 4、同级多个节点可通过惟一的key比照异同;

3. diff流程是什么?

答: 新旧节点不同:创立新节点 ➜ 更新父占位符节点 ➜ 删除旧节点; 新旧节点雷同且没有子节点:不变; 新旧节点雷同且都有子节点:遍历子节点同级比拟,做挪动、增加、删除三个操作,具体见下图;

vue3.0的diff

深度递归遍历vnode树,节点的标签和key雷同认为是同一个节点则更新,不同则删除,而后解决子节点。 子节点分这几种状况解决:纯文本、vnode 数组和空

空往往意味着增加或删除; 纯文本雷同间接更新innerText,不同则删除; 新旧子节点都是vnode数组则diff算法来解决;

vue3.0 diff算法思维

  • 编译模版时进行动态剖析,标记动静节点,diff比照差别时仅比照动静节点(性能晋升显著);
  • diff算法先去头去尾,借此缩短遍历比照数组长度(对数组插入和删除操作性能优化显著);
  • 通过对更新前后子节点数组建设映射表的形式,将O(n^2)复杂度的遍历升高到O(n);
  • 通过最长递增子序列办法了来diff前后的子节点数组,缩小挪动操作的次数;

最长递增子序列算法实现

/* * 寻找最长递增子序列 * 应用动静布局思维,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;}

浏览vue源码姿态小伙伴们你们学废了嘛,你们都是如何浏览的呢,欢送评论留言通知小编哦。

还有想学用 Vue 3.0 来写个小程序框架的小伙伴们记得支付!点击这里也是一样能够支付的

求点赞求反对!提前祝小伙伴们五一高兴嗷!