[자바스크립트][엘리] script async와 defer

2020. 7. 20. 13:57TIL/자바스크립트

자바스크립트 공부를 시작한 지 채 3일이 안되었을 때,

잘은 모르지만 굉장히 좋은 내용이라는 생각이 든 유튜브 채널을 발견하여서 몇 가지 강의를 들어 보았다.

해당 내용들은 나와 같은 입문자들이 짚고넘어가면 좋을 내용들인 것 같다.

가장 먼저, script 파일이 html코드 내에서 적용될 때

어느 시점에서 js파일을 다운로드받고, 어느 시점에서 js파일을 실행할지에 대한 내용을 들었다.

 

 

먼저, HTML에서 자바스크립트 코드를 실행시키는 방법은 <script> 태그를 이용하는 방법이 있다. 

아래와 같이 scipt 태그의 src속성에 js파일을 지정함으로써 해당 내용을 불러올 수 있다. 

script태그를 어디에 위치시키느냐에 따라, 또는 async와 defer 키워드의 사용 유무에 따라 js파일을 다운로드하고 실행시키는 시점이 달라지는데, 어느 경우가 가장 효율적인 방법인지 살펴보았다.

 

 

1. head태그에 위치 + no keyword

위와 같은 경우 어떤 순서로 클라이언트는 페이지를 얻을까?

친절하신 강사님께서 한눈에 이해할 수 있도록 이와같은 블록 모형을 제시해 주었다.

parsing HTML 과정은 HTML파일을 맨 위에서부터 한 줄씩 아래로 읽어나가는 과정이다. 위 HTML 코드를 화면에 표시하는 과정은 다음과 같다. 

  • 한 줄씩 읽어가며 HTML 문서를 parsing 한다. 
  • script태그를 만나면 HTML parsing을 멈추고 해당 js파일을 다운로드한다.
  • js파일의 다운로드가 끝나면 해당 js파일을 실행한다.
  • js파일의 실행이 끝나면 script태그 이후의 HTML 파일을 다시 parsing 한다.

이렇게 head태그에 바로 script태그를 넣을 경우 아래와 같은 단점이 있다.

  • 만약 js파일이 매우 크거나, 인터넷 속도가 매우 느릴 경우에는 사용자가 해당 페이지를 보는데 많은 시간이 걸리게 된다. 

 

2. body태그 맨 밑에 위치 + no keyword

 

두 번째 경우는, 1번의 단점을 고려하여 페이지가 전부 준비가 된 후 js파일을 다운로드하고 실행하는 경우이다.

이렇게 하면 사용자가 페이지의 기본적인 콘텐츠를 js파일을 다운로드하기 전에 미리 볼 수 있지만, 바꿔 말하면 js파일의 영향을 받는 콘텐츠들은 볼 수 없다는 의미이다. 그렇게 js에 의존적인 콘텐츠가 많으면 많을수록 결국 1번과 비슷한 맥락으로 바뀔 수 있다. 

 

3. head태그 + async

script태그를  head에 위치시키는 대신 async라는 키워드를 사용할 경우 위와 같이 진행이 된다.

HTML 파일을 위에서부터 한 줄씩 parsing 하다가 script태그를 만날 경우, js파일을 다운로드하는 행위를 병렬적으로 진행한다. 즉, 1번에서 parsing을 멈추고 js파일 다운로드를 시작했던 것과 달리 parsing HTML 작업과 fetching js 작업이 병렬적으로 이루어지는 것이다. 이후 js파일이 다운로드가 완료가 되면 그때서야 parsing HTML과정을 멈추고 js파일 실행을 한다. 블록 모형만 봐도 1번보다 훨씬 효율적이라는 것을 알 수 있다. 하지만 여전히 단점은 존재한다. html을 완전히 parsing하지 않은 상태에서 js파일이 실행되기 때문에 그 시점에 parsing 되지 않은 부분에 대한 문제가 생길 수 있다. 

 

4. head + defer

 

 위의 단점들을 모두 보완한 방법이라고 할 수 있는 head+defer 조합이다. 

블록 모형에서 이해할 수 있듯이  js파일 다운로드는 병렬적으로 처리하고, 실행은 HTML parsing이 끝난 후 이루어지는 것이다. 이렇게 하면 3번에서 문제가 될 수 있었던, 아직 parsing 되지 않은 HTML을 js로 조작하려고 시도하는 것도 막을 수 있다.

 

다운로드하여 실행시켜야 하는 js파일이 여러 개인 경우에는 defer의 강점이 더욱 두드러진다.

async를 사용하는 경우, js파일 다운로드가 일찍 끝난 순서대로 실행되기 때문에 순서에 민감한 각각의 js파일에 대하여 문제가 발생할 수 있지만, defer의 경우 동시에 js파일 다운로드를 시작하더라도 먼저 실행될 것을 더 위쪽에 위치시킴으로써 순서 문제를 해결할 수도 있다.

----------------------------------------------------------------------------------------------------------------------------

 

HTML의 parsing과정과 더불어 이 영상에서 배운 다른 한 가지는 'use strict';였다.

자바스크립트는 타입에 관하여 매우 유연함과 동시에 위험성을 가지고 있다. (타입 실수를 하기 너무 쉽다.)

이때 js파일의 가장 상단에 'use strict';를 선언해주면 타입과 관련된 문제를 좀 더 엄격하게 검사해준다. 물론 타입 스크립트를 사용할 경우 'use strict'를 하지 않아도 타입에 대해 안정적일 수 있지만, 순수 바닐라 js를 사용할 경우 이와 같은 방법을 통해 좀 더 실수를 줄일 수 있다고 한다.