async, defer

sorikiki·2022년 2월 6일
0


본 포스팅은 유튜브 드림코딩의 강좌를 수강한 후 필자가 홀로 복습한 내용과 함께 재구성하여 작성되었다.




웹 페이지를 구성하는 html의 script 태그에 js파일을 로드할 때 사용할 수 있는 유용한 옵션들에 대해 배울 것이다.


Attribute 없이 사용할 때의 문제점 🤔

브라우저는 html의 코드를 위에서부터 한 줄씩 이어나가기 때문에 <head> 태그에 <script src=""> 태그를 더한다면 parsing을 멈추고 js 파일을 fetching한 후 executing을 마친 뒤에야 다시 parsing을 재개하기 때문에 사용자 입장에서 화면이 로드되기 까지 기다려야하는 치명적인 단점이 있다.

✏️ head: parsing html-> fetching js -> executing js -> parsing html
( js 파일을 fetching 하고 executing하는 동안 html parsing이 blocked됨.)

이를 방지하고자 <body> 태그의 안쪽 끝부분에 <script> 태그를 붙일 수도 있겠으나, 이 경우에는 parsing이 모두 이루어지고 난 후에야 fetching한 후 executing을 하기 때문에 parsing할 양이 많고 동적인 특성이 강한 웹사이트일 경우에는 정적인 상태에서 오래 머물러야 한다는 점에서 단점이 있다.

body: parsing html (all) -> fetching js -> executing js


async, defer

boolean type인 async나 defer을 script의 attribute로서 부여할 수 있다.

기본적인 형태는 <script async src=""> 혹은 <script defer src="">과 같이 작성하면 된다.

✏️ head + async: parsing html + fetching js -> executing js -> parsing html
(parsing과 동시에 진행되는 fetching이 완료되는 시점에 executing을 하고, 이때 html parsing이 blocked됨.)

이 경우, async 옵션을 쓰지 않을 때에 비해 html parsing이 blocked되는 지연 시간을 줄여주는 장점이 있으나 js 파일을 executing할 때에는 여전히 html을 blocking하는 단점을 해소하지 못한다. 또한 executing하는 바로 그 시점에 아직 로딩되지 못한 특정 html 구문을 동적으로 처리하는 코드가 존재할 수도 있다.

✏️ head + defer: parsing(all) + fetching js -> executing js

결국 정답은 defer이다. 이는 async를 사용했을 때의 위 두 가지 문제점을 모두 해소할 수 있다. blocking도 없고, html이 다 로드된 상태에서 js 파일을 executing하기 때문이다.

만일 <script> 태그 여러개를 사용하여 js 파일을 여러개 불러오고자 할 때 모든 태그에 async 옵션을 부여한다면, 태그 순서에 상관없이 fetching이 완료된 js 파일부터 executing을 실행할 것이고 그동안은 html parsing이 당연히 blocked될 것이다. 즉, js 파일을 여러개 로딩할 경우 async 사용의 부정적인 효과는 극대화 된다.

반면 defer 옵션을 부여한다면, 각각의 파일이 fetching이 완료되는 시점은 태그 순서와 무관하더라도 모든 html parsing이 완료된 후에야 태그 순서에 따라 js 파일을 실행하기 시작한다. 따라서 개발자는 이를 고려하여 <script> 태그를 체계적으로 배치할 수 있다.

0개의 댓글