본문 바로가기
Javascript

JavaScript - script async와 defer

by Su1993 2020. 8. 24.
반응형

Index

1. async

2. defer

 


 

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

 

기본적으로 사용자가 HTML 파일을 다운로드하였을 때, 브라우저가 한 줄씩 분석하고 이해한 것을 CSS와 병합해서 DOM요소로 변환하게 된다. HTML에서 js을 포함할 때 head안에 포함할 경우, HTML을 한줄한줄 읽어나가다가 script 태그가 보이면 main.js를 다운로드하여야 되겠다고 이해하게 된다. 그래서 HTML을 읽어나가는 것을 멈추게 되고, 필요한 자바스크립트 파일을 서버에서 다운로드하여 실행한 다음에 다시 한줄한줄 읽어 나가게 된다. 만약 인터넷도 느리고 작성한 js파일의 사이즈가 크다면 사용자가 웹사이트를 보는 데까지 많은 시간이 소요될 수 있다는 단점이 있다. 

 

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

 

첫 번째 다음으로 많이 하는게 바로 body 제일 끝부분에 script를 추가하는 것이다. 이렇게 한다면 브라우저가 HTML을 다운로드하면서 준비가 된 다음에 스크립트를 만나서 서버에서 받아오고 실행하게 된다. 그래서 사용자들에게 js를 받기 전에도 이미 준비가 되어서 페이지 콘텐츠를 볼 수 있게 된다. 여기서 장점은 사용자가 기본적인 HTML의 콘텐츠를 빨리 볼 수 있다는 것이고, 만약 사용자가 보고 있는 웹사이트가 자바스크립트에 의존적이라면(자바스크립트를 통해 서버에 있는 데이터를 받아온다던지 또는 DOM요소를 이쁘게 꾸며준다던지) 사용자가 정상적인 페이지를 보기 전까지 서버에서 자바스크립트를 받아오는 시간도 기다려야 되고, 실행하는 시간도 기다려야 되는 단점이 있다.

 


1. head + async

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

* asyn는 boolean 타입의 속성값이어서 선언해주는 것만으로 true로 설정된다.

asyn를 사용해 줄 경우 브라우저가 HTML을 다운로드하여서 흐름을 읽다가 asyn을 만나면 병렬로 main.js를 다운로드하라고 명령을 한 후, 계속 흐름을 읽어 내려가다 main.js가 다운로드가 완료되면 그때 흐름 읽는 것을 멈추고 다운로드된 js파일을 실행하게 된다. 실행을 다 하고 나면 다시 흐름을 읽어 내려가기 시작한다. async를 사용해주면 body 끝에 script를 설정하는 것보다 fetching js가 흐름을 읽는 동안 병렬적으로 일어나기 때문에 다운로드하는 시간을 절약할 수 있다는 장점이 있다. 하지만 자바스크립트가 HTML의 흐름을 읽기도 전에 실행되기 때문에, 만약 자바스크립트 파일에서 쿼리셀렉터를 이용해서 DOM 요소를 조작한다 그러면 조작하려는 시점에 HTML이 우리가 원하는 요소가 아직 정의되어 있지 않을 수 있다는 것과 HTML의 흐름을 읽는 동안에 언제든지 자바스크립트 실행을 위해 멈출 수 있기 때문에 사용자가 페이지를 보는데 시간이 여전히 조금 더 걸릴 수 있다는 단점이 있다.

 


2. 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>

* defer이 가장 좋은 옵션이라 볼 수 있다.

defer을 사용해 줄 경우, HTML 흐름을 읽다가 defer을 만나면 main.js를 다운로드 받으라고 명령만 해놓은 후, 나머지 HTML의 흐름을 끝까지 읽는다. 흐름이 끝난 후, 다운로드된 자바스크립트를 실행하게 된다.

즉, HTML의 흐름을 읽는동안 자바스크립트를 모두 다운로드해놓고 HTML의 흐름을 끝까지 읽어서 사용자에게 먼저 페이지를 보여준 다음에 이어서 자바스크립트를 실행해준다.

 


 

*주의사항

<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>

async로 다수의 자바스크립트를 다운로드 받게 되면, 정의된 순서와 상관없이 다운로드가 먼저 된 자바스크립트 순으로 실행하게 된다.

만약 자바스크립트가 순서에 의존적이라면 async를 사용하게 되면 문제가 생길 수 있다.

 

<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>

async와 반대로 defer은 HTML의 흐름을 읽는 동안 자바스크립트들을 모두 다운로드해놓은 후 흐름이 끝나면 순서대로 실행하기 때문에 만약 자바스크립트가 순서에 의존적이라면 defer을 사용에 적합하다.

 

⭐️꿀팁

'use strict';

ECMAScript 5에 추가되어져 있는 'use strict';

자바스크립트를 이용할 때 제일 상단 부분에 'use strict'를 정의해주는 것이 좋다.(순수 바닐라 자바스크립트를 이용 시!! 단, 타입 스크립트를 쓴다면 제외)

자바스크립트는 유연한 언어이기 때문에 선언되지 않은 변수에 값을 할당하든, 기존의 존재하는 프로토타입을 변경해도 에러를 나타내지 않는다. 그래서 'use strict'는 이런 비상식적인 행동들을 에러를 나타냄으로써 잡아주는 역할을 한다.

+ 자바스크립트 엔진이 조금더 효율적으로 빠르게 자바스크립트를 분석할 수 있기 때문에, 실행하는 데 있어서 조금 더 나은 성능개선까지 기대할 수 있다.

반응형

'Javascript' 카테고리의 다른 글

JavaScript - Call Stack(호출 스택)  (0) 2020.09.03
JavaScript - JSON  (0) 2020.09.02
JavaScript - object(3)  (0) 2020.07.05
JavaScript - array methods  (0) 2020.07.05
JavaScript - template literals, string method  (0) 2020.07.05

댓글