오늘은 웹 페이지의 로딩 성능을 평가하는 중요한 지표 중 하나인 LCP를 `PerformanceObserver`를 사용해 간단한 LCP 측정기를 만들어 보겠습니다.
PerformanceObserver란 📖
`PerformanceObserver`는 웹 페이지의 성능 데이터를 감지하고 분석하는 API입니다.
브라우저가 기록하는 다양한 성능 데이터를 실시간으로 수집할 수 있습니다.
구문
new PerformanceObserver(callback)
관찰된 성능 이벤트가 기록될 때 호출되는 콜백입니다.
entryTypes
PerformanceObserver를 사용할 때, `observe()` 메서드를 통해 감지할 항목을 설정할 수 있습니다.
Entry Type | 설명 |
paint | first-paint, first-contentful-paint를 감지합니다.(FCP) |
largest-contentful-paint | 가장 큰 콘텐츠 요소가 화면에 렌더링된 시간을 감지합니다.(LCP) |
layout-shift | 페이지의 CLS를 측정합니다. |
resource | 페이지에서 로드된 리소스(JS, CSS, 이미지 등) 정보를 제공합니다. |
navigation | 페이지의 FCP, LCP, CLS 등의 데이터를 포함하는 종합적인 성능을 측정합니다. |
✨ 이번 글에서는 `largest-contentful-paint`를 활용해 LCP 측정기를 만드는 방법에 대해 알아보려고 합니다!
LCP란 📖
LCP란 가장 큰 콘텐츠 요소가 화면에 렌더링 된 시간을 측정하는 성능 지표입니다. LCP가 늦을수록 사용자는 웹사이트가 느리다고 느낄 수 있습니다.
LCP의 기준 (Google Web Vials)
사용자에게 우수한 환경을 제공하기 위해 최대 콘텐츠 렌더링 시간이 2.5초 이하가 좋다고 합니다.
LCP 측정기 예제 📖
아래 코드는 LCP를 측정하는 코드입니다.
HTML 코드 (lcp.html)
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>LCP 측정기</title>
</head>
<body>
<h1>간단한 LCP 측정기</h1>
<img src="https://placehold.co/300x150" alt="small" />
<img src="https://placehold.co/450x300" alt="medium" />
<img src="https://placehold.co/600x450" alt="large" />
<script src="./performanceObserver.js"></script>
</body>
</html>
JS 코드 (performanceObserver.js)
window.onload = () => {
// LCP 측정
const observer = new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
if (entry.entryType === "largest-contentful-paint") {
console.log("LCP time:", entry.startTime, "ms");
console.log("LCP element:", entry.element);
observer.disconnect(); // 측정 후 옵저버 해제
}
}
});
observer.observe({
entryTypes: ["largest-contentful-paint"],
});
};
getEntires()
performanceObserver에서 감지한 성능 데이터 목록을 반환하는 메서드이고, LCP를 측정하는 경우 요소(이미지 or 텍스트 블록)와 렌더링 시간을 확인할 수 있습니다.
for (const entry of entryList.getEntries()) { ... }
observe()
performanceObserver가 특정 성능 이벤트를 감지하도록 설정하는 메서드입니다.
observer.observe({
entryTypes: ["largest-contentful-paint"],
});
해당 코드에서는 LCP를 측정하기 위해 entryTypes를 `largest-contentful-paint`로 설정해 가장 큰 콘텐츠 요소의 렌더링 시간을 측정했습니다.
이후, entryType이 largest-contentful-paint이라면 `startTime`과 `element`를 통해 시간과 요소를 확인할 수 있습니다.
if (entry.entryType === "largest-contentful-paint") {
console.log("LCP time:", entry.startTime, "ms");
console.log("LCP element:", entry.element);
observer.disconnect(); // 측정 후 옵저버 해제
}
실행 화면
어려웠던 점 ❓
LCP 측정 타이밍
LCP를 측정기를 만든다고 했을 때 가장 큰 콘텐츠 요소를 어떻게 측정해야 될지부터 막혀서 측정 방법을 고민하는 부분에서 어려움이 있었습니다. (구글링을 통해 performance 측정 방식에 대해 알게 되었음,,)
그리고 `PerformanceObserver`의 동작 방식과 LCP 항목만을 따로 분리해 분석하는 방법을 mdn 문서를 통해 파악하는 데 시간이 걸리는 문제가 있었습니다.
깨달은 점 ❕
실용적 경험
직접 LCP를 구현하면서 `PerformanceObserver`를 사용해 성능을 측정한 경험은 최적화를 단순히 이론적이지 않고 실제 성능에 어떻게 영향을 미치는지를 이해하는 데 큰 도움이 되었습니다.
최적화의 중요성
웹 성능 최적화는 사용자 경험을 개선할 수 있는 중요한 요소이고, Lighthouse와 같은 성능 지표를 정확히 이해하고 사용한다면 사용자에게 더 빠르고 원활한 웹 경험을 제공할 수 있다는 걸 알게 되었습니다.
회고 🧐
Lighthouse와 같은 툴을 사용해 성능 측정 경험만 있었는데, 이번에 직접 구현해보면서 단순히 툴을 사용하는 것보다 그 원리를 이해하고 활용하는 것이 훨씬 더 효과적임을 깨달았습니다.
많이 부족하기 때문에 조언은 언제나 환영입니다 :)

출처 🏷️
https://developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver
'공부 > javascript' 카테고리의 다른 글
폴리필이란? (1) | 2024.12.12 |
---|---|
javascript 심화 7 (클로저) (0) | 2024.08.07 |
javascript 심화 6 (이벤트 루프) (0) | 2024.08.02 |
javascript 심화 5 (Promise, async, await) (0) | 2024.07.29 |
javascript 심화 4 (콜백함수) (0) | 2024.07.29 |
javascript 심화 3 (this, 화살표함수, call, apply, bind) (0) | 2024.07.26 |
javascript 심화 2 (호이스팅, var let const 차이점, TDZ) (5) | 2024.07.24 |
javascript 심화 1 (실행 컨텍스트) (0) | 2024.07.24 |