안녕하세요! 36기 YB 엄경호입니다. 😊
이전 글들에서 웹 성능의 중요성과 개별적인 최적화 기법들을 많이 보았습니다.
오늘은 사용자가 웹 페이지를 더 빠르게 느끼게 만드는 핵심적인 성능 최적화 기법 세 가지
Critical Rendering Path (CRP) 분석,
코드 스플리팅 (Code Splitting), 그리고
리소스 지연 로딩 (Lazy Loading) 에 대해 깊이 알아보겠습니다 !
빠른 로딩 속도는 사용자 경험을 극대화하고 이탈률을 줄이며, 검색 엔진 순위에도 긍정적인 영향을 미칩니다.
1. Critical Rendering Path (CRP) 최적화
✅ CRP란 무엇인가요?
Critical Rendering Path(핵심 렌더링 경로)는 브라우저가 HTML, CSS, JavaScript를 화면에 픽셀로 변환하는 일련의 단계를 의미합니다.
이 경로를 이해하고 최적화하는 것은 초기 페이지 로딩 속도를 개선하는 데 매우 중요합니다. (웹 브라우저의 작동 원리)
CRP 단계 요약:
- DOM 트리 생성: 브라우저가 HTML을 파싱하여 DOM(Document Object Model) 트리를 만듭니다.
- CSSOM 트리 생성: CSS를 파싱하여 CSSOM(CSS Object Model) 트리를 만듭니다.
- Render Tree 생성: DOM과 CSSOM을 결합하여 실제로 화면에 표시될 요소들로만 구성된 렌더 트리를 만듭니다 (
display: none등은 제외). - Layout (Reflow): 렌더 트리의 각 노드의 정확한 위치와 크기를 계산합니다.
- Paint: 계산된 정보를 바탕으로 각 노드를 화면의 실제 픽셀로 변환합니다.
- Composite: 여러 레이어를 순서대로 합성하여 최종 화면을 그립니다.
✅ 어떻게 최적화하나요?
CRP의 핵심은 렌더링 차단 리소스(Render-Blocking Resources)를 최소화하는 것입니다.
주로 <head> 태그 안의 CSS와 동기적인 JavaScript가 해당됩니다.
- CSS 최적화:
- 미디어 쿼리 활용: 특정 조건(화면 크기, 인쇄 등)에서만 필요한 CSS는 해당 미디어 쿼리 내에서 로드하여 초기 렌더링 차단을 줄입니다. (
<link rel="stylesheet" href="print.css" media="print">) - CSS 파일 크기 최소화: 불필요한 스타일 제거, 압축(Minification) 등을 통해 파일 크기를 줄입니다.
- Critical CSS 인라이닝: 페이지 상단(Above-the-fold) 렌더링에 필수적인 CSS만 HTML
<style>태그 안에 인라인으로 포함시키고, 나머지 CSS는 비동기적으로 로드합니다.
- 미디어 쿼리 활용: 특정 조건(화면 크기, 인쇄 등)에서만 필요한 CSS는 해당 미디어 쿼리 내에서 로드하여 초기 렌더링 차단을 줄입니다. (
- JavaScript 최적화:
async또는defer속성 사용:<script>태그에async나defer속성을 추가하면 HTML 파싱을 차단하지 않고 스크립트를 다운로드/실행할 수 있습니다.async: 다운로드 완료 즉시 실행 (but 순서 보장 X).defer: HTML 파싱 완료 후, DOMContentLoaded 이벤트 전에 순서대로 실행.
- 스크립트 위치: 가능하면
<body>태그 끝부분에 스크립트를 위치시켜 DOM 생성을 방해하지 않도록 합니다.
- 리소스 요청 수 줄이기: 여러 CSS나 JS 파일을 하나로 병합(Bundling)하여 HTTP 요청 수를 줄입니다. (but HTTP/2 이상에서는 효과가 줄어들 수 있음)
2. 코드 스플리팅 (Code Splitting)
✅ 코드 스플리팅이란?
웹 애플리케이션이 커지면 JavaScript 번들 파일 크기도 함께 증가합니다.
큰 번들 파일은 다운로드와 파싱/실행 시간을 늘려 초기 로딩 성능을 저하시킵니다.
코드 스플리팅은 이 거대한 번들 파일을 여러 개의 작은 청크(Chunk)로 나누고, 필요한 시점에 필요한 코드만 로드하는 기법입니다.
✅ 왜 필요한가요?
- 초기 로딩 속도 개선: 사용자가 처음 페이지에 접속했을 때 필요한 최소한의 코드만 로드하여 TTI(Time To Interactive)를 단축시킵니다.
- 리소스 효율성 증대: 당장 사용하지 않는 코드까지 로드하는 낭비를 줄입니다.
✅ 어떻게 구현하나요?
최신 자바스크립트와 모듈 번들러(Webpack, Vite, Rollup 등)를 사용하면 비교적 쉽게 구현할 수 있습니다.
- 동적
import()문법: 표준 JavaScript 문법으로, 프로미스(Promise)를 반환하며 필요한 시점에 모듈을 비동기적으로 로드합니다.
// button 클릭 시 large-module.js 로드
button.addEventListener('click', async () => {
try {
const module = await import('./large-module.js');
module.doSomething();
} catch (error) {
console.error('모듈 로딩 실패:', error);
}
});
- 모듈 번들러 활용:
- Webpack:
optimization.splitChunks설정을 통해 자동으로 코드 중복을 제거하고 청크를 분리할 수 있습니다.
동적import()도 지원합니다. - Vite: 기본적으로 동적
import()를 지원하며, Rollup 기반으로 효율적인 코드 스플리팅을 수행합니다. - React/Vue 등 프레임워크: React.lazy(), Vue의 비동기 컴포넌트 등 프레임워크 자체에서 코드 스플리팅을 위한 기능을 제공합니다.
- Webpack:
3. 리소스 지연 로딩 (Lazy Loading)
✅ 지연 로딩이란?
지연 로딩은 페이지 로딩 시점에 당장 필요하지 않은 리소스(특히 이미지, 비디오, iframe) 의 로딩을 실제로 화면에 보여지기 직전까지 지연시키는 기법입니다.
✅ 왜 유용한가요?
- 초기 페이지 로드 시간 단축: 화면 밖에 있는 이미지까지 처음부터 로드하지 않아 초기 로딩이 빨라집니다.
- 데이터 절약: 사용자가 스크롤하여 보지 않는 이미지/리소스는 로드되지 않아 데이터 사용량을 줄일 수 있습니다. (특히 모바일 환경에서 더욱 중요 !)
- 서버 부하 감소: 초기 요청 리소스 수가 줄어 서버 부담을 덜 수 있습니다.
✅ 어떻게 구현하나요?
- 이미지 및 iframe 네이티브 지연 로딩: 가장 간단한 방법은 HTML
<img>와<iframe>태그에loading="lazy"속성을 추가하면 브라우저가 알아서 지연 로딩을 처리해줍니다. (이는 대부분의 최신 브라우저에서 지원합니다 !) <img src="image.jpg" loading="lazy" alt="설명" width="200" height="200"> <iframe src="https://example.com" loading="lazy" title="예시"></iframe>- Intersection Observer API 활용:
loading="lazy"가 지원되지 않는 리소스나 더 복잡한 로직(예를 들면 특정 컴포넌트 지연 로딩)을 구현할 때 사용합니다.
요소가 뷰포트에 들어왔는지 감지하여 콜백 함수를 실행시키는 API입니다.
const lazyImages = document.querySelectorAll('img.lazy');
// data-src 속성에 실제 이미지 경로 저장
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src; // 실제 이미지 로드
img.classList.remove('lazy');
observer.unobserve(img); // 감지 중단
}
});
});
lazyImages.forEach(img => {
observer.observe(img);
});
🏁 마무리하며
오늘 살펴본 Critical Rendering Path 최적화, 코드 스플리팅, 지연 로딩은 웹 페이지의 로딩 속도와 사용자 경험을 크게 향상시킬 수 있는 강력한 기법들입니다.
개인적으로 프로젝트 초기부터 성능을 염두에 두고 개발하는 습관을 들이고, 테스팅 도구를 활용하여 꾸준히 성능을 측정하고 개선해나가는 것이 중요하다고 생각합니다.
읽어주셔서 감사합니다!
참고하면 좋은 자료 !
- Critical Rendering Path
- Code Splitting:
- Lazy Loading:
- 이와 관련된 소중한 SWEB 게시글 !
'1주차' 카테고리의 다른 글
| CSS와 CSS-in-JS (0) | 2025.04.11 |
|---|---|
| 웹뷰와 PWA (0) | 2025.04.11 |
| 클라이언트, 서버, API, HTTP, REST 등.. (0) | 2025.04.11 |
| 웹 접근성(A11y) 기초와 실전 적용 방법 (0) | 2025.04.11 |
| [Javascript] this 이것 뭐에요? 자바스크립트 this 정복하기 (0) | 2025.04.11 |