브라우저 렌더링 과정 요약(2)

pds·2023년 3월 27일
0

TIL

목록 보기
39/60

브라우저 렌더링 과정 요약했던걸 좀 더 과정 그 자체를 파악하는 것에 중점을 둬 한번 더 요약해보았다.


브라우저의 렌더링이 시작되는 것은 위 아키텍쳐의 11번으로부터 시작된다.


1. 불러올 파일을 서버에 요청한다.

주소창에 직접 주소를 입력하던가 클릭을 통해 웹 페이지로 사용자가 접근하면 클라이언트에서 해당되는 파일을 서버에 요청해 받아오게 된다.

사용자가 요청한 URI를 DNS를 통해 적절한 IP주소를 찾아 해당 IP를 가진 서버에 GET요청을 보내는 것이다.


2. 응답으로 얻은 HTML 데이터를 파싱한다.

브라우저가 서버에 있는 HTML파일을 얻어 Byte Stream(2진수) 형태로 응답받는다.

응답된 바이트 형태의 HTML문서를 응답 헤더의 charset에 명시된 대로 디코딩하여 문자열로 변환하고

content-type에 명시된 text/html MIMTYPE을 보고 HTML 파일로 인식하고 파싱한다.

문자열로 변환 된 이후의 상세한 파싱 과정

(1) 토큰: 변환된 문자열을 토큰화해 HTML에 사용되는 최소 단위인 `Element`, `Attribute` 등의 구성요소로 분해한다.
(2) 노드: 변환된 토큰을 DOM에서 사용될 객체인 Node로 변환한다.

3. DOM Tree를 생성한다.

변환된 노드들은 트리 자료구조인 DOM을 형성하게 된다.

HTML 마크업에 정의된 여러 태그 간의 계층 관계를 해석해서 트리 구조로 연결이 된다.


4. CSS 마크업을 바탕으로 CSSOM 트리를 생성

HTML파싱 중 css링크를 만나면 CSS파일을 가져오고 파싱한다.

HTML처럼 CSS도 서버로부터 바이트 데이터로 얻어와 파싱하고 CSS Object Model을 형성한다.

결국 HTML을 파싱하던 도중 외부 CSS 파일을 다운로드하고 파싱하는 형태일텐데 이들은 브라우저에서 병렬처리된다.


5. Render Tree를 형성

렌더링 엔진이 문서의 처음부터 끝까지 모두 해석하고 DOMCSSOM이 완성되면 이 둘을 결합해 render tree를 생성한다.

render tree를 사용해 브라우저에 보이는 레이아웃(Layout Operation)을 계산하고 페인팅(Painting Operation)한다.

render tree에는 최종적으로 화면에 보여질 항목에 대한 것들로만 형성된다.


6. Layout Operation

render tree를 기반으로 HTML 요소들의 위치와 크기를 계산해 적절한 위치에 구성한다.


7. Painting Operation

계산된 HTML요소들의 레이아웃을 바탕으로 브라우저 화면에 픽셀을 채워넣는 작업이다.

페인팅 작업까지 모두 완료되면 실제로 브라우저 화면에 렌더링이 된다!



자바스크립트는 브라우저 렌더링 과정에서 어떻게 동작할까?

렌더링 엔진이 HTML 노드를 통해 DOM을 형성하던 도중 script태그를 만나면 DOM 생성을 중지한다.

script 태그에 정의된 자바스크립트 파일을 서버에 요청하여 로드하고

해당 자바스크립트 코드를 파싱하기 위해 자바스크립트 엔진에게 제어권이 넘어가며

모두 파싱해 실행이 끝나면 렌더링 엔진으로 다시 제어권이 넘어간다.

Blocking되는 이유

병렬적으로 처리하다가 렌더링 작업을 방해할 수 있다.

자바스크립트에서 DOM을 변경하거나 스타일을 변경할 수 있고 이는 DOM, CSSDOM을 업데이트하는데 동시에 이 작업들이 수행된다면 뭘 먼저 읽어서 처리해야되는지 모르는 상황이 발생한다.


async

HTML파싱과 외부 자바스크립트 파일 로드가 비동기적으로 동시에 진행된다.

자바스크립트 파일 로드가 끝나면 자바스크립트 파싱이 진행되며 이 때 HTML 파싱이 중단된다.

여러 태그에 async를 지정하면 스크립트 태그 지정 순서와 상관없이 먼저 로드된 자바스크립트 파일부터 실행하기 때문에 주의해야 한다.


defer

HTML파싱과 외부 자바스크립트 파일 로드가 비동기적으로 동시에 진행되고

자바스크립트의 파싱과 실행은 DOM이 형성된 직후 진행된다.

profile
강해지고 싶은 주니어 프론트엔드 개발자

0개의 댓글