1. DOM操作非常耗费性能
以前用jquery,可以自行控制DOM操作的时机,手动调整
Vue和React是数据驱动视图,如何有效控制DOM操作?
2. 有了一定复杂度,想减少计算次数比较难
能不能把计算,更多的转移为js计算?因为js执行速度很快
vdom-->用js模拟DOM结构,计算出最小的变更,操作DOM
<div class="aaa" id="div1">
<p>vdom</p>
<ul style="font-size:20px">
<li>a</li>
</ul>
</div>
用js模拟DOM结构,上面的html转成下面的结构
{
tag:‘div‘,
props:{
className:‘aaa‘,
id:‘div‘
},
children:[{
tag:‘p‘,
children:‘vdom‘
},{
tag:‘ul‘,
props:{style:‘font-size:20px‘},
children:[{
}]
}]
}
3.通过snabbdom学习vdom
生成vnode:h函数:传入tag元素、属性、子节点等,返回vnode数据结构return { sel, data, children, text, elm, key };
patch函数-->patch(vnode, newVnode),对比tag,对比tag与key,对比children
updateChidren==>更新children==>key的重要性
const snabbdom = window.snabbdom
// 定义 patch
const patch = snabbdom.init([
snabbdom_class,
snabbdom_props,
snabbdom_style,
snabbdom_eventlisteners
])
// 定义 h
const h = snabbdom.h
const container = document.getElementById(‘container‘)
// 生成 vnode
const vnode = h(‘ul#list‘, {}, [
h(‘li.item‘, {}, ‘Item 1‘),
h(‘li.item‘, {}, ‘Item 2‘)
])
patch(container, vnode)
document.getElementById(‘btn-change‘).addEventListener(‘click‘, () => {
// 生成 newVnode
const newVnode = h(‘ul#list‘, {}, [
h(‘li.item‘, {}, ‘Item 1‘),
h(‘li.item‘, {}, ‘Item B‘),
h(‘li.item‘, {}, ‘Item 3‘)
])
patch(vnode, newVnode)
})
4. diff算法-->最大程度减少渲染的范围,通过把DOM通过js去模拟,找出最小变更和范围
dif算法是vdom中最核心和最关键的部分
diff算法能在日常使用vue React中体现出来(如key)
5.diff算法概述
diff即对比,是一个广泛的概念,如 linux diff,git diff
两个js做对比
两棵树做diff,这里的vdom diff
6.树diff的时间复杂度 O(n^3)
1.遍历第一棵树
2.遍及第二棵树
3.排序
三次循环,1000个节点,要计算1亿次,算法不可用
===>
优化时间复杂度到O(n)
1.0 只比较同一层级,不跨级比较
2.0 tag不同,则直接删掉重建,不深度比较
3.0 tag和key,两者都相同,则认为是相同节点,不再深度比较
7.diff算法源码-->生成vnode:h函数:传入tag元素、属性、子节点等,返回vnode数据结构return { sel, data, children, text, elm, key };
patch函数-->patch(vnode, newVnode),对比tag,对比tag与key,对比children
updateChidren==>更新children==>key的重要性
8.vdom和diff算法总结
细节不重要,核心概念很重要:h,vnode,patch,diff,key