script 요소의 async, defer 어트리뷰트
Goal
<script>
요소의 async
, defer
어트리뷰트에 대해 알아보기
JavaScript 파일의 실행 순서
브라우저의 파싱 작업은 동기적 방식이라고 할 수 있다.
브라우저의 렌더링 과정에서 HTML이 파싱될 때 <script>
요소를 만나면 HTML 파싱 작업은 즉시 중지되고 자바스크립트 파일이 실행되기 때문이다.
전통적으로 <script>
요소는 <head>
요소 안에 쓰는 것이 일반적이었지만, 자바스크립트 파일을 전부 <head>
요소에 넣어버리면 자바스크립트 코드를 전부 내려받고, 파싱하고, 해석이 끝날 때까지 페이지 렌더링이 멈추게 된다. <script>
요소의 이러한 특성은 HTML 페이지를 렌더링하는 속도에 상당한 영향을 미칠 수 있다. 또한 사용자에게는 화면이 멈춘 것처럼 느껴지게 되는 문제가 생길 수 있다.
그리고 <head>
요소에 스크립트가 있을 때 자바스크립트 코드 내에 DOM을 조작하는 부분이 있다면 오류가 발생할 수 있다. DOM이 아직 생성되지 않았을 수 있기 때문이다.
따라서 이러한 문제점을 방지하기 위해 <body>
요소 가장 아래에 자바스크립트를 위치시키면 DOM이 완성되지 않은 상태에서 자바스크립트가 DOM API를 사용하는 것과 자바스크립트 로드, 파싱, 실행으로 인해 HTML 요소가 렌더링이 지연되는 일을 방지할 수 있는 장점이 있다.
<body>
요소 가장 아래에 자바스크립트를 위치시키는 방법 외에 자바스크립트 파싱에 의해 DOM 생성이 지연되는 문제를 해결하기 위해 HTML5부터 <script>
태그에 async
와 defer
어트리뷰트가 추가되었다. 이 속성들을 추가하면 HTML 파싱과 외부 자바스크립트 파일의 로드가 비동기적으로 동시에 실행된다.
defer 어트리뷰트
- 브라우저는
defer
속성이 있는 스크립트를 '백그라운드'에서 다운로드 한다. - 그래서
defer
스크립트를 다운로드 하는 중에도 HTML 파싱이 중단되지 않는다. defer
스크립트는 자바스크립트 파싱과 실행이 HTML 파싱이 완료된 직후 진행된다.- DOM 생성 완료 직후 스크립트가 실행되지만
DOMContentLoaded
이벤트 발생 전에 실행된다.DOMContentLoaded
이벤트는defer
속성이 적용된 스크립트의 실행을 기다리기 때문이다.
async 어트리뷰트
async
속성이 있는 스크립트도defer
스크립트와 마찬가지로 '백그라운드'에서 다운로드된다.async
는 자바스크립트 파싱과 실행이 자바스크립트 파일의 로드가 완료된 직후 진행되며 이때 HTML 파싱이 중단된다.DOMContentLoaded
이벤트와async
스크립트는 서로 기다리지 않는다.DOMContentLoaded
이벤트는async
스크립트 실행 전에 발생될 수도 있고, 실행 후에 발생될 수도 있다.
같이 보기
reference
- 한선용 역, 니콜라스 자카스 저, 《프론트엔드 개발자를 위한 자바스크립트 프로그래밍》, 인사이트, 2013년
- 안재우 역, 코디 린들리 저, 《DOM을 깨우치다》, O'Reilly, 2013년
- 이웅모 저, 《모던 자바스크립트 Deep Dive》, 위키북스, 2020년
- JAVASCRIPT.INFO - defer, async 스크립트