[Modern JS Deep Dive] CH38-브라우저의 렌더링 과정

Boo Sung Jun·2022년 8월 31일
0

JavaScript

목록 보기
26/27
post-thumbnail

Modern JavaScript Deep Dive 스터디 - CH38 브라우저의 렌더링 과정

참고 자료:
⟪모던 자바스크립트 Deep Dive⟫(이웅모 지음,위키북스, 2020)
⟪면접을 위한 CS 전공지식 노트⟫(주홍철 지음,길벗, 2022)




0. 클라이언트 사이드 자바스크립트의 실행

  • 브라우저는 HTML, CSS, JS로 작성된 텍스트 문서를 파싱(해석)하여 브라우저에 렌더링한다.

    파싱: 프로그래밍 언어의 문법에 맞게 작성된 텍스트 문서를 읽어 들여, 실행하기 위해 텍스트 문서의 문자열 토큰으로 분해하고, 토큰에 문법적 의미와 구조를 반영하여 트리 구조의 자료구조인 파스 트리를 생성하는 과정

    렌더링: HTML, CSS, JS로 작성된 문서를 파싱하여 브라우저에 시각적으로 출력하는 것

1. 요청과 응답

  • 브라우저의 핵심 기능은 필요한 리소스(HTML, CSS, 자바스크립트, 이미지, 폰트 등의 정적 파일 또는 서버가 동적으로 생성한 데이터)를 서버에 요청하고 서버로부터 응답받아 브라우저에 시각적으로 렌더링하는 것이다
  • 서버에 요청을 전송하기 위해 브라우저는 주소창을 제공한다. 주소창의 URL의 호스트이름이 DNS를 통해 IP 주소로 변환되고 이 IP 주소를 갖는 서버에게 요청을 전송한다.
    url

2. HTTP

  • HTTP(Hyper Text Transfer Protocol): 웹에서 브라우저와 서버가 통신하기 위한 규약

□ HTTP/1.0

  • 하나의 TCP 연결 당 하나의 요청 처리 -> RTT 증가

    RTT: 패킷이 목적지까지 왕복하는데 걸리는 시간

  • RTT 증가를 해결하기 위해 '이미지 스플리팅', '코드 압축', '이미지 Base64' 인코딩 등의 기술 사용

□ HTTP/1.1

  • 매번 TCP 연결을 할 필요 없이, 한 번의 연결 후 여러 개의 파일 송수신 가능(keep-alive)

  • HOL Blocking 으로 요청할 리소스 개수에 비례하여 대기 시간이 길어지는 단점이 있다.

    HOL Blocking(Head Of Link Blocking): 네트워크에서 큐에 들어있는 첫 번째 패킷의 사이즈가 커서 나머지 패킷들의 처리가 지연되는 현상
    hol blocking

  • 헤더에 쿠키 등 많은 메타데이터가 들어있어, 무거운 헤더 구조를 가지는 단점이 있다.

□ HTTP/2

  • 지연 시간과 응답 시간을 개선했다.

  • 멀티플렉싱, 헤더 압축, 서버 푸시, 요청의 우선순위 처리를 지원한다.

    멀티플렉싱:

    • 여러 개의 stream을 사용하여 송수신하는 것. 한 스트림의 패킷이 손상되어도 나머지 스트림에는 영향 없음.
    • 병렬적인 스트림 구조에 데이터들을 프레임으로 조각내어 전송 -> HOL Blocking 방지

    헤더 압축

    • 허프만 코딩(huffman coding) 알고리즘을 이용하여 헤더 압축하여 크기 줄임
    • 허프만 코딩 알고리즘: 문자열을 문자 단위로 쪼개고, 빈도 수가 많은 문자는 비트 수를 적게, 빈도 수가 적은 문자는 비트 수를 많이 사용하는 알고리즘

    서버 푸시

    • 클라이언트 요청 없이 서버가 리소스를 푸시하는 것
    • html 파일을 읽으면서, 여기에 필요한 css 파일을 서버가 푸시하여 보내줄 수 있음

    □ HTTP/3

  • TCP 연결이 아닌, QUIC 계층 위에서 UDP를 통해 통신한다.

  • QUIC는 FEC(Forword Error Correction) 메커니즘을 통해 에러를 검출하고 수정하는 방식으로 낮은 패킷 손실률을 가진다.

  • 3-Way-Handshake 과정이 없으므로 초기 연결 설정 시 지연 시간이 감소한다.

  • HOL Blocking 문제를 더 개선하였다.

    □ HTTPS

    • HTTP에 SSL/TLS 계층을 넣어 보안을 강화한 프로토콜
    • SSL(Secure Socket Layer)보다 TLS(Transport Layer Security Protocol)가 최신 프로토콜이다
    • 클라이언트와 서버가 통신 할 때, 메시지를 가로채거나 변조하지 못하도록 방지한다.

    TLS: 보안 세션을 기반으로 데이터를 암호화하며, 보안 세션이 만들어질 때 인증 메커니즘, 키 교환 암호화 알고리즘, _해싱 알고리즘이 사용된다.
    **
    보안 세션_**: 보안이 시작되고 끝날 때까지 유지되는 세션. SSL/TLS는 핸드셰이크를 통해 보안 세션을 생성하고 상태 정보를 공유

    인증 메커니즘: CA(Certificate Authorities)에서 발급한 인증서를 기반으로 이루어지는 방식. 서버와 클라이언트가 통신 할 때, 공개키를 클라이언트에 제공.
    암호화 알고리즘: 디피-헬만 키 교환 암호화 알고리즘(Diffie-Hellman key exchange)에 기반한 알고리즘. ECDHE와 DHE 방식이 있다. 클라이언트와 서버 모두 개인키와 공개키를 생성하고 서로에게 보낸 뒤, 공개키와 개인키를 결합하는 방식으로 암호화
    해싱 알고리즘: 데이터를 추정하기 힘들도록, 더 작고 섞여있는 조각으로 만드는 알고리즘. SHA-256 알고리즘이 있다.

    • HTTPS를 이용하면 SEO 순위가 높아진다.

      구글은 사이트 내의 모든 요소가 동일하다면 HTTPS 서비스의 SEO 순위가 높을 것이라고 공식적으로 밝힌적이 있다.

3. HTML 파싱과 DOM 생성

  • HTML 문서를 브라우저가 렌더링하기 위해서는 HTML 문서를 브라우저가 이해할 수 있는 자료구조(객체)로 변환하여 메모리에 저장해야 한다
  • DOM(Document Object Model)은 응답받은 HTML문서를 파싱하여, 브라우저가 이해할 수 있도록 만든 자료구조이다

4. CSS 파싱과 CSSOM 생성

  • 렌더링 엔진은 HTML을 처음부터 한줄씩 순차적으로 파싱하여 DOM을 생성해 나간다
  • 렌더링 엔진은 DOM을 생성해 나가다가 CSS를 로드하는 link태그나 style태그를 만나면 DOM 생성을 일시 중단한다
  • CSSOM(CSS Object Model)은 link 태그의 href 속성에 지정된 CSS 파일을 서버에 요청하여 로드한 파일이나 style 태그 내의 CSS를 HTML과 동일한 파싱 과정(바이트 -> 문자 -> 토큰 -> 노드 -> CSSOM)을 거치며 해석되어 만들어진 결과물이다
  • CSS 파싱이 완료되면 중단된 HTML 파싱을 중단 지점부터 다시 파싱하기 시작하여 DOM 생성을 재개한다

5. 렌더 트리 생성

  • 렌더 트리는 렌더링을 위한 트리 구조의 자료구조이다.
  • 브라우저 화면에 렌더링되지 않는 노드(예: meta 태그, script 태그 등)와 CSS에 의해 비표시(ex. display: none)되는 노드들은 포함하지 않는다. -> 브라우저 화면에 렌더링 되는 노드만으로 구성된다.
  • 생성된 DOM과 CSSOM은 렌더링을 위해 렌더 트리로 결합된다.
  • 브라우저의 렌더링 과정은 반복해서 실행될 수 있다
  • 레이아웃 계산과 페인팅을 다시 실행하는 리렌더링은 비용이 많이 들어, 성능에 악영향을 주는 작업이다

6. 자바스크립트 파싱과 실행

  • DOM은 HTML 요소와 스타일등을 변경할 수 있는 프로그래밍 인터페이스로서의 DOM API도 제공한다.
  • 자바스크릅트 코드에서 DOM API를 사용하면 이미 생성된 DOM을 동적으로 조작 할 수 있다
  • CSS와 마찬가지로 자바스크립트 파일을 로드하는 script 태그나 자바스크립트 코드를 콘텐츠로 담은 script 태그를 만나면 DOM 생성을 일시 중단한다
  • 자바스크립트 엔진에 제어권을 넘기고 자바스크립트 코드를 파싱하고 실행한다.
  • 자바스크립트 파싱과 실행이 종료되면 렌더링 엔진으로 다시 제어권을 넘겨 HTML 파싱이 중단된 지점부터 다시 HTML 파싱을 시작하여 DOM 생성을 재개한다
  • 자바스크립트 파싱과 실행은 브라우저의 렌더링 엔진이 아닌 자바스크립트 엔진이 처리한다.
  • 자바스크립트 엔진은 자바스크립트 코드를 파싱하여 CPU가 이해할 수 있는 low level language로 변환하고 실행한다.
  • HTML이 DOM, CSS가 CSSOM을 생성하듯, 자바스크립트는 AST(Abstract Syntax Tree)를 생성한다.
  • AST 기반으로 인터프리터가 실행 할 수 있는 중간코드인 바이트 코드를 생성하여 실행한다.

javascript compile

□ Tokenizing

  • 소스코드를 어휘분석(lexical analysis)하여 문법적 의미를 갖는 코드의 최소 단위인 토큰(Token)들로 분해하는 것이다.

□ Parsing

  • 토큰들의 집합을 구문분석(syntactic analysis)하여 AST(Abstract Syntax Tree) 추상적 구문 트리를 생성한다
  • AST를 사용하면 TS, Babel, Prettier 같은 트랜스파일러를 구현할 수도 있다

□ Bytecode

  • 파싱의 결과물로서 생성된 AST는 인터프리터가 실행할 수 있는 중간코드인 바이트코드로 변환되고 인터프리터에 의해 실행한다.

7. 리플로우(reflow)와 리페인트(repaint)

  • DOM API가 사용하어 DOM이나 CSSOM이 변경되면, 다시 렌더 트리로 결합되고 변경된 렌더 트리를 기반으로 레이아웃과 페인트 과정을 거쳐 브라우저의 화면에 다시 렌더링된다. 이것이 이를 리플로우, 리페인트 과정이다.
    • 리플로우: 레이아웃 계산을 다시 하는 것. 노드 추가/삭제, 요소의 크기/위치 변경, 윈도우 리사이징 등 레이아웃에 영향을 주는 변경이 발생한 경우 실행
    • 리페인트: 재결합된 렌더 트리를 기반으로 다시 페인트를 하는 것

8. script 태그의 async/defer 어트리뷰트

  • script 태그의 위치에 따라 자바스크립트 파싱에 의한 DOM 생성이 중단되어 발생하는 문제를 해결하기 위해, HTML5부터 script 태그에 async와 defer 어트리뷰트가 추가되었다.
  • async와 defer 어트리뷰트는 src 어트리뷰트를 통해 외부 자바스크립트 파일을 로드하는 경우에만 사용할 수 있다. 즉, src 어트리뷰트가 없는 인라인 자바스크립트에는 사용할 수 없다.
<script async src="extern.js"></script>
<script defer src="extern.js"></script>
  • async와 defer 어트리뷰트를 사용하면 HTML 파싱과 외부 자바스크립트 파일의 로드가 비동기적으로 동시에 진행되지만, 자바스크립트의 실행 시점에 차이가 있다.
  • async 어트리뷰트
    • HTML 파싱과 외부 자바스크립트 파일의 로드가 비동기적으로 동시에 진행된다.
    • 단, 자바스크립트의 파싱과 실행은 자바스크립트 파일의 로드가 완료된 직후 진행되며, 이때 HTML 파싱이 중단된다.
    • script 태그의 순서와는 상관없이 로드가 완료된 자바스크립트부터 먼저 실행되므로 순서가 보장되지 않는다.
  • defer 어트리뷰트
    • sync 어트리뷰트와 마찬가지로 HTML 파싱과 외부 자바스크립트 파일의 로드가 비동기적으로 동시에 진행된다
    • 단, 자바스크립트의 파싱과 실행은 HTML 파싱이 완료된 직후, 즉 DOM 생성이 완료된 직후 진행된다
    • DOM 생성이 완료된 이후 실행되어야 할 자바스크립트에 유용하다.

0개의 댓글