ݺߣ

ݺߣShare a Scribd company logo
불변객체 적용으로
리액트 성능 최적화
송헌용
발표에 사용할 예제
2
컴포넌트 파일 구조
3
• App: 엔트리 포인트
• Container: 자식들을 감싸고 있는 부모
• Title: 타이틀 영역
• AddLi: inputbox 영역
• TodoLi: 리스트 중 개별 영역
컴포넌트 구조
4
렌더링 프로세스
1. 초기 props/state로 render 메소드 실행
2. 외부에서 데이터 받음 (ex. AJAX)
3. 전달 받은 컴포넌트에서 setState 메소드 실행
• 내부 트리거에 의해 render 메소드 자동 실행
4. 기존 대비 바뀌는 부분만 렌더링
• virtual DOM 내부적으로 판단
5
문제점1
• 부모에서 setState 메소드를 실행할 경우
• 딸려있는 모든 자식의 render 메소드가 실행
• 결과적으로 바뀌든 바뀌지 않든 실행
• virtual DOM에서 판단하는 과정이 성능에 영향
6
shouldComponentUpdate
• 컴포넌트의 업데이트 가능성을 미리 알려주는 메소드
• 기본 값은 true
• 만약 false일 경우 아래의 메소드는 실행 X
• componentWillUpdate
• render
• componentDidUpdate
7
사용 예
• ex1
shouldComponentUpdate(nextProps, nextState) {
return (
this.props.text !== nextProps.text
);
}
• ex2
shouldComponentUpdate(nextProps, nextState) {
return (
this.state.todos !== nextState.todos
);
}
8
문제점2
9
• 비교 대상이 참조 타입(Array, Object...)이라면?
• 항상 객체 복사를 통해 새로운 객체 생성
• 그렇지 않으면 참조가 같아서 SCU 비교 불가
문제점2
10
• 객체의 구조가 깊은 구조라면?
• this.state.todos.obj1.value !==
nextState.todos.obj1.value ||
this.state.todos.obj2.value !==
nextState.todos.obj1.value
• SCU 비교 로직이 복잡해짐
• this.state.todos !== nextState.todos
• 훨씬 간단
가변객체
• 자바스크립트의 Object는 생성 후, 변경 가능
• ES5 이하: Array, Object, etc
• ES6 이상: Array, Object, Map, Set, etc
var testStr = "str";
testStr.substr(0, 1); // “s"
console.log(testStr); // "str"
var testArr = ["a", "r", "r"];
testArr.pop(); // "r"
console.log(testArr); // ["a", "r"]
• 참조를 공유하는 모든 곳에 부작용 발생
11
Immutable.js
• 페이스북에서 만든 라이브러리
• 리액트와의 의존성 없음
• 어느 곳에서나 사용 가능
• 원본 객체는 수정되지 않는다는 컨셉
• 새로운 객체 생성
• 다양한 자료구조
• List, Stack, Map, OrderedMap, Set, OrderedSet, Record 등
12
Immutable.js
• 변경이 일어나면 새로운 객체를 반환
• ex 배열 수정
const immutableArray = Immutable.List([]);
const immutableArray2 = immutableArray.push(1);
console.log(immutableArray === immutableArray2); // false
// immutableArray = [];
// immutableArray2 = [1];
13
immutability-helper
• react-addons-update의 새로운 이름
• 리액트와의 의존성 없음
• 어느 곳에서나 사용 가능
• 원본 객체는 수정되지 않는다는 컨셉
• 새로운 객체 생성
• Array, Object에만 대응
14
결론
• 문제점1
• 부모 쪽 데이터 갱신 -> 자식의 모든 render가 실행
• 해결: SCU 메소드 활용
• 문제점2
• 참조 타입의 수정 부작용
• 해결: Immutable.js / Immutability-helper 활용
15
결론
• 렌더링 퍼포먼스 향상
16
FE팀 메일링으로 질문 환영합니다
• Vanilla(= Native)
• Angular
• Vue
• React
17
참고
18
• 컴포넌트 성능 최적화
• 링크: 리액트 가이드
• Immutability Helpers
• 링크: 리액트 가이드
• state 객체를 immutable.js로 다루기
• 링크: 리액트 가이드

More Related Content

불변객체 적용으로 리액트 성능 최적화

  • 3. 컴포넌트 파일 구조 3 • App: 엔트리 포인트 • Container: 자식들을 감싸고 있는 부모 • Title: 타이틀 영역 • AddLi: inputbox 영역 • TodoLi: 리스트 중 개별 영역
  • 5. 렌더링 프로세스 1. 초기 props/state로 render 메소드 실행 2. 외부에서 데이터 받음 (ex. AJAX) 3. 전달 받은 컴포넌트에서 setState 메소드 실행 • 내부 트리거에 의해 render 메소드 자동 실행 4. 기존 대비 바뀌는 부분만 렌더링 • virtual DOM 내부적으로 판단 5
  • 6. 문제점1 • 부모에서 setState 메소드를 실행할 경우 • 딸려있는 모든 자식의 render 메소드가 실행 • 결과적으로 바뀌든 바뀌지 않든 실행 • virtual DOM에서 판단하는 과정이 성능에 영향 6
  • 7. shouldComponentUpdate • 컴포넌트의 업데이트 가능성을 미리 알려주는 메소드 • 기본 값은 true • 만약 false일 경우 아래의 메소드는 실행 X • componentWillUpdate • render • componentDidUpdate 7
  • 8. 사용 예 • ex1 shouldComponentUpdate(nextProps, nextState) { return ( this.props.text !== nextProps.text ); } • ex2 shouldComponentUpdate(nextProps, nextState) { return ( this.state.todos !== nextState.todos ); } 8
  • 9. 문제점2 9 • 비교 대상이 참조 타입(Array, Object...)이라면? • 항상 객체 복사를 통해 새로운 객체 생성 • 그렇지 않으면 참조가 같아서 SCU 비교 불가
  • 10. 문제점2 10 • 객체의 구조가 깊은 구조라면? • this.state.todos.obj1.value !== nextState.todos.obj1.value || this.state.todos.obj2.value !== nextState.todos.obj1.value • SCU 비교 로직이 복잡해짐 • this.state.todos !== nextState.todos • 훨씬 간단
  • 11. 가변객체 • 자바스크립트의 Object는 생성 후, 변경 가능 • ES5 이하: Array, Object, etc • ES6 이상: Array, Object, Map, Set, etc var testStr = "str"; testStr.substr(0, 1); // “s" console.log(testStr); // "str" var testArr = ["a", "r", "r"]; testArr.pop(); // "r" console.log(testArr); // ["a", "r"] • 참조를 공유하는 모든 곳에 부작용 발생 11
  • 12. Immutable.js • 페이스북에서 만든 라이브러리 • 리액트와의 의존성 없음 • 어느 곳에서나 사용 가능 • 원본 객체는 수정되지 않는다는 컨셉 • 새로운 객체 생성 • 다양한 자료구조 • List, Stack, Map, OrderedMap, Set, OrderedSet, Record 등 12
  • 13. Immutable.js • 변경이 일어나면 새로운 객체를 반환 • ex 배열 수정 const immutableArray = Immutable.List([]); const immutableArray2 = immutableArray.push(1); console.log(immutableArray === immutableArray2); // false // immutableArray = []; // immutableArray2 = [1]; 13
  • 14. immutability-helper • react-addons-update의 새로운 이름 • 리액트와의 의존성 없음 • 어느 곳에서나 사용 가능 • 원본 객체는 수정되지 않는다는 컨셉 • 새로운 객체 생성 • Array, Object에만 대응 14
  • 15. 결론 • 문제점1 • 부모 쪽 데이터 갱신 -> 자식의 모든 render가 실행 • 해결: SCU 메소드 활용 • 문제점2 • 참조 타입의 수정 부작용 • 해결: Immutable.js / Immutability-helper 활용 15
  • 17. FE팀 메일링으로 질문 환영합니다 • Vanilla(= Native) • Angular • Vue • React 17
  • 18. 참고 18 • 컴포넌트 성능 최적화 • 링크: 리액트 가이드 • Immutability Helpers • 링크: 리액트 가이드 • state 객체를 immutable.js로 다루기 • 링크: 리액트 가이드