본문 바로가기

기술면접

script, script async 와 defer

html에서 자바스크립트를 포함할 때 어떻게 포함하는게 효율적인지 알아봅시다.

<script> 태그를 <body> 태그가 끝나기 직전에 위치 시키는 이유

브라우저는 HTML을 다운로드 받으면, 한줄 한줄씩 파싱하면서 DOM을 만들고, CSS를 다운로드 받으면 CSSOM을 만들어 병합하게 됩니다. 브라우저는 <script> 태그를 만나면 HTML 파싱을 잠시 멈추고, <script>를 다운로드한 후 실행합니다. 

<head> 태그 안에 <script>태그를 위치시키게된다면, 만약 자바스크립트 파일의 크기가 크고 인터넷이 느리다면 사용자가 웹사이트를 보는데 많은 시간이 소요됩니다.

<body> 태그 끝부분에 <script> 태그를 넣는다면 html을 다운받아서 파싱한 뒤에 <script>를 fetch하고 실행하게 되면 페이지가 사용자들에게 자바스크립트 파일을 다운 받기 전에도 이미 준비가 되어서 사용자가 기본적인 html 컨텐츠를 빨리 볼 수 있다는 장점이 있지만, 웹사이트가 자바스크립트에 의존적이라면, 즉 사용자가 의미 있는 컨텐츠를 보기 위해서는 자바스크립트에 있는 서버에 있는 데이터를 받아오거나 DOM 요소를 꾸며주는 등의 방법으로 동작하는 웹사이트라면, 사용자가 정상적인 페이지를 보기 전까지는 자바스크립트를 받아오는 시간과 실행시간을 기다려야하는 큰 단점이 있습니다.

head + async

<script async>는 불리언 타입의 속성값이기 때문에 선언하는 것으로 true로 설정이 되어서 async 옵션을 사용할 수 있습니다.

<script async>를 사용하게 되면 브라우저가 html을 다운로드 받아서 파싱을 하다가 병렬적으로 <script> 파일 다운로드를 진행하면서 파싱을 하다가 <script> 파일이 다운로드가 완료되면 그때 파싱을 멈추고 다운받은 자바스크립트 파일을 실행한 뒤에 나머지 html파일을 파싱하게 됩니다.

<script async>의 장단점은 body 끝에 사용하는것보다는 fetching이 파싱하는 동안 병렬적으로 일어나기 때문에 다운로드 받는 시간을 절약할 수 있지만, 자바스크립트가 html이 파싱되기 전에 실행되기 때문에 자바스크립트 파일에서 html의 원하는 요소가 아직 정의되어 있지 않을 수 있어 위험할 수 있고 언제든지 자바스크립트를 실행하기 위해서 멈출 수 있기 때문에 사용자가 페이지를 보는데 시간이 조금 더 걸릴 수 있습니다.

head  + defer

<script defer>는 파싱을 하다가 script defer가 있다면 <script> 파일 다운로드를 진행하면서 html을 끝까지 파싱하게 됩니다. 그리고 마지막에 parsing이 끝난 뒤에 다운로드 되어진 자바스크립트를 실행하게 됩니다. html을 파싱하는 동안 필요한 자바스크립트를 다 다운받아놓고 html 파싱을 먼저해서 사용자에게 페이지를 보여준 후 바로 이어서 자바스크립트를 실행합니다.

async와 defer의 공통점

HTML을 파싱하는 동시에 해당 <script>를 다운로드 받는 점이 동일합니다.

async와 defer의 차이점

async 옵션으로 다수의 스크립트를 다운로드 받게 되면, 먼저 다운로드가 완료되는 스크립트를 순차적으로 실행하게 됩니다.

정의된 스크립트 순서에는 상관없이 다운로드가 먼저 된 스크립트를 실행하기 때문에 만약 웹사이트가 순서에 의존적이라면 문제가 될 수 있습니다

defer는 반대로, HTML 파싱이 진행되는 동안 파일을 모두 다운받고 순서에 맞게 실행하기 때문에 정의한 순서대로 스크립트가 실행이 될거라는 것을 예상할 수 있습니다.

 

https://www.webtips.dev/webtips/html/what-is-the-difference-between-async-and-defer

요약하자면,

  • <script> 는 HTML 파싱을 중단하고 해당 스크립트를 즉시 다운로드 받고 실행합니다. 스크립트 실행이 완료되면 HTML 파싱을 계속 진행합니다.
  • <script async> 는 HTML을 파싱하는 동시에 해당 스크립트를 다운로드 받습니다. 그리고 HTML 파싱이 완료되지 않았어도 스크립트를 실행할 수 있을 때 즉시 실행합니다.
  • <script defer>는 HTML을 파싱하는 동시에 해당 스크립트를 다운로드 받고 HTML 파싱이 끝난 후에 스크립트를 실행합니다. 스크립트가 여러개인 경우, 스크립트는 페이지에 나타나는 순서대로 실행되며, 스크립트가 DOM에 의존적인 경우 유용하게 사용됩니다. 또한 HTML이 파싱된 후 스크립트가 실행된다는 점에서 <script> 태그를 <body> 태그가 끝나기 직전에 위치시키는 것과 거의 비슷한 효과를 가져옵니다.

Reference

https://www.webtips.dev/webtips/html/what-is-the-difference-between-async-and-defer

https://youtu.be/tJieVCgGzhs

반응형