Lighthouse 란?
Lighthouse는 웹 앱의 성능, 품질 및 정확성을 개선하기 위한 자동화된 오픈 소스 도구입니다. 페이지를 감사할 때 Lighthouse는 페이지에 대해 대규모 테스트를 실행한 다음 페이지가 얼마나 잘 수행되었는지에 대한 보고서를 생성합니다. 여기에서 실패한 테스트를 앱을 개선하기 위해 무엇을 할 수 있는지에 대한 지표로 사용할 수 있습니다.
* Lighthouse 사용에 대한 빠른 시작 가이드: https://developers.google.com/web/tools/lighthouse/
Chrome에서 실행하기
- 크롬에서 검사하고 싶은 페이지의 url을 입력합니다.
- 개발자 도구를 엽니다.
- lighthouse 탭을 클릭합니다.
※ Node CLI에서 실행하기
1. Lighthouse를 설치합니다. 이때 -g옵션을 사용하여 전역 모듈로 설치하는 것이 좋습니다.
npm install -g lighthouse
2. 검사 실행
3. 모든 옵션 보기lighthouse <url>
lighthouse --help

1. 페이지 로드 분석을 눌러줍니다.(카테고리에서 원하는 사항만 선택하고 로드 분석을 진행할 수도 있습니다.)
2. 30-60초 후 분석 결과가 개발자도구탭에 열립니다.
Lighthouse 분석 결과 항목

Performance(성능)
Performance 항목에서는 웹 성능을 측정합니다. 화면에 콘텐츠가 표시되는데 시간이 얼마나 걸리는지, 표시된 후 사용자와 상호작용하기 까진 얼마나 걸리는지, 화면에 불안정한 요소는 없는지 등을 확인합니다.
Accessibility(접근성)
Accessibility 항목에서는 웹 페이지가 웹 접근성을 잘 갖추고 있는지 확인합니다. 대체 텍스트를 잘 작성했는지, 배경색과 콘텐츠 색상의 대비가 충분한지, 적절한 WAI-ARIA 속성을 사용했는지 등을 확인합니다.
Best Practices(권장사항)
Best Practices 항목에서는 웹 페이지가 웹 표준 모범 사례를 잘 따르고 있는지 확인합니다. HTTPS 프로토콜을 사용하는지, 사용자가 확인할 확률은 높지 않지만 콘솔 창에 오류가 표시 되지는 않는지 등을 확인합니다.
SEO(검색엔진 최적화)
SEO 항목에서는 웹 페이지가 검색 엔진 최적화가 잘 되어있는지 확인합니다. 애플리케이션의 robots.txt가 유효한지, <meta> 요소는 잘 작성되어 있는지, 텍스트 크기가 읽기에 무리가 없는지 등을 확인합니다.
PWA (Progressive Web App)
PWA 항목에서는 해당 웹 사이트가 모바일 애플리케이션으로서도 잘 작동하는지 확인합니다. 앱 아이콘을 제공하는지, 스플래시 화면이 있는지, 화면 크기에 맞게 콘텐츠를 적절하게 배치했는지 등을 점수가 아닌 체크리스트로 확인합니다.
Performance(성능) 의 Opportunities(측정항목)

위 사진에서 성능은 17이 나왔다. 이를 측정한 항목들을 살펴보면 6가지 항목들이 나온다.

위의 항목들을 자세히 알아보자.
First Contentful Paint(FCP)
FCP는 성능(Performance) 지표를 추적하는 메트릭입니다.
FCP는 사용자가 페이지에 접속했을 때 브라우저가 DOM 컨텐츠의 *첫 번째 부분을 렌더링하는 데 걸리는 시간을 측정합니다. 즉 사용자가 감지하는 페이지의 로딩속도를 측정할 수 있습니다. 우수한 사용자 경험을 제공하려면 FCP가 1.8초 이하여야 합니다.
페이지의 이미지와 <canvas> 요소, SVG 등 모두 DOM 콘텐츠로 구분되며 <iframe> 요소의 경우 이에 포함되지 않습니다.
※ 이 메트릭에서 "콘텐츠"란 텍스트, 이미지(배경 이미지 포함), <svg>요소 또는 흰색이 아닌 <canvas> 요소를 뜻합니다.
* 첫 번째 렌더링 시점을 측정하는 것이 아닌 주요 콘텐츠 로딩이 완료된 시점을 측정하는 것을 목표로 한다면 LCP 지표로 확인할 수 있습니다.
JS에서 측정하는 방법
//1번째 방법 new PerformanceObserver((entryList) => { for (const entry of entryList.getEntriesByName('first-contentful-paint')) { console.log('FCP candidate:', entry.startTime, entry); } }).observe({type: 'paint', buffered: true}); //2번째 방법 import {getFCP} from 'web-vitals'; // FCP를 이용 가능하게 되면 바로 측정 및 기록합니다. getFCP(console.log);
- 개선 방법으로는 무엇이 있을까?
렌더링 차단 리소스 제거 / CSS 축소 / 사용하지 않는 CSS 제거 / 필요한 원본에 사전 연결 / 서버 응답 시간 단축(TTFB)
여러 페이지 리디렉션 방지 / 핵심 요청 사전 로드 / 막대한 네트워크 페이로드 방지 / 효율적인 캐시 정책으로 정적 자산 제공
과도한 DOM 크기 방지 / 크리티컬 요청 깊이 최소화 / 웹폰트 로드 중에 텍스트가 계속 표시되는지 확인
요청 수를 낮게 유지하고 전송 크기를 작게 유지
Largest Contentful Paint (LCP)
페이지가 처음으로 로드를 시작한 시점을 기준으로 뷰포트 내에 있는 가장 큰 이미지 또는 텍스트 블록의 렌더링 시간을 보고합니다. LCP가 빠르면 사용자가 해당페이지를 사용할 수 있다고 인지하는데 도움이 됩니다. 우수한 사용자 경험을 제공하려면 사이트의 최대 콘텐츠풀 페인트가 2.5초 이하여야 합니다.
LCP time(in seconds) | Color-coding |
0-2.5 | Green (fast) |
2.5-4 | Orange (moderate) |
Over 4 | Red (slow) |
고려하는 요소로는 아래와 같은 요소들이 있습니다.처음부터 단순하게 작업하기 위해 제한적인 요소들로 구성되어있습니다.
<img> 요소
<svg> 요소 내부의 <image>
<video> 요소(포스터 이미지 사용)
url() 함수를 통해 로드된 배경 이미지가 있는 요소(CSS 그라데이션과는 대조적임)
텍스트 노드 또는 기타 인라인 수준 텍스트 하위 요소를 포함하는 블록 수준 요소
- 요소 레이아웃 및 크기 변경 처리는 어떻게 될까요?
처음에 화면 밖에서 렌더링된 후 다음 화면으로 전환되는 이미지는 보고되지 않을 수 있습니다. 또한, 처음에 뷰포트에서 렌더링된 요소가 아래로 밀려 뷰에서 벗어나도 초기 뷰포트 내에서의 크기를 보고합니다.
JS에서의 측정방법
//1번째 방법 new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { console.log('LCP candidate:', entry.startTime, entry); } }).observe({type: 'largest-contentful-paint', buffered: true}); //2번째방법 import {getLCP} from 'web-vitals'; // LCP를 이용 가능하게 되면 바로 측정 및 기록합니다. getFCP(console.log);
- 개선 방법으로는 무엇이 있을까?
느린 서버 응답 시간 / 렌더링 차단 JS 및 CSS / 리소스 로드 시간 / 클라이언트 측 랜더링
위 4가지 요인으로 영향을 받으므로
PRPL 패턴으로 즉각적 로딩 적용 / 중요 렌더링 경로 최적화 / CSS 최적화 / 이미지 최적화 / 웹 글꼴 최적화 /
JavaScript 최적화(클라이언트 렌더링 사이트용)
Speed Index
페이지 로드 중에 콘텐츠가 시각적으로 표시되는 속도를 측정합니다. Lighthouse는 먼저 브라우저에서 페이지 로드의 비디오를 캡처하고 프레임 간의 시각적 진행을 계산합니다. 그런 다음 Lighthouse는 Speedline Node.js 모듈 을 사용하여 속도 지수 점수를 생성합니다.
속도 지수(초) | 색상 코딩 |
0–3.4 | 녹색(빠름) |
3.4–5.8 | 오렌지(보통) |
5.8 이상 | 빨강(느림) |
- 개선 방법으로는 무엇이 있을까?
메인 스레드 작업 최소화 / 자바스크립트 실행 시간 단축 / 웹폰트 로드 중에 텍스트가 계속 표시되는지 확인
Time to interactive
TTI 메트릭은 페이지가 로드되기 시작한 시점부터 주요 하위 리소스가 로드되고 사용자 입력에 신속하게 안정적으로 응답할 수 있는 시점까지의 시간을 측정합니다.
TTI 계산 방법
1. First Contentful Paint(최초 콘텐츠풀 페인트, FCP)에서 시작합니다.
2. 이 시점 이후부터 최소 5초 정도의 조용한 기간을 검색합니다. 여기서 조용한 기간이란 긴 작업이 없고 전송 중 네트워크 GET 요청이 2개 미만인 기간을 뜻합니다.
3. 긴 작업이 발견되지 않으면 조용한 기간 이전의 마지막 긴 작업을 역방향으로 검색하며 FCP에서 종료합니다.
4. TTI는 조용한 기간이 발생하기 이전 마지막 긴 작업의 종료 시간이거나, 긴 작업이 발견되지 않았을 경우에는 FCP와 동일한 값입니다.
TTI 측정 기준
페이지에 FCP로 측정된 컨텐츠가 표시되어야 합니다.
이벤트 핸들러가 가장 잘 보이는 페이지의 엘리먼트에 등록됩니다.
페이지가 0.05초안에 사용자의 상호작용에 응답합니다.
- 개선 방법으로는 무엇이 있을까?
JavaScript 축소 / 필요한 원본에 사전 연결 / 핵심 요청 사전 로드 / 타사 코드의 영향 줄이기 / 크리티컬 요청 깊이 최소화 JavaScript 실행 시간 단축 / 메인 스레드 작업 최소화 / 요청 수를 낮게 유지하고 전송 크기를 작게 유지
Total Blocking Time
총 차단 시간(TBT) 메트릭은 메인 스레드가 입력 응답을 막을 만큼 오래 차단되었을 때 FCP와 TTI 사이 총 시간을 측정합니다.
대부분의 사용자는 0.05초가 넘는 작업에는 응답이 올때까지 계속 키보드를 두드리거나 마우스를 클릭하기 때문에 페이지가 느리다고 인식합니다. 이를 개선하기 위한 지표가 TBT입니다.


위 두 사진을 비교해서 보면 50ms 를 넘는 블록은 세개가 있습니다. 이 세개의 블록은 아래에서 보면 팥죽색으로 표시된부분이 초과된 부분입니다. 따라서 메인 스레드에서 작업을 실행하는 데 소요된 총 시간은 560ms이지만 차단 시간으로 간주되는 것은 345ms뿐입니다.
- 개선 방법으로는 무엇이 있을까?
타사 코드의 영향 줄이기 / JavaScript 실행 시간 단축 / 메인 스레드 작업 최소화 /
요청 수를 낮게 유지하고 전송 크기를 작게 유지
Cumulative Layout Shift
Cumulative Layout Shift, 줄여서 CLS는 사용자에게 컨텐츠가 화면에서 얼마나 많이 움직이는지(불안정한 지)를 수치화한 지표입니다. 이 지표를 통해 화면에서 이리저리 움직이는 요소(불안정한 요소)가 있는 지를 측정할 수 있습니다. 좋은 CLS점수는 0.1이하여야 합니다.
속도 지수(초) | 색상 코딩 |
0–1 | 녹색(빠름) |
0.1–0.25 | 오렌지(보통) |
0.25 이상 | 빨강(느림) |
JS에서 측정방법
import {getCLS} from 'web-vitals'; // Measure and log CLS in all situations // where it needs to be reported. getCLS(console.log);
- 개선 방법으로는 무엇이 있을까?
이미지 및 비디오 요소에 항상 크기 속성을 포함하거나 CSS 가로 세로 비율 상자와 같은 방식으로 필요한 공간을 미리 확보하세요. 이러한 접근 방식을 사용하면 이미지가 로드되는 동안 브라우저가 문서에 올바른 양의 공간을 할당할 수 있습니다. unsized-media 기능 정책을 사용하여 기능 정책을 지원하는 브라우저에서 이 동작을 강제할 수도 있습니다.
사용자 상호 작용에 대한 응답을 제외하고는 기존 콘텐츠 위에 콘텐츠를 삽입하지 마세요. 이렇게 하면 레이아웃 이동이 발생하기 때문입니다.
레이아웃 변경을 트리거하는 속성의 애니메이션보다 전환 애니메이션을 사용하세요. 상태에서 상태로 컨텍스트와 연속성을 제공하는 방식으로 애니메이션 전환을 수행하는 것이 좋습니다.
개선방향잡기


스크롤을 내려보면 진단항목들이 나오는데, 아래와 같이 나와있는 것을 볼 수 있습니다.
"애플리케이션 성능과 관련된 추가 정보입니다. 이러한 숫자는 성능 점수에 직접적인 영향을 미치지 않습니다."
'개발공부 > TIL' 카테고리의 다른 글
OS | Process | Thread (0) | 2023.05.12 |
---|---|
크롬 브라우저 아키텍쳐 (0) | 2023.05.12 |
Bundling과 Webpack (1) | 2022.09.26 |
웹 표준 & 접근성 (0) | 2022.09.07 |
meta 요소 (0) | 2022.09.05 |