Chrome Devtools를 활용한
웹 프론트엔드 성능 측정과 개선
한재엽, LINE Financial
@Jbee
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402145/pasted-from-clipboard.png)
for beginner
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402173/profile.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5414054/스크린샷_2018-10-27_오후_2.14.02.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
성능이란?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402613/pasted-from-clipboard.png)
성능이란
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
UX
다.
User Experience
무조건 빠른 것이 아닌,
사용자에게 끊기는 느낌이 없도록
부드러운,
...
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402759/pasted-from-clipboard.png)
If you can't measure it,
you can't manage it"
측정할 수 없다면,
개선할 수 없다.
- 피터드러커
측정
-
RAIL
-
Audits
개선
-
로딩 과정
-
3R
-
최적화
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402625/pasted-from-clipboard.png)
측정
어떻게 측정할 수 있을까
- RAIL
- Audits
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402625/pasted-from-clipboard.png)
RAIL
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402613/pasted-from-clipboard.png)
R
A
I
L
esponse
입력 지연 시간이 100ms 미만
nimation
각 프레임 작업의 완료 시간은 16ms 미만
dle
oad
메인 스레드 JS 작업이 50ms 이하
페이지가 1000ms 이내에 사용할 준비
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
아쉬운 점
- 귀찮다.
- 이슈를 발견해도 파악이 어렵다.
- 해결한 후 다시 측정해야 한다.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
Audits
lighthouse
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402613/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5358652/lighthouse.png)
웹 앱의 품질을 개선하는 오픈 소스 자동화 도구
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5358653/audit.png)
Chrome Devtools - [Audits] tab
Identify and fix common problems that affect your site's performance, accessibility, and user experience.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5360612/audits_1.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
Audits results
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5372994/audit_results_1.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
Performance details
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5373001/audit_results_performance.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
Accessibility details
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5373013/audit_results_accessibility.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
Best practice details
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5373025/audit_results_best-practice.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
SEO details
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5373016/audit_results_seo.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
개선
어떻게 개선할 수 있을까
- 로딩 과정
- 3R
- 최적화
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402625/pasted-from-clipboard.png)
로딩 과정
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402613/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5360691/loading.png)
1. Connection
2. TTFB (Time To First Bytes) 이후 Single Thread에서 렌더링 시작
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5360698/rendering.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
3R
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402613/pasted-from-clipboard.png)
1. Request 개수
2. Resource 크기
3. Rendering 시간
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
1. Request 개수 줄이기
- With Webpack
- Merge js file
- Merge css file
- CSS sprite
- Lazy loading
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
2. Resource 사이즈 줄이기
- With Webpack
- Minify
- DCE
- Obfuscation
- Tree-shaking
- lodash 대신 lodash-es
- Code-splitting
- Minify
- 이미지 최적화
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
3. Rendering 시간 단축
-
CRP 최적화
- Script tag with async/defer keyword
- Reflow 최소화
- 부드러운 애니메이션
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
Lazy loading
- IntersectionObserver API
- Custom Image Element
- Native lazy load API
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402613/pasted-from-clipboard.png)
2900+ star react-lazyload
잘못된 예시
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5414196/code_0.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
IntersectionOberserver
The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
IntersectionObserver supports
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5360759/intersectionobserver_caniuse.png)
polyfill : https://github.com/w3c/IntersectionObserver
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
Code
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402818/code_1_1.png)
Threshold
lighthouse에서는 viewport 기준 (x + 100, y + 200) 으로 판단
rootMargin
root
callback 발생 조율
callback 발생 시점
viewport 판단 기준
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
IntersectionObserver 더 읽어보기
- 전반적인 설명 (http://bit.ly/2z4aV3i)
- Formatting Structure (https://www.w3.org/TR/CSS2/intro.html#formatting-structure)
- 명세 (https://www.w3.org/TR/intersection-observer/)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
IntersectionObserver + Custom Image Element
Image Lazy Loading
IntersectionObserver + Initialize component
Lazy Initialize component
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
Custom Image Element
- data-src
- data-alt
- data-emptySrc
- data-emptyAlt
- data-errorSrc
- data-errorAlt
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
Lazy Initialize example
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5373330/test.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
이미지 최적화
- data URI sheme
- srcset attribute
- 불필요한 metadata 제거
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402613/pasted-from-clipboard.png)
Data URI sheme
`data:` 스킴이 접두어로 붙은 URL은
작은 파일을 문서 내에 인라인으로 삽입할 수 있도록 해줍니다.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
<img src="https://www.test.com" alt="test"/>
<img src="data:image/png;base64,...==" alt="test" />
base64 encoding
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
Example
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5360805/data_uri.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
언제 적용하면 좋을까
- 캐싱할 필요가 없는 데이터
- 별도 파일이 아니므로 caching이 안 된다.
- 작은 용량의 이미지 파일
- 무채색의 이미지
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
srcset attribute
디바이스의 pixel ratio 크기에 맞는 이미지 사용
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
srcset support
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5360829/srcset_caniuse.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
Remove useless metadata
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5360835/remove_metadata_of_image.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
부드러운 애니메이션
- 하드웨어 가속
- 스크롤 이벤트 튜닝
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402613/pasted-from-clipboard.png)
하드웨어 가속
컴퓨팅에서 일부 기능을 CPU에서 구성하는 소프트웨어 방속보다 더 빠르게 수행할 수 있는 하드웨어의 사용
(여기서 말하는 하드웨어는 GPU)
CPU보다 GPU가 잘하는 일을 GPU에게 위임하는 것.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5368674/layer_tab.png)
Chrome Devtools - [Layer] tab
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5368689/layer_example_1.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5368691/layer_example_2.gif)
부드러운 애니메이션
- 하드웨어 가속
- 스크롤 이벤트 튜닝
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402613/pasted-from-clipboard.png)
Scroll Event
onScroll={...}
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5360864/scroll_animation.gif)
구현 애니메이션
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
Code #1
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402658/code_1.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5360873/scroll_ttriger.gif)
throttling...?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
Use `requestAnimationFrame`
- 초당 60회 rendering 하는 디바이스 브라우저에 최적화
- animationFrame queue를 사용
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5414061/pasted-from-clipboard.png)
Code #2
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402647/code_2.png)
Code #3
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402660/code_3.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
prevetDefault를 호출하지 않을 것임.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5414090/code_4.png)
{ passive: true }
마무리
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402625/pasted-from-clipboard.png)
- Case by Case 인 성능 튜닝
- 여러 복합적인 요소가 영향.
- 개발이 어느 정도 완료된 후 진행하길 권장.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
뭐가 성능이 더 좋나요?
- react vs vue
- redux vs mobx
- ...
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
Thanks
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402145/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402076/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/608899/images/5402173/profile.png)
@Jbee
devfest_seoul_2018_presentation
By Han JaeYeab
devfest_seoul_2018_presentation
Devfest Seoul 2018 Presentation
- 4,162