반응 구성요소 분할의 중요성

王林
풀어 주다: 2021-02-20 11:25:00
앞으로
2235명이 탐색했습니다.

반응 구성요소 분할의 중요성

머리말:

React는 사용자 인터페이스 구축을 위한 JAVASCRIPT 라이브러리입니다. 주로 UI 구축에 사용되는데, 많은 사람들이 React를 MVC의 V(뷰)로 생각합니다.

react는 가상 DOM 기술을 사용하여 Javascript와 실제 DOM 간의 상호 작용을 줄이고 단방향 데이터 흐름 메커니즘을 사용하여 프런트 엔드 성능을 향상시킵니다. 상위 구성 요소는 소품을 통해 하위 구성 요소에 데이터를 전달하므로 데이터 흐름이 한 눈에 방향이 명확하다.

구성 요소의 소품이나 상태가 변경되면 구성 요소와 해당 하위 구성 요소가 다시 렌더링되고 vdom-diffed되어 데이터 흐름 상호 작용이 완료됩니다. 그러나 이 메커니즘은 데이터 양이 많은 경우와 같은 일부 경우에는 성능 문제가 발생할 수 있습니다. React의 성능 병목 현상을 분석하고, React-addons-perf 도구를 사용하여 React 구성 요소 분할의 중요성을 설명하겠습니다.

React 성능 병목 현상

React의 성능 병목 현상을 이해하려면 React의 렌더링 프로세스를 알아야 합니다. 렌더링은 두 단계로 나눌 수 있습니다:

초기 구성 요소화
이 단계에서는 구성 요소와 모든 하위 구성 요소의 렌더링 방법을 실행하여 가상 돔의 첫 번째 버전을 생성합니다.

구성요소 업데이트 렌더링.
구성 요소의 소품이나 상태가 변경되면 구성 요소의 업데이트 렌더링이 트리거됩니다. 기본적으로 새 가상 DOM을 얻기 위해 구성 요소와 모든 하위 구성 요소의 렌더링 메서드도 실행합니다.

우리가 말하는 성능 병목 현상은 구성 요소 업데이트 단계의 상황을 나타냅니다.

react 컴포넌트 업데이트 프로세스

위의 분석을 통해 컴포넌트 업데이트의 구체적인 프로세스는 다음과 같음을 알 수 있습니다.

컴포넌트와 모든 하위 컴포넌트의 렌더 메소드를 실행하여 업데이트된 가상 DOM을 얻습니다. 즉, 하위 구성 요소를 업데이트할 필요가 없더라도 다시 렌더링합니다.

그런 다음 이전 가상 DOM과 새 가상 DOM을 비교하여 구성 요소를 업데이트합니다.

이 과정에서 구성 요소의 shouldComponentUpdate 메서드의 반환 값을 통해 다시 렌더링이 필요한지 여부를 결정할 수 있습니다.

React의 전체 업데이트 렌더링 프로세스는 그림으로 설명할 수 있습니다.

반응 구성요소 분할의 중요성

기본적으로 구성 요소의 shouldComponentUpdate는 true를 반환합니다. 즉, React는 기본적으로 모든 구성 요소의 render 메서드를 호출하여 새로운 가상 DOM을 생성합니다. 그런 다음 이전 가상 DOM을 비교하여 구성 요소를 결국 업데이트해야 하는지 여부를 결정합니다.

반응 성능 병목 현상

예를 들어 아래 그림은 특정 하위 구성 요소를 업데이트하려는 경우 아래 그림의 녹색 구성 요소(루트에서 전달된 데이터)입니다. ):

반응 구성요소 분할의 중요성

이상적으로는 아래와 같이 중요 경로의 구성 요소만 업데이트되기를 원합니다.

반응 구성요소 분할의 중요성

그러나 실제 효과는 각 구성 요소가 업데이트를 완료한다는 것입니다. 다시 렌더링하고 virtual-DOM diff 프로세스를 수행합니다. 구성 요소가 변경되지 않았지만 이는 분명히 낭비입니다. 아래 그림에서 노란색 부분은 낭비된 리렌더링과 virtual-DOM diff를 나타냅니다.

반응 구성요소 분할의 중요성

위 분석에 따르면 React의 성능 병목 현상은 주로 다음에서 나타납니다.

props와 상태가 변경되지 않은 구성 요소의 경우 React는 가상 DOM과 가상 DOM의 차이점도 재생성해야 합니다.

성능 최적화를 위해 shouldComponentUpdate 사용

React의 성능 병목 현상에 대응하여 React에서 제공하는 shouldComponentUpdate 메소드를 통해 다음과 같이 구성 요소를 선택적으로 업데이트하여 React의 성능을 향상시킬 수 있습니다.

shouldComponentUpdate에는 다음과 같은 사항이 필요합니다. 현재 속성과 상태가 지난번과 동일한지 확인하기 위해, 동일하다면 가상 DOM 및 해당 diff를 생성하는 후속 프로세스를 수행할 필요가 없으며, 그렇지 않으면 업데이트해야 합니다.

(학습 영상 공유: javascript 영상 튜토리얼)

구체적인 구현은 다음과 같이 표시할 수 있습니다.

shouldComponentUpdate(nextProps, nextState){   return !isEqual(nextProps, this.props) || !isEqual(nextState, this.state)
}
로그인 후 복사

그 중 isEqual 메소드는 두 객체가 동일한지 여부를 확인하는 것입니다(객체 내용이 동일하다는 사실 참조). 동일하지만 합동이 아닙니다).

쓸데없는 업데이트를 피하기 위해 구성 요소를 업데이트해야 하는지 여부를 결정하기 위해 shouldComponentUpdate 메서드를 표시하지만, 각 구성 요소에 이 메서드를 추가하는 것은 번거로울 수 있습니다. 다행히도 React는 구체적인 방법을 제공합니다.

구성 요소에 대한 솔루션입니다. shouldComponentUpdate는 구성 요소를 업데이트해야 하는지 여부를 결정하기 위해 구성 요소의 현재 속성 및 상태를 이전 구성 요소와 단순하게 비교하도록 캡슐화됩니다.

React는 다양한 개발 단계에서 두 가지 공식 솔루션 세트를 제공합니다.

PureRenderMin
One은 ES5의 React.createClass를 기반으로 생성된 구성 요소로, 이 형식의 믹스인을 사용하여 PureRenderMixin에서 제공하는 shouldComponentUpdate 메서드를 결합합니다. 물론 ES6으로 생성된 구성 요소도 이 솔루션을 사용할 수 있습니다.

반응 구성요소 분할의 중요성

PureComponent
이 솔루션은 React 15.3.0 버전에서 출시된 ES6용으로 추가된 컴포넌트 기본 클래스인 React.PureComponent입니다. 이는 분명히 ES6 방식으로 생성된 구성 요소에 더 친숙합니다.

반응 구성요소 분할의 중요성

PureRenderMin이든 PureComponent이든 내부 shouldComponentUpdate 메서드는 소품과 상태 개체를 얕은 비교(shallowCompare)합니다. 즉 개체의 첫 번째 레이어 속성과 그 값만 비교합니다. ​​​​동일합니다. 예를 들어, 다음 상태 개체는 다음 값으로 변경됩니다.

반응 구성요소 분할의 중요성

상태 값이 다른 개체에 할당되므로 nextState.value와 this.props.value가 항상 동일하지 않아 얕은 비교가 실패합니다. 실제 프로젝트에서는 이러한 중첩된 개체 결과가 매우 일반적입니다. PureRenderMin 또는 PureComponent 메서드를 사용하면 원하는 효과를 얻을 수 없습니다.

심층비교를 통해 판단할 수 있지만, 심층비교는 재귀 연산인 딥카피와 유사하며 성능 오버헤드가 상대적으로 크다.

이를 위해 구성 요소를 최대한 분할하여 구성 요소의 props 및 상태 객체 데이터를 평면화할 수 있습니다. PureRenderMin 또는 PureComponent를 사용하여 구성 요소가 업데이트되었는지 확인하면 반응 성능을 더 잘 향상할 수 있습니다. 인력이 너무 많이 신경 쓰지 않습니다.

구성 요소 분할

구성 요소 분할은 이에 대응하여 구성 요소를 최대한 세분화하여 재사용과 최적화를 용이하게 하는 것입니다. 분할의 구체적인 원칙:

분할 구성 요소를 업데이트할지 여부를 더 쉽게 결정하도록 하세요

이것은 이해하기 쉽지 않습니다. 예를 들어 보겠습니다. 5,000개의 하위 구성 요소를 포함하는 상위 구성 요소를 정의한다고 가정해 보겠습니다. 입력란 입력 동작이 있습니다. 숫자를 입력할 때마다 해당 하위 구성 요소의 배경색이 빨간색으로 변합니다.

반응 구성요소 분할의 중요성

이 예에서 입력 상자 구성 요소와 목록 하위 구성 요소는 분명히 다릅니다. 하나는 입력이 어떻게 입력되는지에 관계없이 입력 값이 상대적으로 더 빈번합니다. 5,000개의 항목만 포함됩니다. 입력 상자에 숫자를 입력할 때마다 모든 구성 요소가 다시 렌더링되므로 목록 하위 구성 요소가 불필요하게 업데이트됩니다.

위 목록 구성 요소의 업데이트는 입력 구성 요소와 목록 하위 구성 요소의 상태가 상위 구성 요소 상태에 있고 공유가 불가능하기 때문에 취소하기 쉽지 않다는 것을 알 수 있습니다. shouldComponentUpdate의 반환 값을 사용하여 구성 요소의 구성 요소 부분을 업데이트하도록 반응하고 다른 부분은 업데이트되지 않습니다. 이들을 서로 다른 구성 요소로 분할해야만 각 구성 요소는 해당 소품에만 관심을 갖습니다. 분할 목록 컴포넌트는 자신의 속성만 신경쓰고, 다른 컴포넌트는 상위 컴포넌트의 업데이트를 유발합니다. 목록 컴포넌트에서는 관심 있는 속성의 값을 판단하여 업데이트 여부를 결정할 수 있으므로 더 잘 최적화할 수 있습니다. 구성 요소.

분할 컴포넌트의 props와 상태 데이터를 평면화해 보세요

이는 주로 컴포넌트 최적화 관점에서 고려되는 부분이므로 컴포넌트가 성능에 너무 많은 관심을 기울일 필요가 없다면 무시해도 됩니다.

분할 컴포넌트가 플랫한 이유는 React에서 제공하는 최적화 솔루션 PureRenderMin 또는 PureComponent가 컴포넌트의 props와 state를 얕게 비교하여 컴포넌트 업데이트 여부를 결정하기 때문입니다.

위의 목록 구성 요소에서 this.state.items는 각 목록을 업데이트해야 하는지 더 잘 판단하기 위해 각 목록 항목을 목록 항목 구성 요소로 분할할 수 있습니다. 관련 소품은 항목 배열의 각 개체입니다. 이 플랫 데이터를 사용하면 데이터가 변경되었는지 쉽게 확인할 수 있습니다.

컴포넌트 분할의 예

이 기사에서는 Todo 목록 추가 및 표시에 대한 사례 라이브러리를 작성했습니다. 효과를 로컬에서 실행하려면 코드를 로컬로 복제하세요.

사례 라이브러리는 5,000개의 항목이 포함된 Todo 목록이며, Todo 항목을 삭제하고 추가할 수 있습니다. 이 예에서는 구성 요소 분할 전후의 경험을 비교하여 성능이 크게 향상되었음을 확인할 수 있습니다.

아래에서는 구성 요소 분할을 설명하기 위해 반응의 성능 테스트 도구인 React-addons-perf를 사용합니다.

분할 전 구성 요소 TodosBeforeDivision의 렌더링 부분은 다음과 같습니다.

반응 구성요소 분할의 중요성

구성 요소가 분할되기 전에 다음과 같이 입력 상자에 문자를 입력하거나 할 일을 추가하거나 할 일 항목을 삭제할 때 명백한 지연을 볼 수 있습니다. 아래 그림:

반응 구성요소 분할의 중요성

렉 현상의 원인을 파악하기 위해 Chrome의 devTool을 사용하여 이를 찾아냅니다. 구체적인 방법은 최신 버전의 Chrome 브라우저의 성능 옵션을 사용하여 완료하는 것입니다. 먼저 이 옵션에서 녹음 버튼을 클릭하면 녹음이 시작됩니다. 이때 컴포넌트 입력 상자에 문자를 입력한 다음 녹음을 중지하려면 녹음을 중지합니다. 입력.

반응 구성요소 분할의 중요성

그림에서 볼 수 있듯이, 단일 문자를 입력하면 입력 상자의 입력 이벤트 로직이 거의 전체 응답 시간을 차지합니다. 구체적인 처리 로직은 주로 반응 수준의 일괄 업데이트 메서드입니다. 사용자 정의 논리 대신 목록 구성 요소를 일괄 업데이트합니다.

그렇다면 일괄 업데이트에 시간이 이렇게 많이 걸리는 이유를 파악하기 위해, 우리는 React-addons-perf 기반의 크롬 플러그인 chrome-react-perf를 사용하는데, 이는 분석 결과를 크롬 플러그인.

이 플러그인을 사용할 때 주의할 점은 다음과 같습니다.

chrome-react-perf 플러그인을 사용하려면 프로젝트에 React-addons-perf 모듈을 도입해야 하며 해당 객체를 마운트해야 합니다. 창 전역 객체의 Perf 속성. 그렇지 않으면 사용할 수 없습니다.

devTool 도구에서 Perf 옵션 보기를 선택하고 시작 버튼을 클릭하면 구성 요소 입력 상자에 문자를 입력한 다음 Perf 보기에서 중지 버튼을 클릭하면 해당 성능 보기가 표시됩니다. .

반응 구성요소 분할의 중요성

위 그림에서 제공하는 4가지 뷰 중 Print Wasted가 성능 분석에 가장 도움이 됩니다. 이는 구성 요소가 변경되지 않았지만 업데이트 프로세스, 즉 다시 렌더링 및 업데이트 프로세스에 참여했음을 나타냅니다. vdom-diff가 낭비되었습니다. 그림에서 볼 수 있듯이 TodosBeforeDivision 및 TodoItem 구성 요소는 각각 167.88ms 및 144.47ms를 낭비합니다. 이 오버헤드는 구성 요소를 분할하여 피할 수 있습니다. 이것이 반응 성능 최적화의 초점입니다.

이를 위해 TodosBeforeDivision 구성 요소를 입력 및 버튼이 있는 동적 구성 요소인 AddTodoForm과 비교적 정적인 구성 요소인 TodoList로 분할해야 합니다. 둘 다 불필요한 구성 요소 업데이트를 피하기 위해 각각 React.PureComponent를 상속합니다.

반응 구성요소 분할의 중요성

TodoList 컴포넌트도 각 Todo 작업에 대한 TodoItem 컴포넌트로 분할해야 합니다. 그래야 각 TodoItem 컴포넌트의 props 객체가 플랫 데이터이고 React.PureComponent를 최대한 활용하여 객체의 얕은 비교를 수행할 수 있습니다. 어느 쪽이 더 낫습니까? 구성 요소를 독립적으로 업데이트해야 하는지 여부를 결정하면 TodoItem 항목이 추가되거나 삭제될 때 다른 TodoItem 구성 요소를 업데이트할 필요가 없습니다.

반응 구성요소 분할의 중요성

위의 성능 테스트 도구를 사용하여 분할 구성 요소의 해당 효과를 확인하세요.

반응 구성요소 분할의 중요성

위 스크린샷에서 볼 수 있듯이 분할 구성 요소의 성능이 수백 배 향상되었습니다. 또한 구성 요소 속성 위치에서 함수를 여기에 바인딩하지 않고 상수 개체 소품을 캐싱하여 다시 렌더링이 수행될 때마다 새로운 기능과 새 개체 소품이 재생성되는 것을 방지하는 등 몇 가지 다른 최적화도 포함되어 있습니다.

일반적으로 React 구성요소를 분할하는 것은 React 성능을 향상시키는 데 매우 중요합니다. 이는 React 성능 최적화를 위한 방향이기도 합니다.

관련 추천: 반응 튜토리얼

위 내용은 반응 구성요소 분할의 중요성의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:cnblogs.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿