[JS] script의 async와 defer 속성

Lian Kim·2022년 9월 10일
0

자바스크립트는 파서 블로킹 리소스(parser blocking resource)이다.
브라우저는 HTML을 파싱하다가 <script> 태그를 만나면 진행하던 HTML 파싱을 중단하고 스크립트를 먼저 다운로드하여 파싱하고 실행한다. (인라인 스크립트의 경우 다운로드 과정 생략)

이렇게 되면 두 가지 문제가 발생할 수 있다.

  1. 스크립트 아래에 위치한 DOM 요소는 생성되기 전이므로 스크립트가 핸들링하지 못한다.
  2. 페이지 위쪽에 위치한 스크립트가 용량이 아주 크다면 렌더 블로킹이 일어나게 되어 사용자가 페이지의 컨텐츠를 보기 위해 기다려야 한다.

이러한 문제들을 근본적으로 해결하기 위해 HTML5부터 asyncdefer라는 속성(attribute)이 추가되었다. asyncdefer를 사용하면 HTML 파싱과 스크립트 다운로드가 비동기적으로 동시에 진행된다.

asyncdefer는 src 속성을 가진 외부 스크립트에서만 동작하고, 인라인 스크립트에서는 동작하지 않는다. (예외/ 인라인 스크립트가 module 타입이라면 async는 동작함)




📌 defer

DOM 생성 후 스크립트 실행

defer는 스크립트를 다운로드하는 동안에 HTML 파싱이 중단되지 않으며, HTML 파싱이 완료되어 DOM이 모두 생성된 직후 스크립트가 실행된다. (DOM 생성과 DOMContentLoaded 이벤트 발생 사이에 스크립트 실행)
=> DOM을 조작해야 하는 경우 defer 사용


실행 순서 보장

먼저 다운로드 완료된 스크립트가 있어도 태그 순서대로 실행된다. 뒤에 위치한 스크립트가 먼저 다운로드 완료되더라도 앞에 위치한 스크립트의 실행이 완료된 다음 뒤에 위치한 스크립트가 실행된다. 즉, defer 속성을 가진 스크립트는 실행 순서가 보장된다.
=> 여러 개의 스크립트가 서로 의존성을 가지는 경우 defer 사용




📌 async

(DOM이 모두 생성된 후에 async 스크립트가 다운로드 완료된 경우, DOMContentLoadedasync 스크립트 실행 전에 발생할 수 있음)


HTML 파싱 중단 후 실행

async는 다운로드 단계에서는 HTML 파싱을 중단하지 않지만, 실행 단계에서는 HTML 파싱을 중단하기 때문에 DOM이 모두 생성되기 전에 스크립트가 실행될 수도 있다.
=> 일찍 실행하는 것이 중요한 경우 async 사용


load-first order

async는 완전히 독립적이기 때문에 태그 순서와 상관없이 다운로드가 먼저 완료되는 것부터 실행된다.




✏️ 정리

defer - async 공통점

  • 스크립트를 다운로드하는 동안 HTML 파싱이 중단되지 않는다.
  • src 속성을 가진 외부 스크립트에서만 동작한다. (인라인 스크립트가 module 타입이라면 async는 동작함)

defer - async 차이점

  • defer는 HTML 파싱이 완료되면 스크립트가 실행되지만, async는 스크립트 다운로드가 완료되면 HTML 파싱이 중단되고 스크립트 먼저 실행된다.
  • defer는 태그 순서대로 스크립트가 실행되지만, async는 다운로드가 완료되는 순서대로 스크립트가 실행된다.



출처 자료
javascript.info defer, async 스크립트
이웅모, 『모던 자바스크립트 Deep Dive』, 위키북스

0개의 댓글