JavaScript 실행되면 html 파싱 중단되는 이유에 대해

안윤경·2023년 4월 17일
0

JavaScript 실행되면 html 파싱 중단되는 이유에 대해?

A:

이유는 브라우저 렌더링과 관련되어있습니다.

  1. 브라우저는 서버로 부터 받은 html,css,js를 가지고 화면을 그리는데 html,css파일은 렌더링 엔진에서, js파일은 자바스크립트엔진에서 해석합니다

브라우저 랜더링 과정

DOM트리 ▶︎ CSSOM트리 ▶︎ redner tree ▶︎ layout ▶︎ paint

  1. JS 엔진과 렌더링 엔진은 직렬적으로 실행되는데 이 때문에 html 중간에 script태그를 만나면 자바스크립트 엔진으로 제어권이 넘어가게 됩니다.

  2. DOM이 완성되지 않은 상태(렌더트리가 다 구성되지 않았을 때)에서 script로 제어권이 넘어가면 JS 엔진이 DOM 트리 변경시킬 수도 있고 에러가 발생할 수 있어 script태그는 body의 끝부분에 위치시키는 것이 좋습니다.

단 body에 넣는 경우 사용자가 기본적인 HTML컨텐츠를 빨리 본다는 장점은 있지만
자바스크립트 의존성이 큰 페이지인 경우, 사용자가 정상적으로 작동하는 웹 페이지를 보지는 못합니다.

이를 해결하기 위한 방법으로 HTML5부터 async와 defer 추가됩니다.

1. head +async

<p>...스크립트 앞 콘텐츠...</p>

<script src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

<!-- 스크립트 다운로드 및 실행이 끝나기 전까지 아래 내용이 보이지 않습니다. -->
<p>...스크립트 뒤 콘텐츠...</p>

async는 boolean 타입이기 때문에 선언하는것만으로도 true로 쓸 수 있다.
브라우저가 HTML을 파싱하다가 async을 확인하고 병렬로 다운로드를 명령만 해놓고 다시 파싱을 하고 JS 파일이 다운로드되면 그때 파싱을 멈추고
다운로드된 JS 파일을 실행하게된다. 이후 실행을 다하고나서 나머지 HTML을 파싱하게된다.

다운로드받는속도를 절약할 수 있지만 HTML이 파싱되기도전에 실행이 되기 때문에 querySelector로 DOM 요소를 조작하려 한다면
위험할 수 있으며 HTML을 파싱하는동안 언제든지 자바스크립트를 실행하기 위해서 멈출 수 있기때문에
사용자가 페이지를 보는데 여전히 시간이 조금 걸릴 수 있는 단점이 있다.
즉, 자바스크립트 파일의 로드는 동기적으로 진행할 수 있으나, 바로 자바스크립트 파일이 실행되므로 실행 순서를 보장할 수는 없음.

2.head +defer

<body>
  ... 스크립트 위 콘텐츠들 ...

  <script src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
</body>

HTML을 파싱을하다가 defer를 확인하고 JS 파일 다운로드를 명령시킨후 나머지 HTML을 끝까지 파싱하게 된다. 이후 마지막
파싱을 끝낸 다음에 다운로드되어진 JS 파일을 실행하도록한다.

참고자료
(https://velog.io/@eojine94/JavaScript-%EC%8B%A4%ED%96%89%EB%90%98%EB%A9%B4-html-%ED%8C%8C%EC%8B%B1-%EC%A4%91%EB%8B%A8%EB%90%98%EB%8A%94-%EC%9D%B4%EC%9C%A0)
(https://velog.io/@cherrycock/script-async%EC%99%80-defer%EC%9D%98-%EC%B0%A8%EC%9D%B4)
(https://ko.javascript.info/script-async-defer)

profile
프론트엔드 개발자 안윤경입니다

0개의 댓글