자바스크립트 파일은 HTML 문서에서 <script>
태그로 작성한다. 이때 script 태그는 어디에 작성하는 것이 좋을까?
브라우저는 다음 순서대로 동작한다.
1. HTML 읽기
2. HTML 파싱
3-1. DOM 트리 생성
3-2. CSSOM 트리 생성
4. Render 트리(Dom트리와 CSSOM 트리의 결합) 생성
5. 렌더링
//DOM: Document Object Model
//CSSOM: CSS Object Model
브라우저는 HTML을 파싱할때 script 태그를 만나면, 파싱을 멈추고 script 태그를 다운로드한 후 실행한다. 자바스크립트 파일을 파싱해 syntax 트리
가 모두 생성할때까지 Render 트리
생성은 멈춘다. Render 트리가 끝나야 디스플레이에 렌더링되는데, 그렇다면 script 태그를 어디에 작성하는 것이 적절할까?
head 태그에는 title, html 파일에 대한 메타데이터(author, description 등)와 link 태그로 css 파일이 연결돼있다. 따라서, css 파일을 파싱해 CSSOM 트리를 만들고, js 파일을 파싱해 Syntax 트리를 만든 후 다시 HTML을 파싱하여 DOM 트리를 이어 만들기 때문에, Render 트리를 모두 만들어 렌더링하기까지 시간이 오래 걸리게 된다.
만약, js 파일 내에서 css를 조작하여 렌더링 이전에 적용돼야하는 경우 또는 body 태그 내의 요소에서 함수를 호출하는 등의 경우 등 자바스크립트가 css와 html 태그에 반영되어 렌더링되어야한다면head 태그 사이에 script 태그를 사용할 수 있다.
<body>
<script src="script.js">
</body>
script 태그를 작성하기 가장 적절한 위치는 body 태그의 최하단이다. 유저 입장에서 생각해보면, 일부만 렌더링된 화면을 보게 되므로, 에러라고 생각하거나 새로고침을 눌러 불필요한 트래픽이 늘어날 수 있다. 따라서, HTML 상단이나 body 태그 중간에 위치할 경우 이러한 문제가 발생할 수 있으므로 body 태그 최하단에 위치시키는 것이 적절하다.
<script async src="script.js">
다른 방법으로는 script 태그에 async 속성을 추가하는 것이다. script 태그를 만나면 HTML 파싱과 동시에 script를 다운로드한다. 다운로드가 끝나면 HTML 파싱을 멈추고, script를 실행한다. script 실행이 끝나면 다시 HTML 파싱을 시작한다.
<script defer src="script.js">
또다른 방법으로는 script 태그에 async 속성을 추가하는 것이다. async와 유사하지만, HTML 파싱이 시작된 후 script 태그를 만나면, 파싱과 동시에 script 태그를 다운로드한다. HTML 파싱이 모두 끝난 뒤에 script 태그를 실행한다.
reference