
바닐라JS를 다시 공부하다가 문득 <script>태그의 위치에 대해 의문점이 생겼다.
이전에 프로젝트를 할 때 당연하게 <body>태그의 맨 밑에 선언했는데
학원에서 배울 때는 또 <head>에 선언했다.
그때는 의문점이 없었는데 지금 공부하다보니 갑자기 의문이 생겼다.
<script>태그의 위치에 대해서 다시 정리하자.
<script> 태그는 어디 선언하는지에 따라 자바스크립트의 실행 시점과 동작이 달라진다.
<head> 태그 안에 선언하거나, <body> 태그 안에 선언하는 2가지 방법으로 선언할 수 있다.
<body>태그 끝에 선언(권장)<body>
<script src="../script/app.js"></script>
</body>
- HTML이 먼저 로드 된 후 스크립트가 실행된다.
- DOM(Document Object Model)이 모두 준비된 상태에서 자바스크립트가 실행되므로 DOM을 조작할 떄 에러가 발생하지 않는다.
- 브라우저가 HTML을 렌더링하면서 스크립트를 동시에 다운로드 하기 때문에 사용자 경험(UX)에 좋다.
웬만하면 <script>는 <body>태그 끝에 선언하는 것을 권장한다.
웹 브라우저에서 html 페이지를 요청하면 브라우저는 HTML을 위에서 아래로 파싱하면서 렌더링한다.
만약 <head>나 <body>초반에 <script> 태그를 선언하면,
브라우저는 스크립트를 다운로드하고 실행할 때까지 HTML 파싱을 멈춘다.
결과적으로 HTML 콘텐츠가 늦게 렌더링될 수 있다.
<body>태그 끝에 스크립트를 넣으면, 브라우저가 HTML을 모두 파싱하고 렌더링한 뒤 스크립트를 실행하기 때문에 사용자 경험(UX)가 개선된다.
<head>에 <script> 태그 선언 시 발생할 수 있는 에러<head>
<script>
document.getElementById('myButton').addEventListener('click', () => alert('클릭!'));
</script>
</head>
<body>
<button id="myButton">클릭하세요</button>
</body>
위의 코드에서는 자바스크립트가 실행될 때 #myButton이 아직 로드되지 않아 null 에러가 발생한다.
<body>
<button id="myButton">클릭하세요</button>
<script>
document.getElementById('myButton').addEventListener('click', () => alert('클릭!'));
</script>
</body>
<head>태그 안에 선언<head>
<script src="../scripts/app.js"></script>
</head>
위와 같이 선언하면 스크립트가 HTML을 파싱하기 전에 실행된다.
DOM이 아직 준비되지 않은 상태에서 DOM을 조작하려고 하면 에러가 발생할 수 있다.
만약 <head>에 선언해야 한다면 defer 또는 async 속성을 사용하자.
defer: HTML 파싱이 끝난 후 스크립트를 실행한다.<script src="../scripts/app.js" defer></script>
async: 스크립트를 비동기 로드하지만, 실행순서가 보장되지 않는다.<script src="../scripts/app.js" async></script>
만약 단순히 외부라이브러리를 로드하거나 DOM에 의존하지 않는 코드라면 head에 선언한다.