본문 바로가기

JavaScript

[JS] <script> 태그의 defer, async 속성

HTML<script>태그의 defer 속성

페이지가 모두 로드된 후에 해당 외부 스크립트가 실행됨을 명시한다.

-defer속성이 있는 스크립트를 '백그라운드'에서 다운로드하기 때문에 지연스크립트를 다운로드 하는 도중에도 HTML파싱이 멈추지 않는다. 그리고 defer 스크립트 실행은 페이지 구성이 끝날 때까지 지연된다.

-지연스크립트는 페이지 생성을 절대 막지 X / DOM이 준비된 후에 실행되긴 하지만 DOMContentLoaded 이벤트 발생 전에 실행

-defer 속성은 불리언(boolean) 속성으로 명시하지 않으면 false 값을 가지게 되고, 명시하면 true 값을 가지게 된다.

- <script> 요소가 외부 스크립트를 참조하는 경우에만 사용할 수 있으므로, src 속성이 명시된 경우에만 사용가능

 

▼ 작성법

 

<script src="js/scrollupdate.js" defer></script>

 

이런 식으로 html의 <head>안에 파일을 첨부하고 뒤에 defer라고 적어주는 형식이다.

 

 

 

<script> 태그의 async 속성

: 스크립트가 나머지 페이지와는 비동기적으로 실행됨을 나타내며, 브라우저가 페이지를 파싱하는 동안에도 스크립트가 사용가능해지면 곧바로 실행됨을 명시한다.

- async 속성의 스크립트는 페이지와 완전히 독립적으로 동작된다.

- defer 스크립트와 마찬가지로 백그라운드에서 다운로드 된다. 따라서 HTML 페이지는 async 스크립트 다운이 완료되길 기다리지 않고 페이지 내 콘텐츠를 처리, 출력한다(하지만 async 스크립트 실행중에는 HTML 파싱이 멈춤)

- DOMContentLoaded 이벤트와 async 스크립트는 서로를 기다리지 않고 실행된다.
  ▶ 페이지 구성이 끝난 후에 async 스크립트 다운로딩이 끝난 경우, DOMContentLoaded는 async 스크립트 실행 전에

      발생할 수 있다.
  ▶ async 스크립트가 짧아서 페이지 구성이 끝나기 전에 다운로드 되거나 스크립트가 캐싱처리 된 경우,

      DOMContentLoaded는 async 스크립트 실행 후에 발생할 수도 있다.
- 다른 스크립트들은 async 스크립트를 기다리지 않고, async 스크립트 역시 다른 스크립트들을 기다리지 않는다.
   이런 특징 때문에 페이지에 async 스크립트가 여러 개 있는 경우, 그 실행 순서가 제각각이 된다.

   실행은 다운로드가 끝난 스크립트 순으로 진행.

- async 속성은 불리언(boolean) 속성으로 명시하지 않으면 false 값을 가지게 되고, 명시하면 true 값을 가지게 된다.

- src 속성이 명시된 경우에만 사용 가능

 

defer와 async 작성

참조된 외부 스크립트 파일을 다음과 같이 여러 가지 방법으로 실행시킬 수 있다.

- async 속성이 명시된 경우 : 브라우저가 페이지를 파싱되는 동안에도 스크립트가 실행됨.

- async 속성은 명시되어 있지 않고 defer 속성만 명시된 경우 : 브라우저가 페이지의 파싱을 모두 끝내면 스크립트가 실행됨.

- async 속성과 defer 속성이 모두 명시되어 있지 않은 경우 : 브라우저가 페이지를 파싱하기 전에 스크립트를 가져와 바로 실행시킴.

 

차이점

async 문서 내 순서와 상관없이 먼저 다운로드된 스크립트가 먼저 실행 비동기 스크립트는 HTML 문서가 완전히 다운로드되지 않은 상태라도 로드 및 실행될 수 있다.
스크립트 크기가 작거나 캐싱 처리 되어있을 때 혹은 HTML 문서 길이가 아주 길 때 이런 일이 발생.
defer 문서에 추가된 순서 지연 스크립트는 문서 다운로드와 파싱이 완료된 후에, DOMContentLoaded 이벤트 발생 전에 실행.

 

 

왜 사용을 하는가?

브라우저는 HTML을 읽다가 <script>...</script> 태그나  <script src="">..</script>를 만나면 스크립트를 먼저 실행해야 하므로 DOM 생성을 멈춘다. 외부에서 스크립트를 다운받고 실행한 후에야 남은 페이지를 처리할 수 있다.

이런 브라우저의 동작 방식은 두 가지 이슈를 만든다.

  1. 스크립트에서는 스크립트 아래에 있는 DOM 요소에 접근할 수 없다. 따라서 DOM 요소에 핸들러를 추가하는 것과 같은 여러 행위가 불가능해진다.
  2. 페이지 위쪽에 용량이 큰 스크립트가 있는 경우 스크립트가 페이지를 ‘막아버린다’. 페이지에 접속하는 사용자들은 스크립트를 다운받고 실행할 때까지 스크립트 아래쪽 페이지를 볼 수 없게 된다.

→그러면 <body>태그 아래에 작성하면 되지 않나?

→페이지 맨 아래에 놓을 시 스크립트 위에 있는 요소에 접근이 가능하고, 페이지 콘텐츠 출력을 막지 않는다. 하지만 완벽한 해결책은 아니다. HTML문서 자체가 큰 경우 브라우저가 HTML문서전체를 다운로드 한 다음 스크립트를 다운받게 하면 페이지가 느려질 것이다. (네트워크 속도가 빠른 경우는 지연이 눈에 잘 띄지 않지만 네트워크 환경이 열악한 경우는 눈에 띈다.)

→위와 같은 문제를 해결할 수 있는 <script>속성이 defer와 async

 

 

 

 

 

 

 

reference: https://ko.javascript.info/script-async-defer