브라우저 렌더링

WebBrowser
shmoon
·
·76 min read

탐색 (요청) → HTTP Request

DNS 조회

탐색은 웹페이지를 로딩하는 첫단계. 사용자가 브라우저 주소창에 URL을 입력하거나, 링크 클릭, form 제출 등 동작을 통해 요청을 할때마다 발생한다.

URL을 입력해서 어떤 웹페이지에 접속하려고 가정할 때, 주소창에 URL을 입력하면 해당 페이지의 자원이 어디 있는지 찾고자 DNS 조회가 이루어진다.

한번도 방문한 적 업는 웹페이지라면, 브라우저는 DNS 조회를 요청하고, DNS 서버는 이에 대해 IP 주소로 응답한다.

IP는 일정 기간 캐시되며, DNS에 다시 요청을 보내는 대신 캐시에서 IP주소를 검색할 수 있다.

DNS 조회는 요청된 페이지에서 참조하는 다른 호스트 이름에 대해서 각각 수행한다. 글꼴, 이미지, 스크립트, 광고 다른 자원들이 서로 다른 호스트 이름을 가지고 있으면 각각에 대해 DNS 조회가 수행된다.

💡

DNS (Domain Name Server)
IP주소와 도메인 주소를 연결해주는 역할

웹페이지 검색 → DNS조회 → IP 응답 → 보안 연결 핸드셰이크, TLS.. → HTTP Request

TCP 핸드 셰이크

💡

TCP/IP (전송 제어 프로토콜/인터넷 프로토콜)
인터넷에서 컴퓨터들이 서로 정보를 주고 받는데 쓰이는 프로토콜의 집합
TCP 는 신뢰성있고 무결성을 보장하는 연결을 통해 데이터를 안전하게 전송해주는 전송 프로토콜
IP 는 패킷들이 가장 효율적인 방법으로 최종 목적지로 갈 수 있도록 해주는 프로토콜

Untitled.png

www.google.com URL을 검색하여 구글 페이지에 접속하고자 할 때,

이 주소에 대한 요청을 인터넷을 통해 구글 서버로 전달한다. 이때 요청 정보를 전달하기 위해 패킷을 만들어야하고 패킷에는 각 계층에 필요한 정보들이 담겨야 한다. (IP, HTTP .. ) 위에서 본 DNS는 Transport Layer에서 UDP라는 프로토콜을 사용한다.

→ 패킷: 네티워크에서 전송되는 데이터의 기본 단위

→ 프로토콜: 네트워크 통신을 위한 공통된 메뉴얼

TCP 핸드셰이크란?

TCP는 서버와 클라이언트 간의 데이터를 신뢰성있게 전달하기 위한 프로토콜이라고 했다. 이를 위해 3-Way Handshake를 사용한다.

TCP/IP 프로토콜을 이용해서 통신을 하는 응용프로그램이 데이터를 전송하기 전에 먼저 정확한 전송을 보장하기 위해 상대방 컴퓨터와 사전에 세션을 수립하는 과정

SYN, SYN-ACK, ACK 3가지 메시지를 전달한다.

3방향 핸드셰이크는 클라이언트와 서버 양쪽 모두 데이터를 전송할 준비가 되어있다는 것을 보장하고, 실제로 데이터 전달이 시작하기 전에 다른 한쪽이 준비되었다는 것을 알 수 있도록 해준다.

DNS 조회 → “TCP 핸드셰이크“ → TLS 협상

TLS 협상

💡

TLS (Transport Layer Security)
온라인 네트워크에서 데이터를 안전하게 주고받기 위한 암호화 프로토콜
통신 데이터를 TLS 프로토콜을 따라 암호화하면 누군가 데이터를 가로채도 복호화할 수 없기 때문에 악성 공격에서 데이터를 보호할 수 있다.
TLS가 적용된 HTTP를 HTTPS라고 불린다.

사용자의 최초 요청 후에 클라이언트와 서버 간에는 DNS, TCP, TLS 프로토콜을 통해 8번의 왕복이 있은 후에 브라우저는 마침내 HTTP Request를 할 수 있게 된다.

  • DNS: IP 조회
  • TCP: 신뢰성있는 데이터 전달을 위한 프로토콜, 데이터 전송 준비 완료 보장
  • TLS: 데이터 암호화

응답 (Response)

위의 과정이 완료되면 마침내! 웹서버와의 연결이 성립되는데, 브라우저는 HTTP GET Request를 보낸다.

브라우저는 서버에 HTML 파일을 요청한다. 서버가 요청을 받으면 HTML의 내용을 응답한다.

TCP 슬로우 스타트 (14kb rule)

네트워크 통신 속도를 조절하는 알고리즘, 첫 응답 패킷은 14kb이다. TCP 슬로우 스타트 방식에 따라, 첫 패킷을 받은 후 서버는 다음 패킷의 사이즈를 두배로 늘린다. 뒤이은 패킷도 혼잡의 징후가 나타나기 전까지 2배씩 커진다.

TCP 슬로우 스타트는 혼잡을 피하기 위해 네트워크 용량에 적당한 전송 속도를 찾고자 점진적으로 속도를 높여나간다.

파싱 (구문 분석)

💡

파싱 (syntax analysis)
브라우저 요청에 의해 서버가 응답한 HTML문서는 문자열로 이루어진 순수한 텍스트다. 파싱은 이런 텍스트 문서를 읽어 들여 실행하기 위해 텍스트 문서의 문자열을 토큰으로 분해하고, 토큰에 문법적 의미와 구조를 반영하여 파스트리를 생성하는 일련의 과정이다.

브라우저가 첫번째 데이터를 응답받으면 수신된 정보를 구문 분석하기 시작한다. 브라우저가 네트워크를 통해 받은 데이터를 DOM 또는 CSSOM으로 바꾸는 단계이다. 이는 렌더러가 화면에 페이지를 그리는데 사용된다.

HTML → DOM (바이트 → 문자 → 토큰분해 → 토큰을 객체변환하여 노드생성 → DOM)
CSS → CSSOM
Javascript → AST (Abstact Syntax Tree) → 바이트 코드(중간코드) → 실행

DOM과 CSSOM은 렌더링을 위해 렌더 트리로 결합된다. 렌더 트리는 렌더링을 위한 트리 구조의 자료. 브라우저 화면에 렌더링 되지 않는 노드 (meta태그, script태그, display: none 처리된 요소 등) 들은 포함하지 않는다.

렌더 트리를 기반으로 HTML 요소의 레이아웃 (위치와 크기)을 계산하고 브라우저 화면에 HTML요소를 페인팅한다. 렌더링 엔진은 HTML을 한 줄씩 순차적으로 파싱하며 DOM을 생성해 나가다가 자바스크립트 파일을 로드하는 script태그를 만나면 DOM생성을 일시 중단한다. 브라우저는 자바스크립트 코드를 파싱하기 위해 자바스크립트 엔진에 제어권을 넘기고, 자바스크립트 파싱 및 실행이 종료되면 렌더링 엔진으로 다시 제어권을 넘겨 HTML파싱이 중단된 지점부터 HTML파싱을 시작하여 DOM생성을 재개한다.

자바스크립트 엔진은 자바스크립트를 해석하여 AST(추상적 구문 트리)를 생성한다.

프리로드 스캐너

브라우저가 DOM 트리를 만드는 프로세스는 메인 쓰레드를 차지한다. 프리로드 스캐너는 사용 가능한 컨텐츠를 분석하고 CSS나 Javascript, 웹 폰트 같이 우선순위가 높은 자원을 요청한다. 프리로드 스캐너가 자원을 뒤에서 미리 요청하기 때문에 구문 분석기가 자원에 다다를 때 쯤이면 이미 그 자원들을 전송받고 있거나, 전송 받은 후다. avascript가 프로세스를 막지 않도록 하려면 async 또는 defer속성을 추가하여야 한다. Javascript는 DOM API를 이용해 DOM, CSS 속성들을 조작할 수 있기 때문에 HTML 분석이나 다운로드를 막을 수 있다.

DOM은 HTML 요소와 스타일 등을 변경할 수 있는 프로그래밍 인터페이스로서 DOM API를 제공한다. Javascript는 DOM API를 이용해 이미 생성된 DOM을 동적으로 조작할 수 있다.

렌더

💡

렌더링 → 스타일, 레이아웃, 페인트, 합성

렌더 트리는 요소의 레이아웃을 계산한다. 그 후 요소가 화면에 페인트된다.

스타일

DOM + CSSOM = Lender Tree (Style Tree)

각각의 보이는 노드는 그 노드에 적용된 CSSOM 규칙이 있다. CSS 캐스케이드 방식에 따라서 각 노드의 계산된 스타일이 무엇일지 결정한다.

레이아웃

렌더 트리에 있는 모든 노드의 너비, 높이, 위치를 결정하는 프로세스

  • 레이아웃

    렌더 트리가 한 번 만들어지고 나면, 레이아웃이 시작된다. 처음 노드의 사이즈와 위치가 결정되는 것

  • 리플로우

    레이아웃 이후에 노드의 크기와 위치를 다시 계산하는 것

페인트

텍스트, 색깔, 경계, 그림자 및 버튼이나 이미지 같은 대체 요소를 포함하여 보든 요소의 시각적인 부분을 화면에 그리는 작업

합성

페이지가 계속해서 자원을 로드하면 리플로우가 일어날 수 있다. 리플로우는 리페인트와 재합성을 일으킬 수 있다.

DOM

💡

DOM
DOM은 HTML 문서의 계층적 구조와 정보를 표현하며, 이를 제어할 수 있는 API, 즉 프로퍼티와 메서드를 제공하는 트리 자료 구조.
→ 문서노드 (루트노드: document), 요소 노드, 어트리뷰트 노드, 텍스트 노드 ..

Untitled.png

모든 노드 객체는 Object, EventTarget, Node 인터페이스를 상속받는다.

프로토타입 체인 관점에서 보면 Input 요소 노드 객체는 HTMLInputElement, HTMLElement, Element, Node, EventTarget, Object의 프로토타입에 바인딩 되어있는 프로토타입 객체를 상속받는다.

객체Object
이벤트를 발생시키는 객체EventTarget
트리 자료구조의 노드 객체Node
브라우저가 렌더링할 수 있는 웹 문서의 요소(HTML, XML, SVG)Element
웹 문서의 요소 중에서 HTML 요소를 표현하는 객체HTMLElement

노드 타입에 상관없이 모든 객체가 공통으로 갖는 기능도 있고, 노트 타입에 따라 고유한 기능도 있다.

예를 들어, 모든 노드 객체는 공통적으로 이벤트를 발생시킬 수 있으므로 이벤트 관련 기능 (EventTarget.addEventListener 등)은 EventTarget 인터페이스가 제공한다. 모든 노드 객체는 트리 자료구조의 노드로서 공통적으로 트리 탐색 기능 (Node.parentNode, Node.childNodes, Node.previousSibling..) 이 필요하다. 이와 같은 노드 관련 기능은 Node 인터페이스가 제공한다.