Front-end

HTML 파싱과 렌더링

madison 2022. 7. 3. 20:13

Parse

파싱이란 프로그램이 런타임 환경에서 실제로 실행될 수 있는 포맷으로 분석하고 변환하는 것입니다. 브라우저 내부의 자바스크립트 엔진이 이에 해당합니다. 

브라우저는 HTML을 DOM tree로 파싱합니다. HTML 파싱은 tokenization과 트리 구조를 포함합니다. HTML 토큰은 names, values와 같은 태그들을 포함합니다.

 

HTML parser가 이미지 같은 non-blocking 요소들을 발견하게 되면 브라우저는 이 자원들을 요청하고 파싱을 멈추지 않고 진행합니다. CSS파일을 만나도 멈추지않고 파싱이 계속되지만,  <script> 태그를 만나게 되면 렌더링이 멈추고 HTML 파싱이 중단됩니다. 스크립트가 다운로드 되고 실행되기 전까지 HTML 파싱이 중단되는 이유는 DOM 을 조작하는 API 를 이용하여 구성이 바뀔수 있기 때문입니다. 

DOM 생성이 멈추면 다음과 같은 문제가 생길 수 있습니다. 

1) 스크립트에서는 스크립트 아래에 있는 DOM 요소에 접근할 수 없습니다. 따라서 DOM 요소에 핸들러를 추가하는것 과 같은 여러 동작이 불가능합니다.

2) 페이지 상단에 용량이 큰 스크립트가 있을때 스크립트가 페이지를 막습니다. 사용자는 스크립트의 다운로드가 완료되고 실행할때까지 스크립트 아래쪽 페이지를 볼 수없습니다. 

<script> 태그를 body의 마지막에 넣어주면 파싱을 먼저 끝낼 수 있습니다. 하지만 만약 HTML 파일 자체가 큰 경우, HTML 다운로드 이후 스크립트를 다운로드 받게 하면 페이지가 느려질 수 있습니다. defer와 async 를 사용하면 이를 해결 할 수있습니다. 

 

 

defer, async

defer 속성이 있는 스크립트는 백그라운드에서 다운로드하기 대문에 다운로드 도중 HTML 파싱이 멈추지 않습니다. defer 스크립트 실행은 페이지 구성이 끝날때 까지 지연 됩니다. 

-지연 스크립트는 페이지 생성을 절대 막지 않습니다.

-지연 스크립트는 DOMContentLoaded 이벤트 발생 전에 실행됩니다.

❗️ defer 속성은 외부 스크립트 (src= " ") 에만 유효합니다. 

async 속성이 있는 스크립트는 페이지와 완전히 독립적으로 동작합니다. defer와 동일하게 백그라운드에서 다운로드 되기 때문에 HTML 페이지는 다운로드 완료를 기다리지 않고 페이지 내 콘텐츠를 처리하고 출력합니다. 하지만 async 스크립트 실행중에는 HTML 파싱이 멈춥니다. 서로의 스크립트를 기다리지 않는 특징 때문에, async 스크립트가 여러개 있다면 실행 순서는 다운로드가 끝난 스크립트 순으로 진행됩니다. 

- DOMContentLoaded 이벤트는 상황에 따라 비동기 스크립트 전이나 후에 실행됩니다. 

 

 

 

 

 

참고

https://developer.mozilla.org/en-US/docs/Glossary/Parse  

https://dev.to/saurabhdaware/html-parsing-and-rendering-here-s-what-happens-when-you-type-url-and-press-enter-3b2o 

https://ko.javascript.info/script-async-defer