虚拟DOM
1 .将UI结构通过数据结构虚拟的表示出来,保存在内存中,然后让真实的DOM与之保持同步.
2 .挂载:遍历整个虚拟Dom,根据这个构建真实的DOM树。
3 .更新:diff新旧虚拟dom树,找出他们之间的区别,并应用这其中的变化到真实的DOM上
默认模版的好处
1 .更贴近真实的HTML
2 .可以让我们更方便的复用已有的HTML代码片段.我觉得这个不算,复用的最优先解永远是组件,而不是复制代码块
3 .有更好的访问性体验
4 .更方便的使用css应用样式
5 .语法确定,可以方便的对模版做静态分析
6 .Vue的模版编译器可以应用许多编译时优化来提升虚拟DOM的性能表现
1 .react 虚拟DOM是运行时的,每次更新无法预知新的DOM树,所以需要遍历整颗DOM树,比较每个vnode上的props来确保正确性。
2 .即使一棵树的某个部分没有改变,还是会在每次重渲染的时候创建新的vnode,带来了大量不必要的内存压力。是一个暴力的更新过程
3 .在vue找那个,框架可以同时运行编译器和运行时,编译器可以静态分析模版并在生成代码中留下标记,使得运行时尽可能走捷径。
4 .静态提升部分
<div>
<div>foo</div> <!-- 需提升 -->
<div>bar</div> <!-- 需提升 -->
<div>{{ dynamic }}</div>
</div>
foo,bar这俩是完全静态的,重新渲染的时候会自动提升这部分vnode创建函数到这个模版的渲染函数之外,每次渲染的时候都使用这份相同的vnode,渲染器知道新旧vnode在这部分是完全相同的,会完全跳过对他们的差异对比所以这个还不在外面,还是复用的不彻底,应该是可以完全使用原来的dom,而不是仅仅复用vnode
4.2 当有足够多的静态元素的时候,还会压缩为一个静态vnode,包含这些节点相应的纯html字符串。这些节点就会直接通过innerHtml来挂载,同时还会在初次挂载后缓存相应的DOM节点,如果这部分内容在应用中被其他地方重用,会使用cloneNode方法来克隆新的DOM节点,会非常高效
image.png
4.3 .更新类型标记
1 .对于有单个动态绑定的元素来说,可以在编译时推断出一些信息
<!-- 仅含 class 绑定 -->
<div :class="{ active }"></div>
<!-- 仅含 id 和 value 绑定 -->
<input :id="id" :value="value">
<!-- 仅含文本子节点 -->
<div>{{ dynamic }}</div>
1 .在对这些元素生成渲染函数时,Vue在vnode创建调用中直接编码了每个元素所需的更新类型
createElementVNode("div", {
class: _normalizeClass({ active: _ctx.active })
}, null, 2 /* CLASS */)
2 .这里的2就是更新标记类型,Vue能够在更新带有动态绑定的元素时做最少得操作
4.4 树结构打平.主要是为了便于上面的编译优化
<div> <!-- root block -->
<div>...</div> <!-- 不会追踪 -->
<div :id="id"></div> <!-- 要追踪 -->
<div> <!-- 不会追踪 -->
<div>{{ bar }}</div> <!-- 要追踪 -->
</div>
</div>
//比如上面的结构
div (block root)
- div 带有 :id 绑定
- div 带有 {{ bar }} 绑定
// 会是这样的结构,里面仅仅包含所有动态的后代节点
4.5 当组件需要重新渲染的时候,只需要遍历这个带有动态节点的数组,不需要遍历全部dom节点
4.6 模版中任何静态部分都会被高效的略过.为啥还是会有diff虚拟dom的操作呢
5 .对SSR 激活的影响
1 .单个元素的激活可以基于相应vnode 的更新类型标记走更快的捷径
2 .在激活时只有区块节点和其动态子节点需要被遍历,这在模版层面上实现更高效的部分激活
网友评论