[CS] 브라우저 동작 원리, 렌더링 ♦︎
# 브라우저의 동작 원리
: 사용자가 입력한 URL로부터 페이지를 로드하고 렌더링하여 화면에 표시하는 전체적인 과정
1. URL 입력
- 사용자가 URL을 입력하면 브라우저는 DNS를 통해 IP 주소를 찾는다.
2. 네트워크 연결 및 보안 설정
- 해당 IP 주소의 서버와 TCP 연결을 설정하고, HTTPS인 경우 TLS handshake 과정을 통해 보안 통신을 설정한다.
3. 요청(Request)과 응답(Response)
- 브라우저는 서버에 HTTP 요청 메세지를 TCP/IP 프로토콜을 사용하여 전송한다.
- 서버에서 HTML, CSS, JavaScript, 이미지 등의 리소스를 클라이언트에 반환한다.
[ 렌더링 파이프라인 (렌더링 과정) ]
4. HTML 파싱
- 브라우저가 HTML 파일을 파싱하여 DOM 트리를 만든다.
- HTML을 위에서부터 한 줄 씩 읽으며 태그를 해석하고, 이를 DOM 노드로 변환하는 과정
5. CSS 파싱
- 브라우저가 CSS 파일을 파싱하여 CSSOM 트리를 만든다
6. 렌더 트리 생성
- DOM과 CSSOM을 결합하여 Render Tree를 생성한다.
7. JavaScript 처리
- 브라우저의 JavaScript 엔진이 JavaScript를 실행하여 DOM이나 CSSOM에 영향을 줄 경우 다시 계산을 수행합니다.
8. Layout (Reflow)
- 뷰포트를 기반으로 렌더트리의 각 노드(요소)의 정확한 위치와 크기를 계산함
9. Painting (Repaint)
- 계산된 레이아웃 정보를 바탕으로 요소의 색상, 배경, 텍스트 등 스타일을 픽셀로 변환
10. Compositing (합성)
- Paint 결과를 Layer로 합성하여 최종 화면을 출력
[ HTML 파싱과 JavaScript ]
- 브라우저가 HTML을 파싱하다가 <script> 태그를 만나면, 동기적으로 JavaScript를 실행한다.
- 기본적으로 브라우저는 JavaScript가 완료될 때까지 HTML 파싱을 멈춘다. DOM을 조작하는 JavaScript가 HTML 구조를 변경할 수 있기 때문이다.
- 해결방법으로 <script> 태그에 async 또는 defer 속성을 사용할 수 있다.
async: HTML 파싱과 병렬로 다운로드, 다운로드 완료 후 바로 실행
defer: HTML 파싱이 끝난 후 실행
[ Javascript 실행 시점 ]
Script 방식 | JS 실행 타이밍 | 특징 |
<script> (기본) | HTML 파싱 중단 | HTML을 파싱하다가 JS가 로드되면 실행 후 다시 HTML 파싱 진행 |
<script defer> | HTML 파싱 후, DOM 완성 후 실행 | HTML을 모두 파싱한 후 실행 (렌더링 차단 없음) |
<script async> | 다운로드 완료 후 즉시 실행 | HTML 파싱과 JS 다운로드를 병렬로 진행 , 다운로드 완료시 HTML 파싱을 멈추고 JS 실행 (실행 순서 보장 안됨) |
Q. HTML 렌더링 도중 JavaScript가 실행되면 렌더링이 멈추는 이유는?
A. 브라우저의 렌더링 엔진은 HTML 파싱 과정을 통해 DOM 트리를 생성한다.
JavaScript는 HTML 요소를 동적으로 추가하거나, 스타일을 변경하거나, 이벤트를 처리하는 등 DOM을 조작(추가, 삭제, 수정)할 수 있다.
JavaScript가 DOM을 조작하는 순간에 HTML 파싱이 동시에 진행된다면 충돌이나 예기치 않은 동작이 발생할 가능성이 있다.
이를 방지하기 위해, JavaScript가 실행될 때 브라우저는 HTML 파싱을 멈춰 DOM의 안정성을 보장한다.
브라우저는 JavaScript 실행이 끝난 뒤에 HTML 파싱을 다시 시작한다.
# Reflow
: HTML 요소의 크기, 위치, 배치가 변경될 때 발생하는 과정, 레이아웃 재계산
✅ 발생하는 원인
- 요소의 크기와 위치(width, height, margin, padding, top, left, border 등) 변경
- 새로운 요소가 추가/삭제될 때
- display: none 설정/해제 시
- 브라우저 창 크기 변경 (responsive 디자인)
- position이 absolute 또는 fixed인 요소가 이동할 때
✅ Reflow가 많은 경우 문제점
- 비용이 큰 작업으로 렌더링 성능을 저하시킨다.
- 브라우저가 레이아웃을 다시 계산해야 하므로 CPU 사용량 증가
- 애니메이션이 끊기거나 버벅임 발생 가능
# Repaint
: 요소의 스타일(색상, 그림자, 배경 등)이 변경될 때 발생하는 과정
✅ 발생하는 원인
- color, background-color, border-color 변경
- box-shadow 변경
- visibility 속성 변경
- ' visibility: hidden ' 은 요소를 숨기지만 요소의 공간은 여전히 차지하도록 하기때문에 레이아웃에는 영향을 미치지 않음
✅ 영향 범위
- Repaint는 레이아웃 변화 없이 픽셀만 다시 그리는 과정이므로 Reflow보다는 성능 부담이 적음
- 하지만 너무 자주 발생하면 그래픽 성능 저하
[ 용어 정리 ]
# DNS (Domain Name System)
: 사용자가 웹사이트에 접속할 때, 도메인 이름(예: www.example.com)을 IP 주소로 변환하는 시스템
- 사람이 읽기 쉬운 도메인 이름을 컴퓨터가 이해할 수 있는 IP 주소로 변환하는 역할
# 파싱(Parsing)
= 동사 (문장을 문법적으로) 분석하다
: 데이터를 특정한 규칙에 따라 분석하거나 해석하여 컴퓨터가 이해할 수 있는 구조로 변환하는 과정
: 하나의 프로그램을 런타임 환경이 실제로 실행할 수 있는 내부 포맷으로 분석하고 변환하는 것
- 문서의 내용을 토큰으로 분석하고, 문법적 의미와 구조를 반영한 파스 트리를 생성한다.
예시)
1. 프로그래밍 언어에서 코드 분석 : 컴파일러나 인터프리터가 소스 코드를 읽고, 이를 구문 분석해 실행 가능한 형태로 변환.
2. HTML, XML, JSON 등의 파일 읽기 : 브라우저나 애플리케이션이 HTML, XML, JSON 데이터를 파싱해 DOM이나 객체로 변환
# DOM(Document Object Model)
= 문서 객체 모델
= 웹 문서를 표현하는 프로그래밍 인터페이스
= 브라우저가 HTML, XML 같은 문서를 파싱한 뒤 생성하는 객체 기반의 구조
= 웹 페이지를 이루는 태그들을 자바스크립트가 이용할 수 있게끔 브라우저가 트리구조로 만든 객체 모델
- 이를 통해 프로그래밍 언어(주로 JavaScript)가 문서의 내용, 구조, 스타일을 동적으로 접근하고 조작할 수 있다
// 자바스크립트로 DOM 객체에 접근하여 읽거나 수정하는 예시
// <h1>Welcome</h1> 노드에 접근
const h1 = document.querySelector("h1");
// 텍스트 변경
h1.textContent = "Hello, DOM!";
// 새로운 노드 추가
const newParagraph = document.createElement("p");
newParagraph.textContent = "This is a new paragraph!";
document.body.appendChild(newParagraph);
# DOM 트리
= DOM을 트리 구조로 표현한 것
= HTML 문서의 계층적 구조를 트리 형태로 변환하여 표현한 것
- 각 HTML 요소가 트리의 노드(Node) 형태로 나타난다
HTML 코드 :
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
</head>
<body>
<h1>Hello, World!</h1>
<p>This is an example paragraph.</p>
</body>
</html>
DOM 트리 :
Document
├── html
├── head
│ └── title
│ └── "Example"
└── body
├── h1
│ └── "Hello, World!"
└── p
└── "This is an example paragraph."
# CSSOM (CSS Object Model) 트리
- CSS 스타일 규칙을 파싱한 뒤, 문서의 각 요소에 스타일을 적용할 수 있도록 생성하는 객체 모델
- CSS 스타일을 계층적으로 표현한 구조
- 스타일 규칙과 속성을 표현한다.
# 렌더링 (Rendering)
= 동사 (어떤 상태가 되게) 만들다[하다]
: 텍스트, 이미지, 동영상 등을 웹 브라우저 화면에 시각적으로 표시하는 과정
- 브라우저는 서버에서 전달받은 리소스(HTML, CSS, JavaScript 등)를 사용하여 렌더링 엔진을 통해 화면에 콘텐츠를 표시한다.
- 렌더링 엔진 : 크롬은 Blink, 사파리는 WebKit, 파이어폭스는 Gecko 라는 렌더링 엔진을 보통 사용
# 렌더 트리 (Render Tree)
= 웹 페이지의 화면에 표시될 요소와 스타일 정보를 포함하는 데이터 구조
- DOM 트리와 CSSOM 트리를 결합하여 생성한다.
- 화면에 그려지는 요소들만 포함한다. (예: display: none 제외)
// 렌더 트리
body {
font-size: 16px;
}
├── h1 {
color: blue;
}
└── p {
font-size: 16px;
}
# Critical Rendering Path (CRP, 중요 렌더링 경로)
= 웹 페이지를 최적화된 속도로 렌더링하기 위해 필요한 핵심적인 렌더링 과정
= 브라우저가 화면에 페이지를 빠르게 표시하기 위해 따르는 경로를 나타낸다.
- 렌더링 과정의 각 단계에서 최적화를 고려하여 최소한의 시간 안에 페이지를 렌더링하고, 불필요한 지연을 줄이는 것이 CRP 최적화의 핵심이다.