1. Optimization
학습목표
- 최적화의 개념에 대해 학습합니다.
- 최적화가 분야 별로 어떤 의미로 사용이 되는지 학습하고, 컴퓨터 공학에서의 최적화에 대해 이해합니다.
- 최적화의 필요성 및 효과에 대해 학습하고, 최적화가 효과적인 UX 개선 수단임을 이해합니다.
- 최적화, 最適化, optimization
- 주어진 상황에서 원하는 가장 알맞은 결과를 얻을 수 있도록 처리하는 과정.
최적화는 허용된 자원의 한계 내에서 주어진 요구사항을 만족시키면서 최선의 결과를 얻는 과정이다. 수익과 관련되는 분야에서는 이익을 최대로 내는 과정을 말하기도 한다. 다양한 분야와 때에 따라 다르게 정의할 수 있고 물류(logistics), 설계(design) 문제 등에 응용된다.
- 컴퓨터 공학에서의 최적화는 가능한 적은 리소스를 소모하면서 가능한 한 빠르게 원하는 결과를 얻을 수 있도록 하는 것을 의미
- 최적화의 필요성 및 효과
- 이탈률 감소
- 전환율 증가
- 이탈률이 줄어들면, 전환율이 높아질 확률도 커진다.
- 전환율이란, 웹 사이트를 방문한 사용자 중 회원가입, 상품 구매, 게시글 조회, 다운로드 등의 행위를 한 방문자의 비율을 의미
- 수익 증대
- 이탈률 감소, 전환율 증가는 트래픽 증대 및 회원 수 증가로 이어지고, 이는 곧 수익 증대를 의미
- 사용자 경험(UX) 향상
2. Optimization 기법
학습목표
- HTML, CSS 코드를 최적화하는 방법에 대해 학습합니다.
- HTML 파일에서 JavsScript 파일과 CSS 파일을 불러오는 적절한 위치에 대해 학습하고 그 이유를 이해합니다.
- 브라우저 이미지를 최적화하는 방법에 대해 학습하고, 브라우저 이미지를 최적화할 시 어떤 것을 우선으로 고려해야 하는지에 대해 이해합니다.
- 아이콘 폰트를 사용하는 법에 대해 학습하고, 각 사용법에 대해 이해합니다.
- 캐시를 사용해야하는 이유와 사용 방법을 이해합니다.
- CDN의 개념에 대해 학습하고, CDN의 특징을 이해합니다.
- 웹 캐시의 필요성에 대해 이해합니다.
- Cache-Control: max-age=60이 어떤 의미인지 이해합니다.
- 요청에서 사용하는 If-Modified-Sinse 헤더와 응답에서 사용하는 Last-Modified 헤더에 대해 이해합니다.
- 요청에서 사용하는 If-None-Match헤더와 응답에서 사용하는 Etag 헤더에 대해 이해합니다.
- Tree Shaking의 개념에 대해 학습하고, 어떤 이유로 해당 방법을 이용해 최적화를 진행하면 되는 지에 대해 이해합니다.
- Tree Shaking을 이용한 최적화 방법에 대해 학습하고, 어느 때에 적용할 수 있는 지에 대해 이해합니다.
- Lighthouse의 개념에 대해 학습하고, Lighthouse의 특징에 대해 이해합니다.
- Lighthouse 사용법을 학습하고, 실제로 어떻게 사용할 수 있는 지에 대해 이해합니다.
- Lighthouse의 분석 결과 항목과 Performance 측정 메트릭에 대해 학습하고, 개선 방향을 잡는 법에 대해 이해합니다.
2-1. 최적화 기법
HTML, CSS 코드 최적화하기
- HTML 파일은 DOM 트리를, CSS 파일은 CSSOM 트리를 만들고 두 트리를 결합하여 렌더링할 때 사용
=> 이 두 트리 중에서 하나라도 변경되면 리렌더링을 유발하는데, 이때 트리의 크기가 크고 복잡할수록 더 많은 계산이 필요
=> HTML, CSS 코드를 최적화함으로써 렌더링 성능을 향상
1. HTML 최적화 방법
- DOM 트리 가볍게 만들기
- DOM 트리가 깊을수록, 자식 요소가 많을수록 DOM 트리의 복잡도는 커진다. 복잡도가 클 수록 DOM 트리가 변경되었을 때 계산해야 하는 것도 많아진다. HTML 요소들의 관계를 잘 살펴보고, 불필요하게 깊이를 증가시키는 요소가 있다면 삭제한다.
// 수정 전
<div>
<ol>
<li> 첫 번째 </li>
<li> 두 번째 </li>
<li> 세 번째 </li>
</ol>
</div>
// 수정 후 : 불필요한 div 요소 제거
<ol>
<li> 첫 번째 </li>
<li> 두 번째 </li>
<li> 세 번째 </li>
</ol>
//수정 전
<div style="margin: 10px;"> 마진 10px </div>
<div style="margin: 10px;"> 이것도 마진 10px </div>
//수정 후 : class와 CSS로 대체
<div class="margin10"> 마진 10px </div>
<div class="margin10"> 이것도 마진 10px </div>
.margin10 {
margin: 10px;
}
2. CSS 최적화 방법
- 사용하지 않는 CSS 제거하기
- 요소를 삭제할 일이 생기면, CSS 코드만 남지는 않는지 확인하고 함께 삭제
- 간결한 셀렉터 사용하기
// 복잡한 CSS 셀렉터 예시
.cart_page .cart_item #firstItem { ... }
// 필요한 경우에는 어쩔 수 없지만, 가능한 한 간결하게 작성해줍니다.
.cart_item { ... }
리소스 로딩 최적화하기
- HTML 파일에서 JavaScript 파일을 불러올 땐
<script>
요소를, CSS 파일을 불러올 땐 <link>
요소를 사용하는데, 이때 파일을 불러오는 위치가 어디인가에 따라서 렌더링 완료 시점이 달라질 수 있다.
1. CSS 파일 불러오기
- DOM 트리는 HTML 코드를 한 줄 한 줄 읽으면서 순차적으로 구성
- CSSOM 트리는 CSS 코드를 모두 해석해야 구성
=> CSSOM 트리를 가능한 빠르게 구성할 수 있도록 HTML 문서 최상단에 배치
// CSS 파일은 HTML 파일 상단의 head 요소 안에서 불러오는 것이 좋습니다.
<head>
<link href="style.css" rel="stylesheet" />
</head>
2. JavaScript 파일 불러오기
- JavaScript 파일은 DOM 트리 생성이 완료되는 시점인 HTML 문서 최하단에 배치
<body>
<div>...</div>
...
// JavsScript 파일은 body 요소가 닫히기 직전에 작성하는 것이 가장 좋습니다.
<script src="script.js" type="text/javascript"></script>
</body>
브라우저 이미지 최적화하기
- 페이지의 대부분의 용량은 HTML/CSS/JS와 같은 코드 데이터가 아닌 이미지 파일과 같은 미디어 파일이 차지
=> 이미지의 용량을 줄이거나 요청의 수를 줄이는 것을 우선적으로 고려할 시, 사용자 경험을 빠르게 개선
1. 이미지 스프라이트
- 이미지 스프라이트 기법은 여러 개의 이미지를 모아 하나의 스프라이트 이미지로 만들고 CSS의 background-position 속성을 사용해 이미지의 일정 부분만 클래스 등으로 구분하여 사용하는 방법
- 하나의 이미지를 배경 이미지로 사용하되, 표시하고 싶은 부분에 맞춰
width
, height
, background-position
속성을 주어 아이콘을 만든다.
- 해당 기법을 이용하면 한번의 이미지 요청으로 대부분의 개별 이미지를 사용할 수 있기 때문에 네트워크 로딩 시간을 줄일 수 있다.
2. 아이콘 폰트 사용하기
- 대표적인 아이콘 글꼴 서비스로는 Font Awesome
- Font Awesome 사용법
- CDN으로 사용하기
- Font Awesome에 가입하면 키트를 발급해주는데, 이 키트를 HTML 파일에서 <head>
요소에 넣어주기만 하면 CDN으로 Font Awesome을 사용할 준비가 완료
- Font Awesome 사이트에서 사용하고 싶은 아이콘을 찾아서 사용할 환경(HTML, React, Vue)에 맞는 코드를 복사하고 붙여넣기만 하면 사용
- Font Awesome 모듈 설치하기
- Font Awesome을 다른 라이브러리처럼 설치해서 사용하는 방법
- 설치 후에는 Font Awesome 사이트에서 사용하고 싶은 아이콘의 정보를 확인한 후에, 알맞게 불러와서 사용하면 된다. 이때 아이콘 이름은 camelCase로 작성한다.
- 불러온 아이콘은 클래스명을 직접 붙이거나 Font Awesome이 정해준 방법을 사용하여 스타일링해줄 수 있다.
// 핵심 패키지 설치
npm i --save @fortawesome/fontawesome-svg-core
// 아이콘 패키지 설치 (해당 코드는 무료 아이콘들입니다. 유료 아이콘을 사용할 경우 추가로 설치가 필요합니다.)
npm i --save @fortawesome/free-solid-svg-icons
npm i --save @fortawesome/free-regular-svg-icons
npm i --save @fortawesome/free-brands-svg-icons
// Font Awesome React 구성 요소 설치
npm i --save @fortawesome/react-fontawesome@latest
WebP 또는 AVIF 이미지 포맷 사용하기
- WebP는 PNG와 비교해 26% 용량이 감소되며 JPEG와 비교했을 땐 25-35% 더 감소
- AVIF는 JPEG와 비교했을 때 무려 용량의 50%가 감소되며 WebP와 비교했을 땐 20% 감소
- 단, 모든 브라우저에서 호환되지 않는다는 단점이 있다.
=> HTML의 <picture>
태그를 이용하면 각 브라우저의 호환에 맞도록 분기를 대체
=><picture>
: img 요소의 다중 이미지 리소스(multiple image resources)를 위한 컨테이너를 정의할 때 사용
<picture>
<source srcset="logo.webp" type="image/webp">
<img src="logo.png" alt="logo">
</picture>
- 다음과 같이 HTML 태그를 작성할 시, 만약 접속한 브라우저에서
<source>
태그 내의 srcset에 정의한 WebP 포맷을 지원하지 않는다면 해당 <source>
태그는 무시
CDN 사용하기
- CDN은 콘텐츠를 좀 더 빠르고 효율적으로 제공하기 위해 설계
- 유저와 서버의 거리가 멀다면 지연(latency) 또한 늘어난다.
=> CDN은 이를 해결하고자 세계 곳곳에 분포한 분산된 서버에 콘텐츠를 저장
2-2. 캐시 관리
캐시 사용하기
- 캐시(Cache): 다운로드 받은 데이터나 값을 미리 복사해 놓는 임시 장소, 데이터에 접근하는 시간이 오래 걸리는 경우나 값을 다시 계산하는 시간을 절약하고 싶은 경우에 사용
- 캐시사용을 안한다면, 윗 그림같이 똑같은 데이터를 100번, 1000번의 요청을 보내는 동안 똑같은 파일을 받아온다.
=> 네트워크 리소스를 낭비
- 서버에서 응답을 보내줄 때 이미지 파일과 함께 헤더에
Cache-Control
을 작성, 값은 60으로, 해당 이미지 파일이 60초동안 유효하다는 것을 의미
- 두 번째 요청부터는 캐시를 우선 조회, 캐시에 데이터가 존재하면서 아직 60초가 지나지 않아 유효하다면 캐시에서 해당하는 데이터를 가져와서 사용
캐시 검증 헤더와 조건부 요청
- 캐시 유효 시간은 지났지만, 서버에서 다시 받아와야하는 파일이 캐시에 저장되어 있는 파일과 완전히 동일한 경우,이때도 똑같은 파일을 다시 받아와야하는 경우가 발생
=> 캐시 검증 헤더와 조건부 요청 헤더
- 캐시 검증 헤더
- 캐시에 저장된 데이터와 서버의 데이터가 동일한지 확인하기 위한 정보를 담은 응답 헤더
Last-Modified
: 데이터가 마지막으로 수정된 시점을 의미하는 응답 헤더로, 조건부 요청 헤더인 If-Modified-Since
와 묶어서 사용
Etag
: 데이터의 버전을 의미하는 응답 헤더로, 조건부 요청 헤더인 If-None-Match
와 묶어서 사용
- 조건부 요청 헤더
- 캐시의 데이터와 서버의 데이터가 동일하다면 재사용하게 해달라는 의미의 요청 헤더
If-Modified-Since
: 캐시된 리소스의 Last-Modified
값 이후에 서버 리소스가 수정되었는지 확인하고, 수정되지 않았다면 캐시된 리소스를 사용
If-None-Match
: 캐시된 리소스의 ETag
값과 현재 서버 리소스의 ETag
값이 같은지 확인하고, 같으면 캐시된 리소스를 사용
- 캐시 검증 헤더와 조건부 요청 헤더 사용 방법
Last-Modified
와 If-Modified-Since
- 첫 번째 요청을 보내고 응답을 받으면서 캐시 유효 시간이 60초인 이미지 파일을 같이 받아온다. 이 때, 서버의 파일이 마지막으로 수정된 시간을 의미하는
Last-Modified
헤더에 담긴 내용도 캐시에 함께 저장한다.
- 캐시 유효 시간인 60초를 초과한 후에 두 번째 요청을 보낸다면, 비록 유효 시간이 지났어도 해당 데이터를 재사용해도 되는지 확인하기 위해서 “이 날짜 이후로 데이터 수정이 있었니? 없었다면 캐시에 저장해놓은 데이터를 재사용해도 괜찮을까?”라는 뜻의 요청 헤더
If-Modified-Since
를 작성하고 캐시에 함께 저장해놓았던 Last-Modified
값을 담아 요청을 보낸다.
=> 서버 데이터의 최종 수정일과 캐시에 저장된 데이터의 수정일을 비교, 두 데이터가 동일한 데이터라면 최종 수정일이 같아야 한다.
- 서버와 캐시의 데이터가 동일한 데이터임이 검증되었다면 서버는 “데이터가 수정되지 않았음”을 의미하는
304 Not Modified
라는 응답을 보내주고, 캐시 데이터의 유효 시간이 갱신되면서 해당 데이터를 재사용할수 있게 된다.
Etag
와 If-None-Match
- 첫 번째 요청을 보내고 응답을 받으면서 캐시 유효 시간이 60초인 이미지 파일을 같이 받아온다. 이 때, 서버의 파일 버전을 의미하는
Etag
헤더에 담긴 내용도 캐시에 함께 저장한다.
- 캐시 유효 시간인 60초를 초과한 후에 두 번째 요청을 보낸다면, 비록 유효 시간이 지났어도 해당 데이터를 재사용해도 되는지 확인하기 위해서 “내가 캐시에 저장해놓은 데이터 버전이랑 서버 데이터 버전이랑 일치하니? 일치한다면 캐시에 저장해놓은 데이터를 재사용해도 괜찮을까?”라는 뜻의 요청 헤더
If-None-Match
를 작성하고 캐시에 함께 저장해놓았던 Etag
값을 담아 요청을 보낸다. 이 값을 이용해 서버 데이터의 Etag
와 캐시에 저장된 데이터의 Etag
를 비교한다. 두 데이터가 동일한 데이터라면 두 Etag
값이 같아야 한다.
- 서버와 캐시의 데이터가 동일한 데이터임이 검증되었다면 서버는 “데이터가 수정되지 않았음”을 의미하는
304 Not Modified
라는 응답을 보내주고, 캐시 데이터의 유효 시간이 갱신되면서 해당 데이터를 재사용할 수 있게 된다.
- 두 쌍중의 헤더 중 한 쌍만 사용할 수도 있지만, 보통 두 종류를 동시에 사용, 둘 중 하나만 사용했다가 매칭되는 응답 헤더가 없는 경우에는 재사용할 수 있는 경우에도 리소스를 다시 받아와야 하는 경우가 생길 수 있기 때문이다.
2-3. Tree Shaking
트리쉐이킹(Tree Shaking)
- 말 그대로 나무를 흔들어 잔가지를 털어내듯 불필요한 코드를 제거하는 것을 의미
1. JavaScript 파일의 크기
- JavaScript 파일 크기의 증가, 요청 횟수의 증가는 그만큼 파일이 오고 가는 동안 화면 표시가 늦어진다는 것을 뜻한다.
=> 트리쉐이킹을 통해 파일 크기를 가능한 줄이는 것이 최적화에 도움이 된다.
2. JavaScript 파일의 실행 시간
- JavaScript 파일이 실행되기 위해서는 여러 과정을 거친다.
a. 다운로드부터 필요한 경우에는 우선 요청을 보내어 파일을 다운받아 온 다음 압축을 해제
b. 그다음에는 JavaScript 코드를 파싱하여 DOM 트리를 생성
c. 파싱이 끝나면 컴파일하여 컴퓨터가 이해할 수 있는 언어로 바꿔줘야 한다.
d. 코드를 실행
=> 상대적으로 많은 시간을 소모
- JavaScript 파일의 실행은 CPU에 크게 영향을 받는데, 그렇다 보니 사양이 천차만별인 모바일 환경에서 그 영향이 더욱 두드러진다.
JavaScript 트리쉐이킹
- 웹팩 4버전 이상을 사용하는 경우에는 ES6 모듈(
import
, export
를 사용하는 모듈)을 대상으로는 기본적인 트리쉐이킹을 제공
- Create React App을 통해 만든 React 애플리케이션도 웹팩을 사용하고 있기 때문에 트리쉐이킹이 가능
1. 필요한 모듈만 import 하기
- 이렇게 모든 코드를 불러오면, 이 중에서 실제로 사용하는 코드는 얼마 되지 않더라도 번들링할때 이 모든 코드를 같이 빌드하게 된다.
- 이를 방지하기 위해서
import
해올 때 아래와 같이 실제로 사용할 코드만 불러온다.
import { useState, useEffect } from 'react'
2. Babelrc 파일 설정하기
- Babel은 자바스크립트 문법이 구형 브라우저에서도 호환이 가능하도록 ES5 문법으로 변환하는 라이브러리
- ES5문법은
import
를 지원하지 않기 때문에, commonJS 문법의 require
로 변경시키는데, require
는 export
되는 모든 모듈을 불러오기 때문에 트리쉐이킹에 큰 걸림돌이다.
- 이를 방지하기 위해서 Barbelrc 파일에 다음과 같은 코드를 작성해주면 ES5로 변환하는 것을 막을 수 있다.
{
“presets”: [
[
“@babel/preset-env”,
{
"modules": false
}
]
]
}
3. sideEffects 설정하기
-
웹팩은 사이드 이펙트를 일으킬 수 있는 코드의 경우, 사용하지 않는 코드라도 트리쉐이킹 대상에서 제외시킨다.
-
아래 코드에서 addCrew 함수는 함수 외부에 있는 배열인 crews를 변경시키는 함수다.
해당 함수는 외부에 영향을 주지도 받지도 않는 함수, 순수 함수가 아니기 때문에 트리쉐이킹을 통해 제외하는 경우 문제가 생길 수도 있다고 판단해 웹팩은 이 코드를 제외시키지 않는다.
const crews = ['kimcoding', 'parkhacker']
const addCrew = function (name) {
crews.push(name)
}
=> 이럴 때 package.json 파일에서 sideEffects
를 설정하여 사이드 이펙트가 생기지 않을 것이므로 코드를 제외시켜도 됨을 웹팩에게 알려줄 수 있다.
{
"name": "tree-shaking",
"version": "1.0.0",
"sideEffects": false
}
{
"name": "tree-shaking",
"version": "1.0.0",
"sideEffects": ["./src/components/NoSideEffect.js"]
}
4. ES6 문법을 사용하는 모듈 사용하기
2-4. Lighthouse
- Lighthouse
- 사이트를 검사하여 성능 측정을 할 수 있는 도구
- 다양한 지표를 이용하여 웹페이지의 성능 검사를 해줄 뿐만 아니라 그에 대한 개선책도 제공
- 구글에서 개발한 오픈소스로서 웹 페이지의 품질을 개선할 수 있는 자동화 툴
- Lighthouse는 성능, 접근성, PWA, SEO 등을 검사하며 이를 이용해 사용자는 어떤 웹페이지든 품질 검사를 할 수있다.
- Chrome DevTools부터 CLI, 노드 모듈 등 다양한 경로를 통해 사용할 수 있다.
- 검사할 페이지의 url을 Lighthouse에 전달하면 Lighthouse는 해당 페이지에 대한 여러 검사를 실행
=> 검사 결과에 따른 리포트를 생성하고 개발자는 해당 리포트를 통해 점수가 낮은 지표에 대해 개선을 꾀할 수 있다.
또한 각각의 지표가 왜 중요한지, 어떻게 개선할 수 있는 지에 대한 레퍼런스도 리포트에서 참고할 수 있다.
Lighthouse 시작하기
Chrome 개발자 도구에서 실행하기
a. 크롬에서 검사하고 싶은 페이지의 url을 입력
b. 개발자 도구를 연다.
c. lighthouse 탭을 클릭
d. Generate report를 클릭, Categories에서 특정한 지표만 선택하여 검사할 수도 있다.
Node CLI에서 실행하기
npm install -g lighthouse
lighthouse <url>
lighthouse --help
Lighthouse 분석 결과 항목
- 웹 성능을 측정
- 화면에 콘텐츠가 표시되는데 시간이 얼마나 걸리는지, 표시된 후 사용자와 상호작용하기 까진 얼마나 걸리는지, 화면에 불안정한 요소는 없는지 등을 확인
2. Accessibility
- 웹 페이지가 웹 접근성을 잘 갖추고 있는지 확인
- 대체 텍스트를 잘 작성했는지, 배경색과 콘텐츠 색상의 대비가 충분한지, 적절한 WAI-ARIA 속성을 사용했는지 등을 확인
3. Best Practices
- 웹 페이지가 웹 표준 모범 사례를 잘 따르고 있는지 확인
- HTTPS 프로토콜을 사용하는지, 사용자가 확인할 확률은 높지 않지만 콘솔 창에 오류가 표시 되지는 않는지 등을 확인
4. SEO
- 웹 페이지가 검색 엔진 최적화가 잘 되어있는지 확인
- 애플리케이션의 robots.txt가 유효한지,
<meta>
요소는 잘 작성되어 있는지, 텍스트 크기가 읽기에 무리가 없는지 등을 확인
5. PWA (Progressive Web App)
- 해당 웹 사이트가 모바일 애플리케이션으로서도 잘 작동하는지 확인
- 앱 아이콘을 제공하는지, 스플래시 화면이 있는지, 화면 크기에 맞게 콘텐츠를 적절하게 배치했는지 등을 점수가 아닌 체크리스트로 확인
1. First Contentful Paint(FCP)
- 성능(Performance) 지표를 추적하는 메트릭
- 사용자가 페이지에 접속했을 때 브라우저가 DOM 컨텐츠의 첫 번째 부분을 렌더링하는 데 걸리는 시간을 측정
- 우수한 사용자 경험을 제공하려면 FCP가 1.8초 이하여야 한다.
- 페이지의 이미지와
<canvas>
요소, SVG 등 모두 DOM 콘텐츠로 구분되며 <iframe>
요소의 경우 이에 포함되지 않는다.
- 이때 FCP처럼 일부 콘텐츠의 첫 번째 렌더링 시점을 측정하는 것이 아닌 주요 콘텐츠 로딩이 완료된 시점을 측정하는 것을 목표로 한다면 Large Contentful Paint, 줄여서 LCP 지표로 확인할 수 있다.
2. Largest Contentful Paint(LCP)
- 뷰포트를 차지하는 가장 큰 콘텐츠(이미지 또는 텍스트 블록)의 렌더 시간을 측정
- 주요 콘텐츠가 유저에게 보이는 시간까지를 가늠할 수 있다.
3. Speed Index
- 성능(Performance) 지표를 추적하는 메트릭
- 페이지를 로드하는 동안 얼마나 빨리 컨텐츠가 시각적으로 표시되는 지를 측정
- Lighthouse는 먼저 브라우저의 페이지 로딩과정을 각 프레임마다 캡쳐하고, 프레임 간 화면에 보이는 요소들을 계산한다. 그 후 Speedline Node.js module을 이용하여 Speed Index 점수를 그래프의 형태로 나타낸다.
4. Time to interactive(TTI)
- 페이지가 로드되는 시점부터 사용자와의 상호작용이 가능한 시점까지의 시간을 측정
- 기준
- 페이지에 FCP로 측정된 컨텐츠가 표시되어야 한다.
- 이벤트 핸들러가 가장 잘 보이는 페이지의 엘리먼트에 등록된다.
- 페이지가 0.05초안에 사용자의 상호작용에 응답한다.
- TTI 점수는 아카이브된 HTTP 데이터를 기반으로 백분위 단위로 점수를 측정
5. Total Blocking Time
- 대부분의 사용자는 0.05초가 넘는 작업에는 응답이 올때까지 계속 키보드를 두드리거나 마우스를 클릭하기 때문에 페이지가 느리다고 인식=> 이를 개선하기 위한 지표가 TBT
- 페이지가 유저와 상호작용하기까지의 막혀있는 시간을 측정
- Lighthouse에서는 FCP와 TTI 사이에 긴 시간이 걸리는 작업들을 모두 기록하여 TBT를 측정
6. Cumulative Layout Shift(CLS)
- 사용자에게 컨텐츠가 화면에서 얼마나 많이 움직이는지(불안정한 지)를 수치화한 지표
- 이 지표를 통해 화면에서 이리저리 움직이는 요소(불안정한 요소)가 있는 지를 측정
개선 방향 잡기
- Lighthouse는 성능을 측정할 뿐 아니라 무엇이 시간을 많이 소모하는지, 어떻게 개선하여 최적화를 할 수 있을지 해결책도 제시
- Opportunities 항목을 확인하면 각 메트릭별 문제를 확인할 수 있다.