브라우저의 동작 원리에 대해서 웹 프론트엔드의 관점에서 알아본다.
배경 상식
- 웹 브라우저는 동기적으로 html,css,js를 해석하여 내용을 화면에 보여주는 소프트웨어이다.
- 렌더링 엔진은 웹 서버로부터 응답받은 자원을 화면에 나타내는 역할을 한다.
- script 태그는 html파싱을 중단시킨다. 다만, style, link 태그는 DOM을 변경할 수 없기 때문에 html파서를 중단시키지 않는다. 다만, scirpt태그의 실행은 멈춘다.
- 페인팅과 컴포지션을 분리하여 브라우저의 성능을 최적화한다. ex) left 값을 수정하면 painting 이 다시 일어나지만, translate 속성을 사용하면 composition만 일어난다. (레이아웃 자체에는 변화가 없기 때문.) 특히, will-change 속성을 사용하면 브라우저가 미리 레이어를 분리하여 성능 최적화를 할 수 있다.
렌더링 엔진
렌저링 엔진은 서버로부터 응답바은 HTML문서를 얻는 것으로 시작한다. 렌더링 엔진은 HTML문서를 파싱하여 DOM 트리를 구축한다. (DOM 생성) 외부 CSS파일과, HTML에 포함된 스타일 요소를 파싱한다. (CSSOM 생성) DOM 트리와 2번의 결과물을 합쳐 렌더 트리를 구축한다. (렌더 트리 생성) 렌더 트리 각 노드에 대해 화면 상에서 배치할 곳을 결정한다. (레이아웃 - 리플로우) (뷰포트 내 상대적 위치, 사이즈) 렌더 트리의 각 노드를 그린다 (화면에 표시하는게 아닌 이미지를 준비한다.). (페인팅) (px값으로 화면에 나타낸다.) 준비된 레이어를 브라우저 위에 순서대로 표시한다. (컴포지션)(z-index 순으로)
자바스크립트
html파서는 script태그를 만나면, dom 생성 프로세스를 중단하고 자바스크립트 엔진으로 권한을 넘긴다. javascript의 실행이 완료되면 다시 html파서로 제어 권한을 넘겨서 dom 생성을 재개한다. 따라서 script 태그는 가급적 body태그의 최하위 (렌더링이 완료된 이후에 실행되도록)에 위치하는 것이 좋다. 다만, async (다운로드 하는동안에도 html 파싱), defer (html파싱이 완료된 이후 실행)속성을 적절히 사용할 수 있다.