브라우저의 렌더링 과정(모던 자바스크립트 Deep Dive)

min seung moon·2021년 9월 24일
0

0. 브라우저의 렌더링 과정

  • 브라우저가 HTML, CSS, 자바스크립트로 작성된 텍스트 문서 파싱(해석)하여 브라우저에 렌더링
    • 파싱(parsing)
      • 구문분석 & 어휘분석 후 문법적 의미와 구조를 반영하여 트리 구조의 자료구조인 파스트리(PARSE TREE)를 생성하는 일련의 과정
      • 파싱이 완료된 후 파스 트리를 기반으로 중간언어(intermediate code)인 바이트코드(bytecode)를 생성하고 실행
    • 렌더링(rendering)
      • HTML, CSS, JS로 작성된 문서를 파싱하여 브라우저에 시각적으로 출력하는 것

1. 요청과 응답

  • 브라우저의 핵심 기능은 필요한 리소스(HTML, CSS, JS, Image, Font 등의 정적 파일 또는 서버가 동적으로 생성한 데이터)를 서버에 요청(Request)하고 서버로부터 응답(Response)받아 브라우저에 시각적으로 렌더링하는 것
    • 렌더링에 필요한 리소스는 모두 서버에 존재하기에 필요한 리소스를 서버에 요청하고 서버가 응답한 리소르를 파싱하여 렌더링한다
    • Protocol : 통신규약
    • Domain : IP address를 가리키는 대체 명칭(사람이 좀 더 기억하기 쉽게하기 위해서 만들어졌다)
    • Port : 서버에 접근하기 위한 문(HTTP = 80, HTTPS = 443)
    • Path : 웹 서버 상의 리소스 경로(예전에는 물리적인 위치를 가리켰지만 최근에는 서버 상 추상화된 위치를 가리킴)
    • Query : 웹 서버에 제공되는 추가적인 파라미터, &로 구분하고 키/값으로 구성된다
    • Fragment : 리소스 자체의 다른 부분을 카리키는 앵커로 리소스 내에서의 북마크의 한 종류를 나타내며, 브라우저에게 그런 북마크된 지점에 위치한 컨텐츠를 보여주기 위한 방법을 제공
    • URI : 인터넷의 우편물 주소 같은 것으로, 정보 리소스를 고유하게 식별하고 위치를 지정할 수 있고 이 URI에는 두 가지 형태가 있는데 이것이 URL, URN이다
    • URL : 특정 서버의 한 리소스에 대한 구체적인 위치를 서술, 리소스가 정확히 어디에 있고 어떻게 접근할 수 있는지 분명히 알려준다
    • URN : 콘텐츠를 이루는 한 리소스에 대해, 그 리소스의 위치에 영향 받지 않는 유일무이한 이름 역할을 하며 이 위치 독립적인 URN은 리소르를 여기저기로 옮기더라도 문제 없이 동작한다

mdn : https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web

2. HTTP 1.1과 HTTP 2.0

  • HTTP(Hyper Text Transfer Protocol)는 웹에서 브라우저와 서버가 통신하기 위한 프로토콜(규약)
  • HTTP/1.1
    • 기본적으로 커넥션(connection)당 하나의 요청과 응답만 처리, 즉 여러개의 요청을 한 번에 전송할 수 없고 응답 또한 마찬가지다
    • 리소스의 동시 전송이 불가능한 구조이므로 요청할 리소스의 개수에 비례하여 응답 시간도 증가하는 단점이 있다(다중 요청/응답 불가)
  • HTTP/2
    • 커넥션당 여러개의 요청과 응답, 즉 요청/응답이 가능(동시 전송 가능)
    • 페이지 로드 속도가 약 50% 정도 빠르다

3. HTTP vs HTTPS

  • HTTP(Hyper Text Transfer Protocol)
    • 서버/클라이언트 모델을 따라 데이터를 주고 받기 위한 프로토콜(하이퍼텍스트를 교환하기 위한 통신 규약)
    • 80번 포트를 사용
    • HTTP는 암호화가 되지 않은 평문 데이터를 전송하는 프로토콜이다
  • HTTPS(Hyper Text Transfer Protocol Secure)
    • HTTP에 데이터 암호화가 추가된 프로토콜
    • 443번 포트를 사용
    • 네트워크 상에서 중간에 제3자가 정보를 볼 수 없도록 공개키 암호화를 지원
      • 공개키와 개인키는 서로를 위한 1쌍의 키이다.
      • 공개키 : 모두에게 공개가능한 키, 공개키로 암호화를 하면 개인키로만 복호화할 수 있다. -> 개인키는 나만 가지고 있으므로, 나만 볼 수 있다.
      • 개인키 : 나만 가지고 알고 있어야 하는 키, 개인키로 암호화하면 공개키로만 복호화할 수 있다. -> 공개키는 모두에게 공개되어 있으므로, 내가 인증한 정보임을 알려 신뢰성을 보장할 수 있다.

4. HTML 파싱과 DOM 생성

  • 브라우저의 요청에 의해 서버가 응답한 HTML 문서는 문자열로 이루어진 순수한 텍스트다.
  • 순수한 텍스트인 HTML 문서를 브라우저에 시각적인 픽셀로 렌더링하려면 HTML 문서를 브라우저가 이해할 수 있는 자료구조(객체)로 변환하여 메모리에 저장해야 한다
  • DOM(Document Object Model)은 응답받은 HTML문서를 파싱하여 브라우저가 이해할 수 있도록 만든 자료구조이다(바이트->문자->토큰->노드->DOM)
    • DOM은 HTML 문서를 파싱한 결과

5. CSS 파싱과 CSSOM 생성

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

6. 렌더 트리 생성

  • 렌더링 엔진은 서버로부터 응답된 HTML과 CSS를 파싱하여 각각 DOM과 SCCOM를 생성
  • DOM과 CSSOM은 렌더링을 위해 렌더 트리(render tree)로 결합
  • 렌더트리는 렌더링을 위한 트리 구조의 자료구조이다, 따라서 브라우저 화면에 렌더링되지 않는 노드(예:meta, script 등)와 CSS에 의해 비표시(예: display : none)되는 노드들을 포함하지 않는다.
  • 렌더트리는 브라우저 화면에 렌더링 되는 노드만으로 구성

  • 브라우저의 렌더링 과정은 반복해서 실행될 수 있다
    • 자바스크립트에 의한 노드 추가 또는 삭제
    • 브라우저 창의 리사이징에 의한 뷰포트 크기 변경
    • HTML 요소의 레이아웃(위치, 크기) 변경을 발생시키는 width, height, margin, padding, border, display, position, top, right, bottom, left 등의 스타일 변경
  • 레이아웃 계산과 페인팅을 다시 실행하는 리렌더링은 비용이 많이 드는, 즉 성능에 악영향을 주는 작업이다

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

  • DOM은 HTML 문서를 파싱한 결과물로, HTML 문서의 구조와 정보뿐만 아니라 HTML 요소와 스타일등을 변경할 수 있는 프로그래밍 인터페이스로서 DOM API를 제공

  • 자바스크릅트 코드에서 DOM API를 사용하면 이미 생성된 DOM을 동적으로 조작 할 수 있다

  • CSS와 마찬가지로 자바스크립트 파일을 로드하는 script 태그나 자바스크립트 코드를 콘텐츠로 담은 script 태그를 만나면 DOM 생성을 일시 중단한다

  • 자바스크립트 코드를 파싱하기 위해 자바스크립트 엔진에 제어권을 넘긴다

  • 자바스크립트 파싱과 실행이 종료되면 렌더링 엔진으로 다시 제어권을 넘겨 HTML 파싱이 중단된 지점부터 다시 HTML 파싱을 시작하여 DOM 생성을 재개한다

  • 자바스크립트 파싱과 실행은 브라우저의 렌더링 엔진이 아닌 자바스크립트 엔진이 처리

  • 자바스크립트 엔진은 자바스크립트 코드를 파싱하여 CPU가 이해할 수 있는 저수준 언어로 변환하고 실행

  • HTML이 DOM, CSS가 CSSOM을 생성하듯이 자바스크립트는 AST(Abstract Syntax Tree) 추상적 구문 트리를 생성

  • AST 기반으로 인터프리터가 실행 할 수 있는 중간코드인 바이트 코드를 생성하여 실행

  • 토크나이징

    • 단순한 문자열인 자바스크립트 소스코드를 어휘분석(lexical analysis)하여 문법적 의미를 갖는 코드의 최소 단위인 토큰(Token)들로 분해
    • 렉싱(lexing)이라고도 부르지만 토크나이징과 미묘한 차이가 있다
  • 파싱

    • 토큰들의 집합을 구문분석(syntactic analysis)하여 AST(Abstract Syntax Tree) 추상적 구문 트리를 생성한다
    • AST는 토큰에 문법적 의미와 구조를 반영한 트리 구조의 자료구조
    • AST를 사용하면 TS, Babel, Prettier 같은 트랜스파일러를 구현할 수도 있다
  • 바이트코드 생성과 실행

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

8. 리플로우와 리페인트

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

9. 자바스크립트 파싱에 의한 HTML 파싱 중단

  • 브라우저는 동기적(synchronous)으로, 즉 위에서 아래 방향으로 순차적으로 HTML, CSS, JS를 파싱하고 실행
  • script 태그의 위치에 따라 HTML 파싱이 블로킹되어 DOM 생성이 지연될 수 있다
  • script 태그의 위치는 중요한 의미를 갖는다
  • body 요소의 가장 아래에 자바스크립트를 위치시키는 것은 가장 좋은 아이디어다
    • DOM이 완성되지 않는 상태에서 JS가 DOM을 조작하면 에러가 발생할 수 있다
    • JS 로딩/파싱/실행으로 인해 HTML 요소들의 렌더링에 지장받는 일이 발생하지 않아 페이지 로딩 시간이 단축된다
profile
아직까지는 코린이!

0개의 댓글