일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- GIT
- 데이터통신
- 파이썬 정렬
- 자료형
- IT5분잡학사전
- 노개북
- 북클럽
- CS
- 파이썬 자료형
- ARP
- 파이썬 연산자
- 이것이 취업을 위한 코딩테스트다
- sort()
- 기억장치
- 쿠키
- 노마드코더
- icmp
- 리스트
- data type
- 라우팅
- 시스템 소프트웨어
- 컴퓨터네트워크
- RARP
- 컴퓨터 동작방식
- 이것이 취업을 위한 코딩 테스트다
- 데이터 통신과 컴퓨터 네트워크
- 이코테
- DP
- 쉽게 배우는 데이터 통신과 컴퓨터 네트워크
- OSI7계층모델
Archives
- Today
- Total
뚝딱햄 탈출기
[기술면접대비] 브라우저의 동작 원리와 페이지 렌더링 과정 본문
브라우저의 동작 원리
주소창에 url을 입력하고 엔터키를 치면?
- DNS 조회 (도메인 이름 → IP 주소)
- 웹 브라우저는 사용자가 입력한 URL 주소를 분석해 도메인 이름(www.naver.com)을 찾은 후 DNS를 통해 도메인 이름을 IP 주소로 변환한다.
- TCP 연결
- 웹 브라우저는 DNS에서 반환된 IP 주소로 TCP 연결을 시도한다.
- HTTP 요청
- 해당 IP 주소로 HTTP GET 요청 메시지를 전송한다.
- 웹 서버는 IP 주소로 식별된다. ⇒ 브라우저가 서버로 HTTP 요청을 보낸다!
- 서버 응답
- 웹 서버는 HTTP 요청을 처리하고 HTTP 응답 메시지를 보낸다.
- 이 응답은 요청에 대한 상태 코드, 응답 헤더 및 본문으로 구성된다.
- 응답 메시지의 본문에 HTML 문서, 이미지, 스크립트와 같은 웹 페이지의 실제 콘텐츠가 포함된다.
- 응답 처리
- 브라우저는 서버로부터 받은 응답을 처리한다.
- 이 과정에서 응답 본문을 분석하여 HTML, CSS 및 JavaScript 파일을 추출하고, 페이지의 렌더링 및 기능 구현을 위한 자원을 내려받는다.
- 페이지 렌더링
🧐 페이지는 어떻게 렌더링되는가?
CRP(중요 렌더링 경로, Critical Rendering Path)
💡 CRP를 최적화하는 것은 아래 단계를 수행하는 데 소요되는 총 시간을 최소화하는 프로세스이다.
- 서버에서 응답으로 받은 HTML 데이터를 파싱한다.
- 파싱하는 중 CSS 파일 링크를 만나면 CSS 파일을 요청해서 받아온다.
- 파싱 과정을 잠시 멈추고 요청을 보내며, 응답이 오면 HTML 과정과 병렬적으로 CSS 파일을 파싱한다.
- 파싱하는 중 JS 파일을 만나면 해당 파일을 받아와 실행할 때까지 파싱이 멈춘다.
<html> <head> <meta charset="utf-8"> <link href="./style.css" rel="stylesheet"> </head> <body> <p>Hello, <span>web performance</span> students</p> <div> <img src="./image.png"> </div> </body> </html>
- 파싱하는 중 CSS 파일 링크를 만나면 CSS 파일을 요청해서 받아온다.
- HTML 파싱 결과로 DOM(Document Object Model) 트리를 구축한다.
- CSS 파싱 후, CSSOM(CSS Object Model) 트리를 구축한다.
- DOM 트리와 CSSOM 트리를 결합해 렌더 트리(Render Tree)를 구축한다.
- DOM 트리의 노드 중 화면에 보이는 것들만으로 구성된다. (페이지를 렌더링하는 데 필요한 노드만 포함된다.)
- 따라서 <header>나 display: none 속성이 적용된 요소는 렌더 트리에 포함되지 않는다.
- visibility: hidden는 요소를 보이지 않게 만들지만 레이아웃에서 공간을 차지한다. (= 렌더 트리에 포함된다)
- 뷰포트 기반으로 렌더트리의 각 노드의 정확한 위치와 크기 계산 (Layout, Reflow) 단계)
- 렌더 트리가 생성되고 나면 레이아웃이 가능해지며 화면의 크기에 의존한다. ⇒ 뷰포트 기반
- 뷰포트 크기는 문서 헤드에 제공된 메타 뷰포트 태그에 의해 결정된다. 태그가 제공되지 않으면 기본 뷰포트 너비(980px)가 사용된다.
- 레이아웃 성능은 DOM의 영향을 받는다.
- 노드의 수가 많을수록 레이아웃은 더 길어지며 스크롤링 또는 다른 애니메이션들이 필요하다면 레이아웃에 쟁크(jank)를 일으키는 병목현상이 발생할 수 있다.
- 렌더 트리가 생성되고 나면 레이아웃이 가능해지며 화면의 크기에 의존한다. ⇒ 뷰포트 기반
- 계산한 위치와 크기를 기반으로 화면에 픽셀을 렌더링한다. (개별 노드를 화면에 페인팅) (Paint 단계)
- 페인트 단계에서 처리에 걸리는 시간은 DOM의 크기와 적용되는 스타일에 따라 다르다.
🔍 리플로우 & 리페인트 자세히 보기
💡 리플로우 비용 > 리페인트 비용
Reflow: 변경사항을 반영하기 위해 렌더링 트리를 생성하고 레이아웃 과정을 다시 수행하는 것
Repaint: 리플로우 결과를 화면에 그리는 것
만약 DOM이 조작되는 등의 이유로 화면을 다시 그려야 한다면 경우에 따라 다시 레이아웃 작업을 하는 리플로우와 다시 페인트 작업을 하는 리페인트 과정이 발생한다.
리플로우가 일어나면 반드시 리페인트가 일어나지만, 레이아웃에 영향을 미치지 않는 단순한 변경사항은 리플로우 수행 없이 리페인트만 수행한다.
Reflow가 일어나는 대표적인 속성
- position, width, height, margin, padding, border, border-width, font-size, font-weight, line-height, text-align, overflow
- width: 50% 로 되어있는데 브라우저를 리사이즈한다면 렌더 트리는 그대로인 상태에서 리플로우 & 리페인트
Repaint가 일어나는 대표적인 속성
- background, color, text-decoration, border-style, border-radius
브라우저 렌더링 과정에서 자바스크립트는 어떻게 작동하는가
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>테스트</title>
</head>
<body>
<div></div>
<script src="script.js"></script>
</body>
</html>
document.querySelector('div').addEventListener('click', () => {
console.log('Click div');
});
- HTML 파일 파싱 과정에서 script 태그를 만나면 파싱 과정을 멈춘다.
- script 태그에 src 속성이 있다면 스크립트 파일을 받고, script 태그의 자바스크립트 파일을 해석하고 실행한다.
- script 태그에 async 속성이 있으면, 파싱과 병렬적으로 스크립트를 다운로드하고, 다운로드가 종료된 직후 파싱 과정을 멈추고 스크립트를 처리한다.
- script 태그에 defer 속성이 있으면, async 속성처럼 파싱과 병렬적으로 스크립트를 다운로드하지만, HTML 파일의 파싱이 종료된 이후에 스크립트를 처리한다.
- 스크립트를 처리할 때, 자바스크립트 파일을 해석하고 실행하기 위해서 렌더링 엔진은 자바스크립트 엔진에게 제어권을 넘겨준다.
- 제어권을 받은 자바스크립트 엔진은 자바스크립트 코드를 해석해서 AST를 생성하고, AST를 기반으로 인터프리터가 실행할 수 있는 중간 코드를 생성해서 실행한다.
- 모든 스크립트 처리가 끝나면 다시 자바스크립트 엔진에서 렌더링 엔진으로 제어권을 돌려주고, 남은 HTML 파일 파싱 과정을 진행한다.
script, script async, script defer
바로 위에 작성한 내용, 그림과 함께 보면 이해할 수 잇서 !!!!!!
HTML 파일 파싱 과정에서 script 태그를 만나면 파싱 과정을 멈춘다.
- script 태그에 src 속성이 있다면 스크립트 파일을 받고, script 태그의 자바스크립트 파일을 해석하고 실행한다.
- script 태그에 async 속성이 있으면, 파싱과 병렬적으로 스크립트를 다운로드하고, 다운로드가 종료된 직후 파싱 과정을 멈추고 스크립트를 처리(실행)한다.
- script 태그에 defer 속성이 있으면, async 속성처럼 파싱과 병렬적으로 스크립트를 다운로드하지만, HTML 파일의 파싱이 종료된 이후에 스크립트를 처리(실행)한다.
💡 주의! async와 defer의 경우 src 속성이 없으면 적용되지 않는다.
<script async>
- 구글 애널리틱스와 같이 다른 스크립트가 의존하지 않는 독자적인 스크립트는 로드할 때 적합하다.
<script defer>
- DOM 요소가 모두 준비된 후에 실행되므로 DOM 조작 관련 오류를 줄일 수 있다.
- 페이지 로딩을 방해하지 않고 DOM 구조 파싱이 완료된 후에 실행되므로 페이지 로딩 성능을 향상시킬 수 있다.
- 태그 배치 순서와 상관없이 DOM 준비 완료 후 실행되므로 코드 순서에 대한 의존성을 줄일 수 있다.
- 브라우저 호환성 측면에서 단점을 갖는다. 모든 브라우저에서 동일하게 지원되는 것이 아니며, 일부 오래된 브라우저에서는 예상대로 작동하지 않을 수 있다.
- 일반적으로 <body> 태그 직전에 삽입한다. (<script> 태그는 <body> 태그의 최하단에 위치시키는 것이 좋다는 점과 대비된다!)
- 최대 호환성을 보장해야 하는 경우
- DOM 조작과 관련된 스크립트를 <head> 섹션에 배치해야 하는 경우 (예: 기본 스타일 적용)
- 스크립트 실행 순서를 명확하게 제어해야 하는 경우
script 태그를 body 태그의 최하단에 위치시키는 이유
- HTML 파일 파싱 중 script 태그를 만나면 HTML 파싱 과정을 멈추고 즉시 스크립트를 다운로드 및 실행한다.
script 태그가 body의 최하단에 위치하지 않으면 생기는 문제
- 스크립트를 처리하는 동안 페이지 로딩 속도가 느려지고, 남은 HTML 부분에 대한 지연이 발생할 수 있다.
- 대용량 스크립트의 경우 페이지 로딩을 크게 방해할 수 있다.
- 스크립트가 DOM 요소를 조작하는 경우, DOM 요소가 아직 준비되지 않은 상태에서 조작하려고 하여 오류가 발생할 수 있다.
script 태그가 body 태그의 최하단에 위치하면 좋은 점
- HTML의 콘텐츠가 다 로딩된 body 태그의 마지막 부분에 script 태그를 위치시키면 로딩 지연을 줄일 수 있다.
- 그러나 기본적인 script 태그를 사용하면 body 태그의 마지막에 선언된 script 태그를 만난 이후 다운로드를 시작하는 문제점이 있다. 이를 해결하기 위해 script 태그에 defer 속성을 둬서 파싱과 병렬적으로 스크립트를 다운로드 한 후, HTML 파싱이 끝난 후 스크립트를 처리할 수 있다.
reference
https://m.post.naver.com/viewer/postView.nhn?volumeNo=8431285&memberNo=34176766
'web' 카테고리의 다른 글
[기술면접대비] HTTP vs. HTTPS (0) | 2024.05.02 |
---|---|
[기술면접대비] HTTP, GET-POST 메서드의 차이?, REST API란? (0) | 2024.05.02 |
[기술면접대비] BOM, DOM, Virtual DOM (0) | 2024.03.13 |
[JavaScript] jQuery 제이쿼리 (0) | 2023.10.09 |
Ajax : 개념, 실습 (0) | 2023.10.09 |
Comments