- Published On
랜더링(rendering)
랜더링이란?
랜더링(rendering)
또는 이미지 합성
은 컴퓨터 프로그램을 사용하여 이미지를 생성하는 프로세스
입니다.
브라우저가 화면에 나타나는 요소를 랜더링할 때, 웹킷(Webkit)이나 게코(Gecko) 등과 같은 랜더링 엔진을 사용합니다.
엔진이 HTML, CSS, Javascript로 랜더링할 때 CRP(Critical Rendering Path)
라는 프로세스를 사용합니다.
이 CRP는 6단계로 이루어져있으며, 사이트 성능을 향상시키는 방법을 이해하는데 매우 유용합니다.
- DOM(Document Object Model) 트리 구축
- CSSOM(CSS Object Model) 트리 구축
- JavaScript 실행
- 렌더트리(Render Tree) 구축
- 레이아웃 생성
- 페인팅
자세히 살펴보겠습니다.
- HTML 파싱 후,
DOM(Document Object Model) 트리 구축
아래의 html을 예시로 살펴보겠습니다.
<html>
<head>
<title>Understanding the Critical Rendering Path</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<h1>Understanding the Critical Rendering Path</h1>
</header>
<main>
<h2>Introduction</h2>
<p>Lorem ipsum dolor sit amet</p>
</main>
<footer>
<small>Copyright 2017</small>
</footer>
</body>
</html>
위의 html은 아래와 같은 dom tree를 생성합니다.
html의 장점 중 하나로 부분적으로 실행 될 수 있으며, 내용이 표시되기 위해 전체가 로드될 필요가 없습니다.
- CSS 파싱 후,
CSSOM(CSS Object Model) 트리 구축
CSS의 특징으로는 "랜더링 차단 리소스(render blocking resource)"로 간주됩니다.
즉, 먼저 리소스를 완전히 파싱하지 않으면 랜더링 트리를 구성 할 수 없습니다.
HTML과 달리 CSS는 계단식 상속 특성 때문에 부분적으로 실행될 수 없습니다.
Javascript 실행
- 주의! HTML 중간에 스크립트가 있다면 HTML 파싱이 중단
즉 ,파서가 내부 태그이든 외부 태그이든 script태그
에 도달하면 fetch를 중단하고 실행합니다.
따라서 문서 내의 요소를 참조하는 JavaScript 파일이 있는 경우 해당 문서가 표시된 후에 배치 해야 한다.
JavaScript가 파서 차단(parser blocking)되는 것을 피하기 위해 async 속성을 적용하여 비동기적으로 로드 할 수 있습니다.
- DOM과 CSSOM을 조합하여
렌더트리(Render Tree) 구축
- 주의!
display: none
속성과 같이 화면에서 보이지도 않고 공간을 차지하지 않는 것은 렌더트리로 구축되지 않는다.
- 주의!
- 뷰포트 기반으로 렌더트리의 각 노드가 가지는 정확한 위치와 크기 계산 (
Layout/Reflow 단계
)
아래 코드는 HTML 문서의 head 태그
안에 들어가는 메타 태그입니다.
이 메타 태그는 웹 페이지가 모바일 장치에서 어떻게 랜더링될지를 제어합니다. 코드는 다음과 같습니다.
<meta name="viewport" content="width=device-width,initial-scale=1">
이 메타 태그와 vw 단위의 사용은 반응형 웹 디자인에서 매우 중요합니다.
name="viewport"
: 이 부분은 메타 태그가 뷰포트 설정과 관련되어 있음을 명시합니다.
뷰포트는 사용자가 웹 페이지를 방문할 때 웹 페이지가 표시되는 영역을 의미합니다.
content="width=device-width"
: 이 설정은 뷰포트의 너비를 장치의 화면 너비와 동일하게 설정합니다.
즉, 웹 페이지의 너비가 사용자의 장치 너비에 맞춰집니다. 이렇게 설정하면 페이지가 다양한 크기의 화면에서도 적절하게 표시됩니다.
initial-scale=1
: 이 부분은 페이지가 처음 로드될 때의 확대/축소 수준을 의미합니다.1
은 페이지가 기본 배율로 표시되어야 함을 나타냅니다.
즉, 추가적인 확대나 축소 없이 기본 크기로 표시됩니다.
사용자가 화면 너비(width)가 1000px인 장치에서 웹 페이지를 방문한다고 가정해보겠습니다.
이 경우, 뷰포트의 너비는 device-width
설정에 따라 1000px가 됩니다.
- 계산한 위치/크기를 기반으로 화면에 그림 (
Paint 단계
)
실시간으로 개발자도구의 네트워크 탭을 눌러서 아래의 내용을 확인할 수 있습니다.
//html
Send Request - index.html에 대한 GET 요청 전송
Parse HTML and Send Request - HTML 및 DOM 구문 분석을 시작. style.css 및 main.js에 대한 GET 요청
Parse Stylesheet - CSSOM이 style.css 용으로 생성
Evaluate Script - main.js 평가
Layout - HTML의 메타 뷰포트 태그를 기반으로 레이아웃 생성
Paint - 문서의 픽셀을 페인트
이제 HTML, React, Next.js의 랜더링 방식에 대해 비교해 보겠습니다.
랜더링 방식 비교
전통적인 HTML 랜더링
전통적인 웹사이트에서 서버가 페이지 요청에 응답하는 방식은 서버 중심 랜더링 방식
입니다.
이 방식은 서버가 미리 준비한 완전한 HTML 파일을 브라우저에 전달하며, 브라우저는 이를 해석하여 화면에 표시합니다.
단계 | 설명 |
---|---|
1. 페이지 요청 | 사용자가 브라우저에서 특정 URL을 입력하거나 링크를 클릭하여 서버에 페이지 요청을 보냅니다. |
2. 서버 응답 | 서버는 해당 페이지에 대한 완전한 HTML 파일을 준비하여 브라우저에 전달합니다. 이 파일에는 문서의 구조와 콘텐츠가 포함되어 있습니다. |
3. DOM 트리 생성 | 브라우저는 수신한 HTML 파일을 파싱하여 DOM(Document Object Model) 트리를 생성합니다. 이 트리는 페이지의 구조와 요소 간의 관계를 나타냅니다. |
4. CSSOM 트리 생성 | 브라우저는 HTML 내에서 연결된 CSS 파일을 로드하고, 이를 파싱하여 CSSOM(CSS Object Model) 트리를 생성합니다. |
5. 렌더 트리 생성 | DOM과 CSSOM 트리를 결합하여 렌더 트리를 생성합니다. 이 렌더 트리는 페이지를 실제로 화면에 그리기 위한 계산을 나타냅니다. |
6. 레이아웃 (Reflow) | 렌더 트리가 생성된 후, 브라우저는 각 요소의 크기와 위치를 계산하여 레이아웃을 설정합니다. 이 단계에서는 각 요소가 화면에 어떻게 배치될지를 결정합니다. |
7. 페인팅 (Painting) | 요소들이 렌더 트리를 통해 결정되면, 브라우저는 실제 화면에 그리기 시작합니다. 이 단계에서 화면에 요소들이 페인팅됩니다. |
8. 화면 표시 | 최종적으로 페인팅된 페이지가 사용자에게 표시됩니다. 이때 모든 리소스가 로드되고, 브라우저는 화면 상에 완성된 페이지를 랜더링합니다. |
React 랜더링
React는 클라이언트 사이드 랜더링(CSR)
을 사용하는 JavaScript 라이브러리입니다.
이는 브라우저가 JavaScript를 실행하여 동적으로 HTML을 생성하고, 사용자와 상호작용할 수 있는 페이지를 랜더링하는 방식입니다.
React에서는 가상 DOM(Virtual DOM)
을 통해 효율적으로 변경된 부분만 업데이트하는 방식으로 UI 성능을 최적화합니다.
단계 | 설명 |
---|---|
1. 페이지 요청 | 사용자가 브라우저에서 특정 URL을 입력하거나 링크를 클릭하여 서버에 HTML 페이지와 JavaScript 파일을 요청합니다. |
2. 서버 응답 | 서버는 기본 HTML과 번들된 JavaScript 파일을 전달합니다. HTML 파일은 주로 비어있으며, JavaScript가 브라우저에서 실행되어 화면을 구성합니다. |
3. 초기 DOM 생성 | 브라우저는 기본 HTML을 파싱해 빈 DOM을 생성합니다. 이후 JavaScript 파일을 로드하고 실행합니다. |
4. 가상 DOM 생성 | React는 JavaScript 실행 중 가상 DOM을 생성하여, 메모리에서 DOM의 구조와 상태를 관리합니다. |
5. 실제 DOM 업데이트 | 가상 DOM과 실제 DOM을 비교하여(디프 알고리즘) 변화된 부분만 실제 DOM에 적용합니다. 이를 통해 효율적으로 화면이 업데이트됩니다. |
6. 사용자 인터페이스 | 최종적으로 업데이트된 DOM이 사용자에게 표시되며, 이후 사용자 상호작용에 따라 DOM이 실시간으로 변경되고, React가 이를 가상 DOM을 통해 효율적으로 관리합니다. |
Next.js 랜더링
Next.js는 React를 확장한 프레임워크로, 다양한 랜더링 방식을 지원합니다.
Next.js는 서버에서 HTML을 미리 랜더링해 빠른 초기 로딩과 SEO 최적화를 달성할 수 있습니다.
단계 | SSR (서버 사이드 랜더링) | SSG (정적 사이트 생성) | CSR (클라이언트 사이드 랜더링) |
---|---|---|---|
1. 페이지 요청 | 사용자가 URL을 입력하거나 링크를 클릭하여 서버에 페이지 요청을 보냅니다. | 빌드 시 서버에서 미리 HTML 파일을 생성하고, 클라이언트는 해당 HTML 파일을 요청합니다. | React와 동일하게 클라이언트 측에서 JavaScript로 페이지를 동적으로 생성합니다. |
2. 서버 응답 | 서버는 해당 페이지에 대한 완전한 HTML 파일을 서버에서 동적으로 생성한 후 클라이언트에 전달합니다. | 서버는 사전에 생성된 정적 HTML 파일을 클라이언트에 전달합니다. | JavaScript 파일을 클라이언트에 전달합니다. |
3. DOM 트리 생성 | 클라이언트는 서버에서 전달된 완전한 HTML 파일을 사용하여 DOM 트리를 생성합니다. | 사전에 생성된 HTML 파일을 기반으로 DOM 트리를 생성합니다. | React와 동일하게 JavaScript가 실행되어 가상 DOM과 실제 DOM이 생성됩니다. |
4. CSSOM 트리 생성 | 브라우저는 연결된 CSS 파일을 로드하고, CSSOM 트리를 생성합니다. | 연결된 CSS 파일을 로드하여 CSSOM 트리를 생성합니다. | CSS 파일을 로드하고 CSSOM 트리를 생성합니다. |
5. 레이아웃 및 페인팅 | DOM과 CSSOM 트리를 결합하여 렌더 트리를 생성하고, 브라우저가 이를 화면에 그립니다. | DOM과 CSSOM 트리를 결합하여 렌더 트리를 생성하고, 브라우저가 이를 화면에 그립니다. | 동일한 과정으로 화면에 표시됩니다. |
6. 인터랙션 처리 | 클라이언트에서 사용자 인터랙션이 발생하면 필요한 부분만 서버에서 다시 랜더링하거나, 클라이언트 측에서 처리된 상호작용을 DOM에 반영합니다. | SSG는 정적으로 생성된 페이지이므로, 추가적인 상호작용은 클라이언트에서 처리됩니다. | 사용자 상호작용이 발생할 때마다 React가 실시간으로 가상 DOM과 비교해 화면을 업데이트합니다. |
최종 랜더링 비교
아래 표는 전통적인 HTML, React, 그리고 Next.js의 랜더링 방식을 비교한 표입니다.
특징 | 전통적인 HTML 랜더링 | React (CSR) | Next.js (SSR, SSG, CSR) |
---|---|---|---|
랜더링 방식 | 서버에서 완전한 HTML 파일을 제공 | 클라이언트에서 동적으로 DOM을 생성 | 서버에서 미리 랜더링 (SSR/SSG) 또는 클라이언트에서 랜더링 (CSR) |
초기 로딩 속도 | 빠름 (완전한 HTML을 제공) | 느림 (빈 HTML과 JavaScript 로딩 후 랜더링) | SSR/SSG는 빠름, CSR은 느림 |
SEO 친화성 | 높음 (서버에서 완전한 HTML 제공) | 낮음 (초기 로딩 시 HTML이 비어 있음) | 높음 (SSR/SSG는 완전한 HTML 제공) |
동적 콘텐츠 처리 | 서버에서 모든 콘텐츠를 준비 | 클라이언트에서 실시간으로 처리 | SSR은 실시간 처리 가능, SSG는 정적, CSR은 클라이언트에서 처리 |
사용 사례 | 정적인 웹 페이지 (정보 제공, 문서) | SPA, 상호작용이 많은 웹앱 | SEO가 중요한 사이트 (블로그, 뉴스), 상호작용이 필요한 앱 |
결론
React는 클라이언트 사이드 랜더링(CSR)
을 통해 클라이언트 측에서 동적으로 DOM을 생성하고, 빠른 UI 업데이트를 제공하지만 초기 로딩 속도는 느릴 수 있습니다.
반면 Next.js
는 SSR, SSG, ISR 등 다양한 랜더링 방식을 지원하여 성능 최적화
와 SEO
에 유리합니다.
이를 통해 Next.js는 동적 콘텐츠가 많거나 SEO가 중요한 웹사이트에서 효과적으로 사용
될 수 있습니다.
참고 자료
이전 포스트
Reflow와 Repaint의 차이점다음 포스트
import vs require연관된 포스트 구경가기