React의 Diff 알고리즘은 무엇입니까? Diff 알고리즘의 전략 및 구현
이 글의 내용은 React의 Diff 알고리즘이 무엇인지에 관한 것입니다. Diff 알고리즘의 전략과 구현에는 특정 참고 가치가 있습니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.
1. Diff 알고리즘은 무엇입니까? DOM 구조는 트리의 차이 검색 알고리즘이며 두 트리 간의 차이를 계산하는 시간 복잡도는 분명히 O(n^3)입니다. 너무 높아서 React가 이 전통적인 알고리즘을 채택하는 것은 불가능합니다. 🎜🎜#
- 앞서 언급했듯이 React는 가상 DOM 기술을 사용하여 구현됩니다. 실제 DOM의 매핑, 즉 React Diff 알고리즘의 차이 검색은 본질적으로 두 JavaScript 개체의 차이 검색입니다. 🎜🎜#
은 세 가지 전략을 기반으로 합니다. # 🎜🎜#
교차가 거의 없습니다. 웹 UI에서 DOM 노드의 수준 이동 작업이며 무시될 수 있습니다. (트리 diff)
같은 클래스를 가진 두 개의 컴포넌트는 비슷한 트리 구조를 생성하고, 다른 클래스를 가진 두 개의 컴포넌트는 다른 트리 구조를 생성합니다. (컴포넌트 diff) # 🎜🎜#동일한 수준의 하위 노드 그룹의 경우 고유 ID로 구분할 수 있습니다. (요소 차이)
- 2. React Diff 알고리즘의 해석
- 우선 , 명확해야 합니다. Diff 알고리즘은 React 업데이트 단계에서만 사용됩니다. #
React Diff 알고리즘 최적화 전략 차트:
- #🎜 🎜# React 업데이트 단계는 ReactElement 유형 판단에 따라 다양한 작업을 수행합니다. ReactElement 유형에는 텍스트, Dom 및 구성 요소의 세 가지 유형이 포함됩니다.
- 텍스트 노드 업데이트는 매우 간단합니다. 복사본을 직접 업데이트하면 됩니다.
- 브라우저의 기본 요소 업데이트는 두 부분으로 나뉩니다:
자식 노드 업데이트는 주로 차이점 개체를 찾을 때 위의 shouldUpdateReactComponent를 사용하여 판단합니다. 즉, 직접 업데이트할 수 있으며 하위 노드의 업데이트를 재귀적으로 호출하고 차이 개체도 재귀적으로 검색합니다. 이전 개체를 삭제하거나 새 개체를 추가하면 직접 업데이트할 수 없습니다. 그런 다음 차이 개체를 기반으로 DOM 요소(위치 변경, 삭제, 추가 등)를 작동합니다.
- 사실 Diff 알고리즘은 React 업데이트 단계의 DOM 요소 업데이트 프로세스에만 호출됩니다. 🎜🎜#왜그래?
- 이 업데이트되어 내용이 다른 경우 직접 업데이트되어 교체됩니다. 복잡한 Diff는 호출되지 않습니다.
-
2 사용자 정의 구성 요소의 경우:
ReactDOMTextComponent.prototype.receiveComponent(nextText, transaction) { //与之前保存的字符串比较 if (nextText !== this._currentElement) { this._currentElement = nextText; var nextStringText = '' + nextText; if (nextStringText !== this._stringText) { this._stringText = nextStringText; var commentNodes = this.getHostNode(); // 替换文本元素 DOMChildrenOperations.replaceDelimitedText( commentNodes[0], commentNodes[1], nextStringText ); } } }
로그인 후 복사 -
#🎜🎜 #명확해야 합니다. 컴포넌트로서 컴포넌트는 단지 Html 구조의 패키징 컨테이너일 뿐이며 이 Html 구조의 상태를 관리할 수 있는 기능이 있습니다. 핵심은 반환된 Html 구조입니다. render 함수에 의해 호출되는 Tab 클래스는 이 Html 구조의 패키징 컨테이너입니다(패키징 상자로 이해될 수 있음).
class Tab extends Component { constructor(props) { super(props); this.state = { index: 1, } } shouldComponentUpdate() { .... } render() { return ( <p> </p><p>item1</p> <p>item1</p> ) } }
로그인 후 복사 - #🎜🎜 #에서 볼 수 있듯이 React 렌더링 메커니즘 다이어그램에서 사용자 정의 구성 요소는 최종적으로 React Diff 최적화 전략 1과 결합됩니다(서로 다른 클래스의 두 구성 요소가 서로 다른 구조를 가짐)
-
3. 기본 요소:
ReactDOMComponent.prototype.receiveComponent = function(nextElement, transaction, context) { var prevElement = this._currentElement; this._currentElement = nextElement; this.updateComponent(transaction, prevElement, nextElement, context); } ReactDOMComponent.prototype.updateComponent = function(transaction, prevElement, nextElement, context) { //需要单独的更新属性 this._updateDOMProperties(lastProps, nextProps, transaction, isCustomComponentTag); //再更新子节点 this._updateDOMChildren( lastProps, nextProps, transaction, context ); // ...... }
- 3. React에서 Diff 알고리즘 구현
4. Diff를 기반으로 한 개발 제안
_updateChildren: function(nextNestedChildrenElements, transaction, context) { var prevChildren = this._renderedChildren; var removedNodes = {}; var mountImages = []; // 获取新的子元素数组 var nextChildren = this._reconcilerUpdateChildren( prevChildren, nextNestedChildrenElements, mountImages, removedNodes, transaction, context ); if (!nextChildren && !prevChildren) { return; } var updates = null; var name; var nextIndex = 0; var lastIndex = 0; var nextMountIndex = 0; var lastPlacedNode = null; for (name in nextChildren) { if (!nextChildren.hasOwnProperty(name)) { continue; } var prevChild = prevChildren && prevChildren[name]; var nextChild = nextChildren[name]; if (prevChild === nextChild) { // 同一个引用,说明是使用的同一个component,所以我们需要做移动的操作 // 移动已有的子节点 // NOTICE:这里根据nextIndex, lastIndex决定是否移动 updates = enqueue( updates, this.moveChild(prevChild, lastPlacedNode, nextIndex, lastIndex) ); // 更新lastIndex lastIndex = Math.max(prevChild._mountIndex, lastIndex); // 更新component的.mountIndex属性 prevChild._mountIndex = nextIndex; } else { if (prevChild) { // 更新lastIndex lastIndex = Math.max(prevChild._mountIndex, lastIndex); } // 添加新的子节点在指定的位置上 updates = enqueue( updates, this._mountChildAtIndex( nextChild, mountImages[nextMountIndex], lastPlacedNode, nextIndex, transaction, context ) ); nextMountIndex++; } // 更新nextIndex nextIndex++; lastPlacedNode = ReactReconciler.getHostNode(nextChild); } // 移除掉不存在的旧子节点,和旧子节点和新子节点不同的旧子节点 for (name in removedNodes) { if (removedNodes.hasOwnProperty(name)) { updates = enqueue( updates, this._unmountChild(prevChildren[name], removedNodes[name]) ); } } }
로그인 후 복사 - # 🎜 🎜#트리 차이 기준:
컴포넌트를 개발할 때 안정성 유지에 주의하세요. DOM 구조 즉, DOM 구조를 가능한 한 적게 동적으로 조작합니다. 특히 이동 작업은 더욱 그렇습니다.
노드 수가 너무 많거나 페이지 업데이트 횟수가 너무 많으면 페이지 지연이 더욱 뚜렷해집니다.
DOM 노드를 실제로 제거하거나 추가하는 대신 CSS를 통해 노드를 숨기거나 표시할 수 있습니다.
- 구성요소 차이 기준
- :
불필요한 컴포넌트 업데이트를 줄이기 위해 shouldComponentUpdate() 사용에 주의하세요.
유사한 구조는 가능한 한 컴포넌트로 캡슐화해야 합니다. 그러면 코드 양이 줄어들 뿐만 아니라 컴포넌트 diff의 성능 소모도 줄어듭니다.
요소 차이에 따라:
목록 구조의 경우 노드 수가 너무 많거나 많을 때 마지막 노드를 목록의 선두로 이동하는 것과 같은 작업을 어느 정도 줄이십시오. 업데이트 작업이 너무 빈번하면 React의 렌더링 성능에 영향을 미칩니다.
위 내용은 React의 Diff 알고리즘은 무엇입니까? Diff 알고리즘의 전략 및 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











HTML의 테이블 테두리 안내. 여기에서는 HTML의 테이블 테두리 예제를 사용하여 테이블 테두리를 정의하는 여러 가지 방법을 논의합니다.

HTML의 Nested Table에 대한 안내입니다. 여기에서는 각 예와 함께 테이블 내에 테이블을 만드는 방법을 설명합니다.

HTML 여백-왼쪽 안내. 여기에서는 HTML margin-left에 대한 간략한 개요와 코드 구현과 함께 예제를 논의합니다.

HTML 테이블 레이아웃 안내. 여기에서는 HTML 테이블 레이아웃의 값에 대해 예제 및 출력 n 세부 사항과 함께 논의합니다.

HTML 입력 자리 표시자 안내. 여기서는 코드 및 출력과 함께 HTML 입력 자리 표시자의 예를 논의합니다.

HTML에서 텍스트 이동 안내. 여기서는 Marquee 태그가 구문과 함께 작동하는 방식과 구현할 예제에 대해 소개합니다.

HTML 순서 목록에 대한 안내입니다. 여기서는 HTML Ordered 목록 및 유형에 대한 소개와 각각의 예에 대해서도 설명합니다.

HTML onclick 버튼에 대한 안내입니다. 여기에서는 각각의 소개, 작업, 예제 및 다양한 이벤트의 onclick 이벤트에 대해 설명합니다.
