JavaScript

[JavaScript/HTML] script 태그의 defer와 async 속성 알아보기

Chae-ri🍒 2025. 1. 7. 17:28

바닐라 JS 실습 프로젝트를 하는 도중

자바스크립트 동작이 제대로 안되는 것을 확인했다.

 

이벤트를 걸어줬는데 이벤트도 동작을 안하고 콘솔로 확인해보니 dom 관련 메서드가 제대로 동작이 안되는 걸 확인할 수 있었다.

Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')

 

<script src="app.js"></script>가 <body> 태그보다 먼저 로드되고 있어서,

app.js가 실행될 때 아직 clickBtn과 backgroundDiv가 DOM에 존재하지 않았기 때문에 발생하는 문제였다.

 

문제의 코드...

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>flipper</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <script src="app.js"></script>  // ❌
  <body>

 

해결 방법에는 script 태그 위치를 옮기거나 defer나 async 요소를 넣으면 된다. (추가로 DOMContentLoaded라는 것도 있다고 한다.)

 

1. script 위치 조정

스크립트가 바디 태그 마지막에 오도록 하자.

<body>
    <div id="background">
      <div class="">background color: <span id="color_text"></span></div>
      <button id="flipper">Click me!</button>
    </div>
    <script src="app.js"></script>
</body>

 

1번 방법처럼 body 마지막 부분에 script 태그를 넣어도 되지만 만약 html 코드가 방대해진다면 script 태그를 찾기가 번거로울 것이다.

또 자신이 원하는 위치에 script 태그를 두고 싶다면 다음에 나오는 defer와 async를 활용하면 된다.

 

2. defer 또는 async 요소 활용

먼저 defer async 모두 브라우저가 HTML 문서와 script 태그 자바스크립트 파일은 동시에 내려받는다는 특징이 있다.

 

이제 여기서 이 둘의 차이점을 알아보자.

 

defer

defer는 HTML 문서와 script 태그 자바스크립트 파일이 동시에 내려받아지고 난 후,

HTML 문서 처리가 끝나고 나서 자바스크립트 파일이 실행이 된다.

async

async는 defer와 동일하게 HTML 문서와 script 태그 자바스크립트 파일이 동시에 내려받아지지만,

자바스크립트 파일이 다 내려받아지는대로 즉시 실행을 한다.

 

그래서 언제 defer을 쓰고 언제 async를 쓰는데?

순차적으로 스크립트 파일을 실행하고 싶을 때 => defer

순서 필요 없이 독립적으로 실행되어도 되는 파일일 때 => async

 

이미지 출처: https://www.josefzacek.cz/blog/whats-the-difference-between-async-vs-defer-attributes/

 

728x90