We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
所谓diff算法,就是给定任意两棵树,找到最少的转换步骤。传统的的Diff 算法复杂度需要O(n^3)。
react总结Web UI的特点,将diff算法的复杂度提升到O(n),主要依据以下3个策略。
基于上面的原则,react从tree diff、component diff、element diff三个方面对diff算法就行了优化。
基于策略1,react对整颗树进行比对的时候,只需要将同层级的节点进行比对。
如上图所示,同颜色框中的节点才会进行比较,只要发现节点不存在,就会将该节点整个删除。
基于策略2,react会比对组件的类型,只要类型不同,就会将组件整个删除;如果发现是相同的组件,就会将组件下的节点进行比对。
统一层级下面的接口进行比对的时候,有3种情况
react会顺序对比相同位置上节点,如果节点不同则会新增节点,并删除老的节点
function enqueueInsertMarkup(parentInst, markup, toIndex) { updateQueue.push({ parentInst: parentInst, parentNode: null, type: ReactMultiChildUpdateTypes.INSERT_MARKUP, markupIndex: markupQueue.push(markup) - 1, content: null, fromIndex: null, toIndex: toIndex, }); } function enqueueMove(parentInst, fromIndex, toIndex) { updateQueue.push({ parentInst: parentInst, parentNode: null, type: ReactMultiChildUpdateTypes.MOVE_EXISTING, markupIndex: null, content: null, fromIndex: fromIndex, toIndex: toIndex, }); } function enqueueRemove(parentInst, fromIndex) { updateQueue.push({ parentInst: parentInst, parentNode: null, type: ReactMultiChildUpdateTypes.REMOVE_NODE, markupIndex: null, content: null, fromIndex: fromIndex, toIndex: null, }); }
为了实现对原有节点的重复使用,用key来表示是否是相同的节点。
_updateChildren: function(nextNestedChildrenElements, transaction, context) { var prevChildren = this._renderedChildren; var nextChildren = this._reconcilerUpdateChildren( prevChildren, nextNestedChildrenElements, transaction, context ); if (!nextChildren && !prevChildren) { return; } var name; var lastIndex = 0; var nextIndex = 0; for (name in nextChildren) { if (!nextChildren.hasOwnProperty(name)) { continue; } var prevChild = prevChildren && prevChildren[name]; var nextChild = nextChildren[name]; if (prevChild === nextChild) { // 移动节点 this.moveChild(prevChild, nextIndex, lastIndex); lastIndex = Math.max(prevChild._mountIndex, lastIndex); prevChild._mountIndex = nextIndex; } else { if (prevChild) { lastIndex = Math.max(prevChild._mountIndex, lastIndex); // 删除节点 this._unmountChild(prevChild); } // 初始化并创建节点 this._mountChildAtIndex( nextChild, nextIndex, transaction, context ); } nextIndex++; } for (name in prevChildren) { if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) { this._unmountChild(prevChildren[name]); } } this._renderedChildren = nextChildren; }, // 移动节点 moveChild: function(child, toIndex, lastIndex) { if (child._mountIndex < lastIndex) { this.prepareToManageChildren(); enqueueMove(this, child._mountIndex, toIndex); } }, // 创建节点 createChild: function(child, mountImage) { this.prepareToManageChildren(); enqueueInsertMarkup(this, mountImage, child._mountIndex); }, // 删除节点 removeChild: function(child) { this.prepareToManageChildren(); enqueueRemove(this, child._mountIndex); }, _unmountChild: function(child) { this.removeChild(child); child._mountIndex = null; }, _mountChildAtIndex: function( child, index, transaction, context) { var mountImage = ReactReconciler.mountComponent( child, transaction, this, this._nativeContainerInfo, context ); child._mountIndex = index; this.createChild(child, mountImage); },
React 源码剖析系列 - 不可思议的 react diff
The text was updated successfully, but these errors were encountered:
No branches or pull requests
传统diff
所谓diff算法,就是给定任意两棵树,找到最少的转换步骤。传统的的Diff 算法复杂度需要O(n^3)。
react diff
react总结Web UI的特点,将diff算法的复杂度提升到O(n),主要依据以下3个策略。
基于上面的原则,react从tree diff、component diff、element diff三个方面对diff算法就行了优化。
tree diff
基于策略1,react对整颗树进行比对的时候,只需要将同层级的节点进行比对。
如上图所示,同颜色框中的节点才会进行比较,只要发现节点不存在,就会将该节点整个删除。
component diff
基于策略2,react会比对组件的类型,只要类型不同,就会将组件整个删除;如果发现是相同的组件,就会将组件下的节点进行比对。
element diff
统一层级下面的接口进行比对的时候,有3种情况
react会顺序对比相同位置上节点,如果节点不同则会新增节点,并删除老的节点
key
为了实现对原有节点的重复使用,用key来表示是否是相同的节点。
参考
React 源码剖析系列 - 不可思议的 react diff
The text was updated successfully, but these errors were encountered: