이전에 만든 프로젝트에서 진행하거나
git clone https://github.com/vlpt-playground/react-contact-tagged.git
모니터링 도구 설치
$ yarn add react-addons-perf --dev
App.js 상단에
import Perf from 'react-addons-perf';
성능 확인하고 싶은 부분 선택
모달 열 때 성능을 모니터링 해보자!
setState 하기전에 Perf.start();
// FloatingButton 클릭
handleFloatingButtonClick = () => {
// 현재 view 가 list 가 아니면 list 로 설정
const { view } = this.state;
if(view !== 'list')
this.setState({view: 'list'});
Perf.start();
// Contact 추가 모달 띄우기
this.modalHandler.show(
'create',
{
name: '',
phone: '',
color: generateRandomColor()
}
);
}
벤치마크 생성
componentDidMount() {
// Perf 가 실행중이라면
if(Perf.isRunning()) {
// Perf 를 멈추고 결과를 프린트한다.
Perf.stop();
Perf.printInclusive();
Perf.printWasted();
}
}
첫번째 테이블: 전체 렌더링 정보
두번째 : 낭비 렌더링 정보
ContactItem 이 낭비렌더링 중..
src/components/ContactItem.js
shouldComponentUpdate(nextProps, nextState) {
return this.props.contact !== nextProps.contact;
}
shouldComponentUpdate 로 불필요한 렌더링 막기
낭비 렌더링 3.65ms -> 0.7ms
ContactList 도 불필요한 렌더링을 하고있다.
막아주자!
src/components/ContactList.js
shouldComponentUpdate(nextProps, nextState) {
return this.props.contacts !== nextProps.contacts
|| this.props.search !== nextProps.search;
}
ContactList 가 업데이트 되는 경우는 contacts 가 변경되거나,
키워드가 변경되었을때
이런식으로 최적화하면 되는데.. (아직 하지마세요)
더욱 쉬운 방법이 존재!
PureComponent !
shouldComponentUpdate 를 자동으로 구현해줌
전달받은 모든 props 를 shallow-compare
shallowCompare?
{
a: {
b: 'hello',
c: 'world'
},
d: 'hi',
e: 'there'
}
겉에만 검사한다!
a, d, e 만 검사함
b, c 값은 검사하지 않음
src/components/ContactList.js
import React, { PureComponent } from 'react';
(...)
class ContactList extends PureComponent {
0.7ms -> 0.35ms
PureComponent 는 일반적인 경우엔 용이하나,
props 데이터의 구조가 복잡해진다면
제대로 작동하지 않을 수 있다.
너무 남용은 X
shouldComponentUpdate 직접 쓰는게 더 좋음
shouldComponentUpdate 언제할까?
리스트를 렌더링할때..
실제로 버벅임이 느껴질 때..
지금은 App 에서 모든 상태를 관리하고있어서
불필요한 업데이트가 발생 할 수 밖에..
Redux 를 사용하게되면,
부모 컴포넌트한테서 받아오는게 아니라
컴포넌트가 특정 데이터를 구독하는 형식으로,
부모 업데이트 없이도 다른 props 를 받아올 수 있다
성능 시각적으로 분석하기
주소뒤에 ?react_perf 붙이고
크롬 개발자도구의 Performance 에서
User Timing 부분 주시