[HTML] [JavaScript] defer와 async

sujpark·2022년 4월 6일
0
post-thumbnail

Script 태그의 문제점

먼저 브라우저의 렌더링 과정 일부를 살펴보자.
서버로부터 받은 HTML 문서를 파싱하여 브라우저가 이해할 수 있는 Tree 자료구조 형태(DOM)로 만든다.
그 과정에서 중간에 <script> 태그를 만나게 되면 HTML 문서 파싱을 멈추고 script를 다운받고 실행한다.
이 과정에서 두가지 문제가 발생한다.

  1. 스크립트를 다운받고 실행하는 동안 화면이 로딩되지 않고 멈춘다.
  2. 스크립트는 아직 파싱되지 않은 DOM요소에 접근할 수 없다.

이 문제 때문에 보통은 script 태그를 HTML 문서 끝 쪽에 배치한다.
하지만 이 방법은 완전한 해결책이 아니다.

script 태그를 만나면 다운로드부터 해야하기 때문에 HTML파일이 과도하게 크거나 네트워크 환경이 열악해서 다운로드가 늦어지는 경우, 화면은 다 로딩이 되었는데 요소들이 제대로 작동하지 않는 상황이 생길 수 있다.

script

이를 해결하기 위한 script 태그의 속성 async, defer 에 대해 알아보자.

async

async 속성은 script 파일을 병렬적으로 다운받게한다. 즉 HTML 문서가 파싱되는 동안 동시에 script를 다운받을 수 있다.
다운을 받은 즉시 HTML 파싱을 멈추고 script 코드를 실행한다. 이 또한 문제를 야기한다. script 코드가 아직 로딩되지 않은 DOM요소에 접근할 수 없다. 여러 개의 스크립트 파일을 다운받는다면 작성 순서와 상관없이 다운받는 순서대로 실행하기 때문에 스크립트가 작성된 순서대로 실행되는 것을 보장하지 않는다. 스크립트 사이에 의존성이 존재하는 경우 제대로 작동하지 않을 수 있다.

<script async src="./first.js"/> <-- 다운로드 5초 !-->
<script async src="./second.js"/> <-- 다운로드 1초 !-->
<-- first가 먼저 실행되어야하는데 second가 먼저 실행된다. !-->

따라서 DOM요소에 직접 접근하는 스크립트는 async를 사용하지 않는 것이 좋다.
DOM요소에 직접 접근하지 않고, 다른 스트립트와의 의존성이 없는 스크립트에 async 속성을 적용해야한다.
async

defer

defer 속성 또한 script 파일을 병렬적으로 다운받게한다. 하지만 실행은 HTML 문서 파싱이 끝난 후에 일어난다.
DOM요소에 정상적으로 접근할 수 있고 다운로드를 기다리지 않아도 된다. 또한 스크립트 간의 순서를 보장받는다.
따라서 DOM 요소에 직접 접근하는 스크립트는 defer 속성을 사용하는 것이 바람직하다.
defer

참고

Async & Defer
Understand JavaScript async Vs defer Vs inline

profile
JavaScript TypeScript React Next.js

0개의 댓글