React dom过程
不可变数据,Immutable 是在 数据结构参数变化 到 虚拟dom对象的阶段。
diff算法是在 旧的虚拟dom 到 新的虚拟dom的阶段。
从数据结构 -> 虚拟对象 -> 到虚拟dom树 -> 新的虚拟dom -> 渲染成真实dom -> 挂载
相比于一版树形结构对比,算法复杂度可以从(o(n^3))降低到 (o(n))。
树形dom树结构如果有1000子节点,一般diff算法,会比较1000^3次,浪费资源。
diff策略提供了逐步提升渲染dom节点的性能,主要有 3 个策略
React diff 算法
将虚拟dom转换成真实dom的过程,称为调和,调和的具体实现就是 diff策略。
主要有 3类 diff算法,可以将复杂度 o(n^3) 转换为 o(n) 。
tree diff
(1), updateDepth对Virtual DOM树进行层级控制
(2), 同层比较,如果节点不存在,该节点及其子节点都会被删除
(3), 只需遍历一次,就能完成整棵dom树的比较
(4), 如果是跨层级,只有新建节点和删除节点的操作,推荐尽量不要跨层级,跨层级可用css display: none等手段完成。
component diff
(1), 同类型的两个组件,比较Virtual DOM树
(2), 若两次组件未发生变化可以通过 shouldComponentUpdate 做判断
(3), 不同类型的组件,会被判定作为脏组件处理,直接删除。或创建新组建
element diff
(1),判断旧的和新的组件集合,如果有组件变更,需要重新创建
(2),同组被子节点添加 唯一的key 进行组件区分,主要操作: 移动,插入,删除
重点说下移动
(1),新旧节点会对比下标,新的下标称为lastIndex,旧的称为index,如果lastIndex大于index,需要将节点旧的节点移动到新的位置,相反则不动。
(2),如果没有找到对应位置节点,新增; 如果旧的节点在新的节点组用不到,则删除;一般是在最后做删除操作。
(3),特殊情形,最后一个节点移动到第一个位置,会导致,前面的n-1个节点的lastIndex都比较大,然后都后移,影响性能。尽量避免这样的操作。