할머니의 콤퓨타 도전기

(Javascript) script async와 defer의 차이점 본문

Web Front-end/Javascript

(Javascript) script async와 defer의 차이점

ji.o.n.e 2021. 5. 1. 02:28

html에서 javascript를 포함할때 어떻게 포함하는게 효율적일까?

 

1. script를 head에 포함

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

html을 위에서 부터 쭉 파싱하다가 script 태그가 보이면 main.js를 다운받아야한다고 이해한다.

따라서 html 파싱을 잠시 멈추고 필요한 javascript 파일을 서버에서 다운받아 실행한 다음에 다시 파싱하는 부분으로 넘어간다.

 

단점

  • js 파일의 사이즈가 크고 인터넷이 느리다면 사용자가 웹사이트를 보는데 까지 많은 시간이 소요된다.
  • 따라서 script를 head에 포함하는 것은 좋지 않음

2. body 태그 가장 끝 부분에 script 추가

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

브라우저가 html을 다운받아서 쭉 파싱해서 페이지가 준비가 된 다음 script를 만나서 script를 fetching(서버에서 받아옴)하고 실행하게 된다. 따라서 페이지가 사용자들에게 js를 받기 전에도 이미 준비가 되어서 사용자가 페이지 컨텐츠를 볼 수 있다.

 

단점

  • 사용자가 기본적인 html의 컨텐츠를 빨리 본다는 장점은 있음.
  • 그러나 웹사이트가 자바스크립트에 의존적이라면(사용자가 의미있는 컨텐츠를 보기 위해서는 자바스크립트를 이용해서 서버에 있는 데이터를 받아온다던지, DOM 요소를 꾸며주는 식으로 동작) 사용자가 정상적인 페이지를 보기 전까지 서버에서 자바스크립트를 받아오는 시간도 기다려야하고 실행하는 시간도 기다려야하는 단점이 있다.

3. head + async

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

head 안에서 script를 이용하되, async이라는 속성값을 사용한다. async는 boolean 타입의 속성값으로 선언하는 것만으로도 true로 설정되어 사용가능하다. async를 사용하게 되면 브라우저가 html을 다운로드 받아서 parsing하다가 async가 있으면 병렬로 main.js 파일 다운로드 받고 명령하고 다시 파싱한다. main.js가 다운로드 완료가 되면 그때 파싱하는 것을 멈추고 다운로드된 js 파일을 실행한다. 실행 후 나머지 html을 파싱한다.

 

단점

  • body 끝에서 사용하는 것 보다는 fetching이 parsing이 병렬적으로 일어나기때문에 다운로드 받는 시간 절약가능
  • 그러나 자바스크립트가 html이 파싱되기도 전에 실행되기 때문에 자바스크립트 파일에서 DOM 요소를 조작하고자한다면, 조작하려는 시점에 우리가 원하는 html 요소가 아직 정의되어있지 않을 수 있음
  • html을 파싱하는 동안에 언제든지 자바스크립트를 실행하기 위해 멈출 수 있다. 따라서 사용자가 페이지를 보는데 시간이 조금 더 걸릴 수 있다.
<!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>
    	<div></div>
    </body>
</html>

 

async 옵션으로 다수의 script를 다운로드 받게되면 정의된 스크립트 순서에는 상관없이 다운로드가 먼저 된 것부터 실행한다. 따라서 자바스크립트가 순서에 의존적이라면 async 옵션을 이용하면 문제가 발생한다.

 

4. head + defer

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

 head 안에 script를 쓰고 defer 옵션을 정의한다. 파싱하다가 script defer가 있으면 main.js를 다운로드 받자고 명령만 시켜놓고 나머지 html을 끝까지 파싱한다. 그리고 파싱이 끝난 마지막에 다운로드되어진 자바스크립트를 실행하게 된다.

html을 파싱하는 동안 필요한 자바스크립트를 다 다운로드 받아놓고 html 파싱을 먼저해서 사용자에게 페이지를 보여준 다음에 이어서 자바스크립트를 실행한다.

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

 

async와 다르게 defer 옵션으로 다수의 script를 다운로드 받게되면 파싱하는 동안 필요한 자바스크립트를 다 다운로드 받아놓은 다음에 순서대로 실행한다. 따라서 정의한 순서가 지켜진다. 원하는대로 스크립트 실행이 가능하다.

 

결론적으로, head 안에 defer 옵션을 사용해서 쓰는 것이 제일 효율적이고 안전하다.

'Web Front-end > Javascript' 카테고리의 다른 글

(Javascript) Array APIs  (0) 2021.05.04
(Javascript) Object  (0) 2021.05.04
(Javascript) Class vs Object  (0) 2021.05.04
(Javascript) Function  (0) 2021.05.04
(Javascript) data types, let vs var, hoisting  (0) 2021.05.03
Comments