Skip to content

Tags

On this page

script 요소의 async, defer 어트리뷰트

수정하기
문서 생성 2021-10-26 17:15:17 최근 수정 2022-05-23 22:28:02

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> 태그에 asyncdefer 어트리뷰트가 추가되었다. 이 속성들을 추가하면 HTML 파싱과 외부 자바스크립트 파일의 로드가 비동기적으로 동시에 실행된다.

defer 어트리뷰트

  • 브라우저는 defer 속성이 있는 스크립트를 '백그라운드'에서 다운로드 한다.
  • 그래서 defer 스크립트를 다운로드 하는 중에도 HTML 파싱이 중단되지 않는다.
  • defer 스크립트는 자바스크립트 파싱과 실행이 HTML 파싱이 완료된 직후 진행된다.
  • defer 속성이 있는 스크립트가 여러 개인 경우 문서에 추가된 순으로 실행된다.
  • DOM 생성 완료 직후 스크립트가 실행되지만 DOMContentLoaded 이벤트 발생 전에 실행된다. DOMContentLoaded 이벤트는 defer 속성이 적용된 스크립트의 실행을 기다리기 때문이다.

async 어트리뷰트

  • async 속성이 있는 스크립트도 defer 스크립트와 마찬가지로 '백그라운드'에서 다운로드된다.
  • async는 자바스크립트 파싱과 실행이 자바스크립트 파일의 로드가 완료된 직후 진행된다. 스크립트 실행 중에는 HTML 파싱이 멈춘다.
  • async를 사용하면 파일들이 병렬적으로 로드되며 다운로드가 끝난 순서대로 해석된다.
  • asyncdefer가 둘 다 사용된 경우 async가 우선하게 된다.
  • DOMContentLoaded 이벤트와 async 스크립트는 서로 기다리지 않는다.
    • DOMContentLoaded 이벤트는 async 스크립트 실행 전에 발생될 수도 있고, 실행 후에 발생될 수도 있다.

같이 보기

reference

  • 한선용 역, 니콜라스 자카스 저, 《프론트엔드 개발자를 위한 자바스크립트 프로그래밍》, 인사이트, 2013년
  • 안재우 역, 코디 린들리 저, 《DOM을 깨우치다》, O'Reilly, 2013년
  • 이웅모 저, 《모던 자바스크립트 Deep Dive》, 위키북스, 2020년
  • JAVASCRIPT.INFO - defer, async 스크립트