简介一下集体浏览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 来写个小程序框架的小伙伴们记得支付!点击这里也是一样能够支付的
求点赞求反对!提前祝小伙伴们五一高兴嗷!