자바스크립트는 파서 블로킹 리소스(parser blocking resource)이다.
브라우저는 HTML을 파싱하다가 <script>
태그를 만나면 진행하던 HTML 파싱을 중단하고 스크립트를 먼저 다운로드하여 파싱하고 실행한다. (인라인 스크립트의 경우 다운로드 과정 생략)
이렇게 되면 두 가지 문제가 발생할 수 있다.
이러한 문제들을 근본적으로 해결하기 위해 HTML5부터 async
와 defer
라는 속성(attribute)이 추가되었다. async
와 defer
를 사용하면 HTML 파싱과 스크립트 다운로드가 비동기적으로 동시에 진행된다.
async
와 defer
는 src 속성을 가진 외부 스크립트에서만 동작하고, 인라인 스크립트에서는 동작하지 않는다. (예외/ 인라인 스크립트가 module 타입이라면 async
는 동작함)
defer
는 스크립트를 다운로드하는 동안에 HTML 파싱이 중단되지 않으며, HTML 파싱이 완료되어 DOM이 모두 생성된 직후 스크립트가 실행된다. (DOM 생성과 DOMContentLoaded
이벤트 발생 사이에 스크립트 실행)
=> DOM을 조작해야 하는 경우 defer 사용
먼저 다운로드 완료된 스크립트가 있어도 태그 순서대로 실행된다. 뒤에 위치한 스크립트가 먼저 다운로드 완료되더라도 앞에 위치한 스크립트의 실행이 완료된 다음 뒤에 위치한 스크립트가 실행된다. 즉, defer 속성을 가진 스크립트는 실행 순서가 보장된다.
=> 여러 개의 스크립트가 서로 의존성을 가지는 경우 defer 사용
(DOM이 모두 생성된 후에 async
스크립트가 다운로드 완료된 경우, DOMContentLoaded
가 async
스크립트 실행 전에 발생할 수 있음)
async
는 다운로드 단계에서는 HTML 파싱을 중단하지 않지만, 실행 단계에서는 HTML 파싱을 중단하기 때문에 DOM이 모두 생성되기 전에 스크립트가 실행될 수도 있다.
=> 일찍 실행하는 것이 중요한 경우 async 사용
async
는 완전히 독립적이기 때문에 태그 순서와 상관없이 다운로드가 먼저 완료되는 것부터 실행된다.
async
는 동작함)defer
는 HTML 파싱이 완료되면 스크립트가 실행되지만, async
는 스크립트 다운로드가 완료되면 HTML 파싱이 중단되고 스크립트 먼저 실행된다.defer
는 태그 순서대로 스크립트가 실행되지만, async
는 다운로드가 완료되는 순서대로 스크립트가 실행된다.출처 자료
javascript.info defer, async 스크립트
이웅모, 『모던 자바스크립트 Deep Dive』, 위키북스