본문 바로가기

JavaScript

[자바스크립트 파일 링크] HTML script async와 defer 차이점

1. head 안에 js 파일 링크하기

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="main.js"></script>
</head>
  • 요약 : 브라우저는 한줄씩 파싱하여 DOM 요소로 변경하는데, js 파일이 보이면 다운로드 받고 나서 다시 다음 줄을 파싱하게 됨
  • 단점 : js 파일크기가 크다면 가져오고 실행하는데 오래걸림
  • 순서 : html의 document에서 link:css, script:src 로 css와 js 파일을 연결한다. 이때 브라우저는 DOM을 한줄씩 parsing 한다. 그러다가 script 태그에 링크된 .js 파일이 있다면, 다운로드를 하려고 parsing한 html을 멈추고 필요한 자바스크립트 파일을 서버에서 받아온다. js파일을 실행한 후 html의 그 다음 줄을 parsing한다. 이러한 방식은 js 파일 크기가 클때는 사용자가 오랫동안 기다려야 하는 단점이 있어서 html의 head에 js파일을 포함하는것은 좋은 방식이 아니다.

2. </body> 위에 링크하기

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="main.js"></script>
</body>
  •  </body> 마감태그 위에 script 하는 방식이다. html 페이지 전체가 이미 준비가 된 상태로 js 파일을 가져오기 때문에 사용자가 페이지 콘텐츠를 바로 볼 수 있는 장점이 있다.
  • 단점 : 자바스크립트에 의존적인 콘텐츠라면, 사용자가 정상적인 콘텐츠를 보기 위해서는 오래 기다려야 한다.
  • 순서 : 이 경우, html을 똑같이 한줄씩 parsing한다. 즉, 모든 html을 읽고나서 정적 페이지가 준비된 다음에, 제일 마지막에 script를 fetching하여 서버에서 받아오고 실행하게 된다. 하지만 동적인 웹사이트의 경우는 사용자가 동적인 요소를 기다려야 한다는 단점이 있다.

3. asyn 방식

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script async src="main.js"></script>**
</head>
  • 요약 : <head> 안에 들여오는 대신, async 속성값 사용하는 방식이다. async는 boolean 타입이므로 true값이며, 병렬 방식으로 파싱하는 방법
  • 순서 : html을 한 줄 씩 파싱하다가 script async를 보면, 일단 병렬로 main.js를 명령만 해놓고서, 그 다음줄부터 html을 파싱한다. 파싱 중간에 main.js 파일 다운로드가 다 완료되면 html 파싱을 멈추고 실행하게 된다. 그리고 나머지 html을 파싱한다.
  • 장단점 : 이전 방식들 보다는 다운로드 받는 시간이 단축되지만, html 파싱을 중간에 멈추기 때문에 html element가 완전히 나오지 않을 수가 있다. 따라서 사용자가 콘텐츠를 완전히 이용하려면 여전히 시간이 걸린다.
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script async src="a.js"></script>
  <script async src="b.js"></script>
  <script async src="c.js"></script>
</head>
  • 여러개의 js 파일이 있을 경우, 가벼운 자바스크립트 파일부터 다운로드 받아지기 때문에 문제가 생길수도 있다.
    • 예) b.js가 가벼운 크기여서 먼저 실행 후 나머지 a.js나 c.js가 실행될 수 있는 경우

4. defer 방식

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script defer src="main.js"></script>
</head>
  • 제일 추천하는 방식으로 효율적이고 안전한 방식이다.
  • main.js를 다운로드만 하는 명령을 내려놓고, 나머지 HTML을 끝까지 파싱하게 된다. 마지막에 다운로드 된 main.js 자바스크립트 파일을 실행한다.
  • 즉, 자바스크립트 파일을 다운로드 하는 동안에 사용자들에게 페이지를 먼저 보여준 다음에 바로 이어서 파일을 실행하게 됨
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script defer src="a.js"></script>
	<script defer src="b.js"></script>
	<script defer src="c.js"></script>
</head>
  • 여러 자바스크립트 파일들이 있어도, HTML을 파싱하는 동안에 필요한 자바스크립트 파일을 다운로드 후, 순차적으로 실행함
  • 즉, 직접 정의한 script 링크 순서대로 실행하게 된다. (a.js → b.js → c.js)

 

[출처]

https://youtu.be/tJieVCgGzhs?si=WAtf-u3YntBP9TL6