script태그 defer, async

진 솔·2025년 6월 13일

💡 HTML에서 JavaScript 파일을 가져올 때 가장 효과적인 방법

HTML 문서에서 외부 JavaScript 파일을 어떻게 불러오느냐에 따라
버튼 클릭이 안 되거나, 에러가 나거나, 성능이 나빠질 수 있습니다.

이 글에서는 간단한 버튼 클릭 예제를 통해
자바스크립트 파일을 언제, 어떻게 로드하는 게 좋은지 알아봅니다.


❗ 문제 상황: 버튼 클릭 시 에러 발생

📄 index.html

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <script src="index.js"></script>
  <title>Document</title>
</head>
<body>
  <h1>제목</h1>
  <p>내용</p>
  <div>
    <button id="btn">버튼</button>
  </div>
</body>
</html>

📄 index.js

let btn = document.querySelector('#btn');
btn.addEventListener('click', () => {
  alert('하하하');
});

🧨 결과

버튼 클릭 에러


🧠 원인: 브라우저의 HTML 파싱 순서

브라우저는 HTML을 위에서 아래로 순차적으로 해석(파싱)합니다.

브라우저 파싱 구조

  1. <script src="index.js">를 만나면,

  2. HTML 파싱을 멈추고 JS 파일을 가져와서 즉시 실행합니다.
    script 실행 흐름

  3. 이때 버튼 태그(<button id="btn">)는 아직 만들어지지 않음 → null 발생

이걸 console.log('btn:', btn);으로 찍어보면...

btn is null

null 찍히는 것을 확인할 수 있다.


✅ script 로드 해결방법

<body> 최하단에서 script 로드

<body>
  <button id="btn">버튼</button>
  <script src="index.js"></script>
</body>
  • HTML 요소가 모두 파싱된 이후 JS 실행됨
  • 전통적인 방식이지만 유효함

load 이벤트 리스너 사용

window.onload

window.onload = () => {
  const btn = document.querySelector('#btn');
  btn.addEventListener('click', () => {
    alert('하하하');
  });
};
  • HTML 파싱, DOM 생성 그리고 외부 컨텐츠(image, script, css etc 등) 모든 리소스 로드 후 실행
  • 이미지가 많다면 실행이 늦어짐

DOMContentLoaded (✅ 추천)

document.addEventListener('DOMContentLoaded', () => {
  const btn = document.querySelector('#btn');
  btn.addEventListener('click', () => {
    alert('하하하');
  });
});
  • HTML 파싱, DOM 생성 완료 후 즉시 실행됨
  • 이미지, CSS 로딩을 기다릴 필요 ❌

🚀 실제로 비교해보면 DOMContentLoadedwindow.onload보다 더 빠르게 실행됩니다.

alert 비교


HTML5 속성: defer vs async

HTML5에서는 defer async 속성을 통해 비동기 script 로드가 가능해져 이 문제를 근본적으로 해결되었습니다.

defer

<head>
  <script src="index.js" defer></script>
</head>
  • HTML 파싱과 함께, 비동기로 JS 파일을 불러옴
  • html 파싱 완료 후 순서 보장하며 JS코드 실행

defer 흐름


async

<head>
  <script src="index.js" async></script>
</head>
  • JS가 준비되면 즉시 실행됨
  • HTML 파싱이 완료되지 않았더라도, 먼저 로딩되어 JS 파일부터 실행이 시작됨.

async 흐름


🤔 defer vs async 언제 쓸까?

GPT 설명

  • 일반 JS는 defer
  • 독립적 외부 스크립트(광고, 통계 등)는 async

📚 참고 및 출처
본 글은 짐코딩님의 자바스크립트 강의를 기반으로 정리하였습니다.(클릭하면 들어가짐)
실제 강의에서는 시각적 예시와 설명이 더 풍부하니, 공부에 많은 도움이 됩니다. 🙏

profile
FE Developer Wannabe / 내가 인정 받을 때까지!! / https://github.com/sorrybro2 <- 깃허브 !

0개의 댓글