내 코드가 화면에 그려지는 과정 - 브라우저 렌더링

ureal·2023년 8월 12일
7

요약

  • 효율적인 코드를 작성하기 위해서는 브라우저가 우리가 작성한 코드를 어떤 순서대로 어떻게 읽어주는지, 즉 렌더링 해주는지를 파악해야 합니다.

  • 각 브라우저마다 다른 브라우저 렌더링 엔진을 사용해 웹페이지를 그립니다.
    ex) 크롬 - 블링크

  • 브라우저 렌더링 순서는 다음과 같습니다. ⭐️
    HTMl 파싱(DOM 트리 생성) -> CSS 파싱(CSSOM) & JS 파싱(JS 렌더링 엔진) -> 렌더트리 생성 -> 레이아웃(리플로우) -> 페인트(리페인트) -> Composite

  • 파싱(Parsing)이란 브라우저가 코드를 이해하고 사용하기 쉬운 구조로 변환하는 것을 말합니다.

  • DOM(Document Object Model) 트리는 HTML 페이지를 구조화해서 계층으로 표현한 개념입니다. 이게 바로 파싱을 통해 브라우저가 얻은 결과물입니다.

  • 자바스크립트 코드에서는 DOM API를 사용해 DOM이나 CSSOM을 변경할 수 있습니다. ⭐️


자세히

🤔 브라우저 렌더링 과정을 알아야하는 이유?

  1. 내가 쓴 코드가 어떻게 화면에 그려지는지 동작원리와 과정이 궁금하지 않으신가요?!
  2. 성능최적화에 있어서 필수지식입니다.
  3. 면접 단골 질문입니다! 알아두면 좋겠죠?!

⚙️ 브라우저 렌더링 엔진

브라우저에는 크롬,파이어폭스,사파리 등 여러 가지가 있습니다. 이 브라우저들은 사용자가 요청한 HTML페이지,이미지 등을 서버에 요청해 보여줍니다. 브라우저가 화면에 나타는 요소를 그리는 것을 브라우저 렌더링 이라고 합니다. 이 렌더링을 하는 것이 렌더링엔진의 역할입니다. 각 브라우저마다 다른 렌더링 엔진을 사용합니다.

  • 파이어폭스 - 게코(Gecko)
  • 사파리 - 웹킷(Webkit)
  • 크롬 - 블링크(Blink)

🔎 브라우저 렌더링 과정

1. HTML 파싱

<!DOCTYPE html>
<html lang="ko">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <ul>
            <li id="apple">Apple</li>
            <li id="banana">Banana</li>
            <li id="orange">Orange</li>
        </ul>
        <script src="app.js"></script>
    </body>
</html>

브라우저 렌더링 엔진은 다음 그림과 같은 과정을 통해 위와같은 코드를 파싱합니다.
브라우저가 이해할 수 있는 자료구조인 DOM으로 바꿔주는 과정입니다.

파싱과정을 순차적으로 살펴보자면 HTML 파싱 중 <link> 또는 <script> 태그를 만나게 되면 렌더링엔진은 DOM 트리 생성을 중단하고 CSS파싱, JS파싱을 모두 진행한 후에 DOM트리를 마저 생성합니다.


2. CSS 파싱

body {
	font-size: 18px;
}

ul {
	list-style-type: none;
}

렌더링 엔진은 CSS 파싱 또한 HTML 파싱과 동일한 과정을 통해 CSSOM을 생성합니다. 이때 font-size ,list-style-type 속성이 상속되는것처럼 상속 관계까지 반영되어 CSSOM이 생성됩니다.



3. 렌더 트리

HTML을 파싱해서 얻은 DOM과 CSS를 파싱해서 얻은 CSSOM을 결합하여 렌더트리를 생성합니다. 렌더트리는 실제 화면에 표현되는 노드들로만 구성됩니다. 화면에 표현되는 노드 란 단순히 시각적으로 보이냐 가 아닌 공간을 차지하고 있느냐 입니다.

  • <head> 요소와 같은 비시각적 DOM 요소는 렌더 트리에 추가되지 않습니다.
  • display : none; 속성은 아예 사라지는 것이므로 렌더트리에서 제외됩니다.
  • visibility : hidden; 속성은 자리는 화면상에서 공간을 차지하는 속성이기 때문에 렌더트리에 반영됩니다.

4. 레이아웃 & 페인트 -> Composite

앞서 생성된 렌더트리를 기반으로 각 노드들이 뷰포트 내에서 어떻게 배치될건지 결정되는 과정이 레이아웃입니다. 이 때 모든 상대적인 값 rem,vw 들이 절대단위인 px로 변환됩니다.

렌더트리를 기반으로 각 노드를 화면의 실제픽셀로 그리는 과정페인트입니다. 요소를 렌더링 하는 순서, 페이지를 여러개의 레이어로 나눈 후 그 위에 그려지는 색,텍스트,보더 등 시각적인 내용기록됩니다.

페인트단계에서 레이어를 여러개로 나누는 이유는 리페인트가 발생했을때 모든 레이어가 아닌 수정해야하는 레이어만 페인트하면 되기 때문입니다.

Composite은 화면에 표시하기 위해 페이지에서 paint에서 나누어진 레이어들을 합치는 과정입니다.


5. JS 파싱 (blocking)

앞서 HTML 파싱 단계에서 살펴 보았듯 렌더링 엔진은 <script> 태그를 만나게 되면 DOM 트리 생성을 중단(blocking)하고 JS 파싱을 진행합니다. CSS 파싱과 다른점은 JS파싱은 렌더링 엔진이 아닌 자바스크립트 엔진이 처리한다는 점입니다. 렌더링 엔진으로부터 제어권을 넘겨받아 파싱을 시작합니다. DOM 과 CSSOM 처럼 JS파싱을 통해 AST(추상적 구문 트리)를 생성합니다.

자바스크립트 코드에서는 DOM이나 CSSOM을 변경하는 DOM API를 사용할 수 있는데 이 때 DOM이나 CSSOM 생성이 완료되어있지 않은 경우 에러가 발생합니다.

<!DOCTYPE html>
<html lang="ko">
    <head>
        <meta charset="UTF-8">
         🔒--- <link rel="stylesheet" href="style.css"> --- 🔒
         🔒--- <script src="app.js"></script> --- 🔒
    </head>
    <body>
        <ul>
            <li id="apple">Apple</li>
            <li id="banana">Banana</li>
            <li id="orange">Orange</li>
        </ul>
    </body>
</html>

위의 코드의 경우 HTML 파싱이 🔒 --- 🔒 부분에서 중단됩니다. 만약 app.js 에 DOM API를 이용해 DOM 요소를 변경하는 코드가 있다면 에러가 발생합니다. DOM 생성완료가 되지 않았기때문입니다.

때문에 보편적으로 <script><body> 맨 밑에 적어주곤 합니다. 이렇게 하면 페이지로딩 시간 또한 단축됩니다. 물론 페이지가 js파일에 의존적이라면 완전하지 않은 페이지를 로딩하게 될 수도 있습니다.

<script> 태그의 async/defer 어트리뷰트를 사용하는 방법도 있습니다.


6. 리플로우 & 리페인트

만약 DOM API를 사용해 DOM이나 CCSOM을 변경했다면 이때 변경된 DOM과 CSSOM은 다시 렌더 트리로 결합되고 변경된 렌더 트리를 기반으로 레이아웃과 페인트 과정을 거쳐 브라우저의 화면에 다시 렌더링합니다. 이를 리플로우, 리페인트라합니다.

리플로우,리페인트가 발생하는 리렌더링은 성능에 악영향을 주는 작업입니다. 리플로우,리페인트를 줄이는 코드를 작성함으로써 성능최적화를 할 수 있습니다.



마무리

웹개발에 있어 필수 상식이라고 할 수 있는 브라우저 렌더링에 대해 알아보며 처음 DOM API를 사용할때 마주쳤던 에러들의 원인들을 알 수 있었습니다. 동작원리를 알아야 효율적이고 구조적인 코드작성이 가능하다는 점도 배웠습니다. 성능최적화를 위해 리렌더링을 최소화 해야하는데 구체적으로 어떤 부분을 유의하면 좋을지에 대한 공부도 필요할것같습니다!

웹 개발에 앞서 브라우저가 어떤과정을 통해 코드를 시각적 웹 페이지로 그려내는지를 통해 큰 숲을 보았으니 이제 어느곳에 어떤 나무를 심으면 될지 고민해보아야할 차례이지 않을까요?


ref.
예제코드 및 이미지 출처 - 자바스크립트 딥 다이브
브라우저는 어떻게 화면을 렌더링할까?
웹개발 필수개념! DOM이 뭔가요? (+ Web API)
[JavaScript] 브라우저 렌더링 과정(원리)
HTML 문서에서 DOM으로의 여정

profile
프리린 프프리린 프린이

0개의 댓글