script 태그 위치

sam_il·2022년 7월 24일
0

Script 태그의 위치

  1. head 태그 내부
  2. body 태그 마지막
  3. async / defer

대부분의 코드를 작성할 때 body 태그의 마지막에 script 태그를 사용했지만 그 이유는 정확히 알지 못했다. script 태그가 body 태그의 최하단에 위치해야 하는 이유는 무엇일까?

이에 대해 알아보려면 먼저 브라우저 작동원리에 대해 알아야 한다.


브라우저 동작 원리

  1. HTML을 읽기 시작한다.
  2. HTML을 파싱한다. (parsing: 컴퓨터가 읽을 수 있는 코드로 바꾸는 작업)
  3. DOM 트리를 생성한다.
  4. Render 트리(DOM tree + CSS의 CSSOM 트리 결합)가 생성된다.
  5. Display(브라우저)에 표시한다.

위의 브라우저 동작원리에서 1~2가 중요하다.
HTML을 읽어 내려가는 과정에서 script 요소를 만나면 파싱을 중단하고 중단한 상태에서 자바스크립트 코드(파일)을 로드 후 자바스크립트 코드를 파싱한다. 그 후 다시 HTML 파싱이 계속된다.

즉 HTML을 읽는 과정에서 자바스크립트 로드와 파싱을 위해서 중단되는 시점이 생기고, 그에 따라 Display에 표시되는 것이 지연된다.

또 다른 이유로는 HTML 파싱이 끝나고 DOM 트리가 생기기 전에 자바스크립트가 실행되어 DOM 조작을 할 경우 에러가 발생할 수 있다는 점이다.


정리해보자면,

script 태그가 body 태그의 최하단에 위치해야 하는 이유

  1. HTML을 읽는 과정에서 중간에 스크립트를 만나면 스크립트 로드와 실행을 위해서 중단되는 시점이 생기고, 그에 따라 그 만큼 Display에 표시되는 것이 지연된다.
  2. HTML 파싱이 끝나고 DOM 트리가 생기기 전 자바스크립트가 실행되어 DOM 조작을 할 경우 에러가 발생할 수 있다.

async, defer

body 태그 최하단에 위치하지 않고도 위의 2가지 이유를 방지하기 위해 사용하는 script 태그의 async / defer 속성을 알아보자.

<script async src="index.js"></script>
<script defer src="index.js"></script>

async 또는 defer 속성을 사용하면 공통적으로 HTML 파싱과 동시에 스크립트 로드가 이루어진다.

이후,

  • async는 HTML 파싱이 끝나지 않더라도 스크립트 로드가 완료되는 즉시 스크립트가 실행된다.
  • defer는 HTML 파싱이 모두 끝난 뒤 스크립트가 실행된다.

추가적으로 async의 경우 비동기적으로 여러 스크립트를 로드, 실행하기 때문에 스크립트의 순서에 상관없이 실행될 수 있다. 따라서 실행 순서가 서로 영향이 있는 스크립트들을 사용할 때에는 주의해서 사용해야 한다. (동기적인 실행을 위해서는 async=false로 설정하여 순서대로 실행할 수 있다.)

defer는 순서대로 실행된다.

script 태그가 body 태그의 최하단에 위치한다면 async와 defer가 필요없겠지만 그렇지 않을 경우 async와 defer를 활용해서 볼 수 있는 효과와 주의해야할 점은 아래와 같다.

효과)
async, defer 모두 HTML 파싱과 스크립트 로드가 동시에 진행되므로 HTML 파싱이 완료되는 시간을 줄일 수 있다.

주의할 점)
async는 HTML 파싱과 동시에 스크립트 로드를 하지만 스크립트 실행은 HTML 파싱이 중지된 상태에서 진행되기 때문에 중간에 HTML 파싱이 멈추는 시점이 생길 수 있다. 다만 실행 순서를 감안해야 한다.

defer는 HTML 파싱과 동시에 스크립트를 로드하고 HTML 파싱이 완료된 후 스크립트가 실행된다. 이는 위에서 설명한 'script 태그가 body 태그의 최하단에 위치해야하는 이유'를 모두 보충해준다.


📌참고자료

브라우저 작동원리 https://wormwlrm.github.io/2021/03/27/How-browsers-work.html#tldr
script 태그위치 https://junhobaik.github.io/js-script-position/

profile
🍀

0개의 댓글