브라우저 렌더링 과정

Haz·2022년 11월 16일
0

개발여행기

목록 보기
2/32
post-thumbnail

드디어 이직을 작심했다.
이력서에 이 회사에서 했던 일들을 추가하고, 시험 삼아 몇 군데 회사에 이력서를 넣었다.
세 곳 중 두 곳에서 연락이 왔고 한 회사에서 전화 인터뷰를 진행했다.
경험 삼아 진행한 면접이었기에 별다른 준비 없이 나를 알아보자는 마음으로 임했다.
생각보다 내가 어버버거리고 있어 당황스러웠다.
분명 스터디에서 공부했던 것들인데 질문을 받으니 기억이 안났다.
그래서 하나씩 정리하며 다시 내 것으로 만들고자 면접 질문 중 중요한 부분들을 기록한다.


브라우저 렌더링 과정


첫 브라우저 관련 질문이었다. "자바스크립트 딥다이브"라는 책을 읽으며 분명 공부했는데 생각 정리가 안되서 자꾸 더듬게 되었다. 하나하나 되짚어보자.

추가 참고자료: https://ui.toast.com/fe-guide/ko_PERFORMANCE

1. HTML 파싱

URL을 입력하고 사용자가 엔터를 치면 그때부터 브라우저 렌더링이 시작된다.
우선 HTML 파일을 위에서부터 아래로, 순서대로 파싱하게 된다.
그 과정에서 CSS 파일도 head 태그에 포함되어있으니 함께 파싱하여 DOM Tree와 CSSOM Tree를 구성한다.

2. 스타일

파싱한 DOM 트리와 CSSOM 트리를 엮어 마치 연리지 나무처럼 Render Tree를 만든다.
이 렌더 트리가 후속 단계에서 실질적으로 화면에 나타나게 된다.
즉, HTML Element에 어떤 스타일이 부여될 지 연동되는 과정이다.
이 과정에서 display:none 인 element는 렌더 트리에서 삭제된다.

3. Layout

그려낸 렌더 트리의 루트부터 탐색하면서 화면에 배치할 element들의 위치와 크기를 계산한다.
"%" 단위를 사용했다면 이 과정에서 "px"로 계산하여 치환한다.

4. Paint

드디어 렌더 트리가 화면에 그려지기 시작하는 단계다.
실제 픽셀로 변환되어 화면에 여러 레이어로 렌더 트리가 구성된다.
그려야하는 요소가 많을수록 시간이 소요되며, 스타일이 복잡할수록 더 오래 걸리게 된다.

5. Compose

페인트 단계에서 여러 레이어로 그려냈던 픽셀들이 합성되어 우리가 원하는 화면이 짠하고 그려진다.




Defer & Async

이 질문은 인터뷰 중 렌더링 과정을 설명하다가

보통 Script 파일을 body 태그 맨 하위에 삽입하여 불러온다.

라고 대답한 것에서 시작됐다.
일반적으로 스크립트 태그를 저렇게 삽입하는 이유는 세 가지다.

1. HTML을 읽는 과정에 스크립트를 만나면 중단 시점이 생기고 그만큼 Display에 표시되는 것이 지연된다.
2. DOM 트리가 생성되기전에 자바스크립트가 생성되지도 않은 DOM의 조작을 시도할 수 있다.
3. 화면 출력과 직접적인 영향이 없는 경우가 많다.

첫번째 이유는 사용자들에게 서비스 성능이 떨어지는 것처럼 보이게 하고, 두번째 이유는 당연히 에러가 발생하기 때문에 서비스가 중단되기 때문이다. 마지막 이유는 요새 자바스크립트 프레임워크들이 프론트 개발에 주로 쓰이기 때문에 아니라고 생각할 수도 있다. 그러나 프레임워크를 사용하면 내부적으로 별개의 렌더링 과정을 거치기 때문에 잠깐 이상하다는 생각을 저멀리로 날리도록 하자.

그런데 반드시 script 태그가 head 태그에 들어가야한다면, 그와 동시에 위와 같은 문제를 막고 싶다면 어떻게 해야할까?

방법은 두 가지다.

1. Async 프로퍼티를 script 태그에 추가한다.
2. Defer 프로퍼티를 script 태그에 추가한다.



Async


Async 프로퍼티를 추가하게 되면 HTML 파싱 중간에 script 파일을 파싱하는 것이 아니라,
script 태그를 만나는 순간 동시에 파싱을 진행한다.
그러다가 script 태그가 파싱이 끝나면 먼저 script 파일을 실행하고 그 후에 HTML 파일을 마저 파싱한다.
즉, async 속성은 html 파일의 길이가 script 파일보다 짧다면 문제를 유발하지 않으면서 동시에 브라우저에게 작업을 진행하도록 할 수 있다.
그러나 html 파일이 script 파일보다 길다면? 1번 문제가 발생하게 된다.
그럼 어떻게 해야할까?



Defer


이럴 경우, Defer 프로퍼티를 추가하면 된다.
Defer 프로퍼티를 추가하면 HTML 파싱 중간에 script 파일을 만나게 되면 동시에 파싱을 진행하는 것은 async와 동일하지만, script 파일의 실행을 HTML 파일 파싱이 완료된 이후에 하게 된다.



위 두 가지 속성을 적절하게 사용한다면 사용자들에게 쾌적한 서비스 환경을 제공할 수 있겠지만,
두 속성을 추가한 스크립트 태그를 너무 과하게 사용하게 된다면 당연히 브라우저가 병렬 처리를 해야할 작업이 늘게 되니 자칫 과부하가 걸릴 수 있다.
안 그래도 브라우저는 CPU를 꽤 먹는 편이니 파일 분리는 잘해보도록 하자.











오늘의 궁금한 점

그렇다면 자바스크립트 프레임워크는 어떤 렌더링 과정을 거치게 될까?
결국 브라우저에 그려주려면 html, css, js 파일로 컴파일 되어야 인식할 수 있을텐데
자바스크립트 프레임워크의 트렌드는 이 모든 걸 자바스크립트 파일 안에서 하나로 아우르는 것이다.
과연 어떻게 내부 작동을 하게 되어있을까...?

profile
나도 재밌고, 남들도 재밌는 서비스 만들어보고 싶다😎

0개의 댓글