script 태그의 위치를 알아보기 전에 DOM 실행 순서에 대해 알아봅시다.
DOM 실행 순서
1. HTML 파싱은 위에서 아래로 진행
브라우저는 HTML 파일을 위에서 아래로 읽어가며, 각 HTML 요소를 DOM 트리로 변환합니다.
2. 이미지 / CSS는 non-blocking resources
이미지와 CSS 파일은 비차단 리소스(non-blocking resources)로, 이를 다운로드하는 동안에도 HTML 파싱을 계속 진행할 수 있습니다.
3. JavaScript는 HTML 파싱을 차단
<script> 태그가 HTML 문서 중간에 있을 경우, 브라우저는 해당 스크립트를 실행할 때까지 HTML 파싱을 중단합니다.
이를 보았을 때 DOM 조작 시, DOM이 완전히 생성된 후 실행되는 것이 안전하다고 볼 수 있습니다.
<script> 태그의 위치
1. <body> 끝에 배치
HTML 파싱이 완료된 후 DOM이 모두 생성된 후 스크립트가 실행되므로, DOM 조작을 안전하게 할 수 있습니다.
<body>
<!-- 모든 HTML 요소 -->
<script src="script.js"></script>
</body>
2. <head> 에 배치 - defer
defer 속성을 사용하면 HTML 파싱을 차단하지 않으며, DOM 파싱이 끝난 후 스크립트가 실행됩니다. DOM 조작이 필요하지만 초기 로드가 중요한 경우 유용합니다.
<head>
<script src="script.js" defer></script>
</head>
3. <head> 에 배치 - type="module"
type="module"은 defer와 유사하게 동작하며, ES6 모듈 시스템(import/export)을 사용할 때 적합합니다.
<body>
<!-- 모든 HTML 요소 -->
<script src="script.js"></script>
</body>
4. <head> 에 배치 - async
async는 스크립트를 병렬로 로드하되, 로드가 완료되는 즉시 실행됩니다. DOM이 생성되기 전에 스크립트가 실행될 수 있으므로, DOM 조작이 필요 없는 스크립트에 적합합니다.
<head>
<script src="script.js" async></script>
</head>
Populating the page: how browsers work - Web performance | MDN
Users want web experiences with content that is fast to load and smooth to interact with. Therefore, a developer should strive to achieve these two goals.
developer.mozilla.org
Window: DOMContentLoaded 이벤트 - Web API | MDN
DOMContentLoaded 이벤트는 HTML 문서가 완전히 구문 분석되고 모든 지연된 스크립트(<script defer src="…">와 <script type="module">)가 다운로드되고 실행될 때 발생합니다. 이미지, 서브프레임, 비동기 스크
developer.mozilla.org
<script>: 스크립트 요소 - HTML: Hypertext Markup Language | MDN
HTML <script> 요소는 데이터와 실행 가능한 코드를 문서에 포함할 때 사용하며 보통 JavaScript 코드와 함께 씁니다. WebGL의 GLSL 셰이더 프로그래밍 언어, JSON 등 다른 언어와도 사용할 수 있습니다.
developer.mozilla.org