TIL.02 async, defer

HTML파일에 <script>태그를 이용해 JavaScript를 하는 방법은 4가지가 있다.

  1. 일반적인 sciprt tag 삽입
  2. body태그 안에 script 태그 삽입
  3. async 속성 사용
  4. defer 속성 사용

1.일반적인 script tag 삽입

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script src="main.js"></script>
  </head>
  <body>
  </body>
</html>

1번 방법은 head태그 안에 script태그를 삽입한다. 브라우저가 HTML을 parsing 하다가 script 태그를 만나면 JS파일을 로드하고 실행한다. 그 과정에서 HTML은 parsing을 멈추고 JS파일이 실행된 후 나머지 HTML이 parsing된다. 이 방법의 단점은 JS파일의 크기가 크고 인터넷이 느리다면 사용자가 온전한 웹사이트를 보기까지의 시간이 더 걸린다.


2. body태그 안에 script 태그 삽입

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    
  </head>
  <body>
    <script src="main.js"></script>
  </body>
</html>


2번 방법은 HTML을 우선적으로 parsing 후 JS파일을 로드한다. 이 방법은 사용자가 온전한 HTML을 먼저 볼 수 있다는 점에서는 1번의 경우보다는 낫지만 단점이 있다.
만약에 개발한 웹사이트가 JS에 굉장히 의존적이라면 사용자가 정상적인 페이지를 보기 힘들다.


3. async 사용

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script async src="main.js"></script>
  </head>
  <body>
  </body>
</html>


3번 방법은 script 태그 내에 async속성을 추가함으로서 사용이 가능하다. 이 방법은 HTML을 parsing하다가 script 태그를 만나면 병렬적으로 JS파일을 로드한다. JS파일의 다운이 완료되면 HTML parsing을 멈추고 JS를 실행한다. 그 후 나머지 HTML을 parsing한다. 병렬적으로 JS파일을 다운받는다는 점에서 빠르다. 하지만 HTML의 parsing이 다 끝나기 전에 JS가 실행되기 때문에 JS에서 parsing이 되지 않은 HTML요소를 조작하는 코드가 있을 시 잘못된 동작을 일으킬 수 있다. 또한 JS의 실행을 위해 HTML parsing을 멈추기 때문에 완전한 page를 준비하기까지의 시간이 걸린다.

3-1. 여러개의 JS파일을 받는 경우의 위험성

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script async src="a.js"></script>
    <script async src="b.js"></script>
    <script async src="c.js"></script>
  </head>
  <body>
  </body>
</html>


우리가 만약 여러개의 JS파일을 다운로드 받을 시 정의된 태그 순서대로의 실행을 보장하지 않는다. 이 말은 a.js가 먼저 실행되어야할 코드임에도 불구하고 b.js가 먼저 다운로드될 시 b.js를 먼저 실행된다는 것이다. 순서의존적인 JS파일이라면 사용상의 문제가 있다.


4. defer 사용

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script defer src="main.js"></script>
  </head>
  <body>
  </body>
</html>

defer 속성은 async와 마찬가지로 script 태그 내에서 선언하면 적용이 가능하다. defer속성 선언 시 HTML을 parsing하다가 script태그를 만나면 병렬적으로 JS를 로드한다. 그리고 남은 HTML을 모두 parsing 후 JS를 실행한다. 4개의 방법 중 가장 안정성이 있고 신속하다.

4-1. aync와 다른 다수의 파일 처리 방법

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script async src="a.js"></script>
    <script async src="b.js"></script>
    <script defer src="c.js"></script>
  </head>
  <body>
  </body>
</html>


여러개의 JS파일을 다운받는 경우, 모든 JS파일을 HTML parsing과 동시적으로 다운 받는다. 그리고 HTML parsing이 완료된 후 정의한 script 순서대로 JS파일이 실행된다.

reference

https://youtu.be/tJieVCgGzhs
https://developer.mozilla.org/ko/docs/Web/HTML/Element/script

comment - FE 개발자이자 youtuber이신 드림코딩엘리님의 JS 기초 강의를 정리한 글입니다.

좋은 웹페이지 즐겨찾기