script 로딩방법-async와 defer의 특징과 장단점

hannah·2023년 9월 15일
0

JavaScript

목록 보기
85/121

html 문서에서 src 속성의 외부 스크립트 script 를 로딩 할 때 다양한 방법이 존재함

1. <head><script>를 별다른 조건 없이 넣는 경우

스크립트가 모두 로딩 된 후에서야 사용자들은 스크립트 밑의 페이지를 볼 수 있는데 만약 스크립트의 용량이 크다면 로딩 시간이 오래 걸릴 것이고, 그 시간 동안은 페이지 자체를 막아버리기 때문에 (자바스크립트의 기본 옵션은 동기처리) 스크립트에서 DOM 요소에 접근이 불가능해진다.

실행 흐름을 보면, 브라우저가 html 문서를 위에서부터 아래로 쭉 읽는데 여기서 script를 만나면 바로 script 안의 내용을 한 줄 한 줄 해석하기 시작한다. 하지만 위에서 말한 것처럼 script의 내용이 방대할 경우 시간이 오래 걸리고, 자바스크립트는 동기처리가 기본이기 때문에 여기서 스크립트를 다 해석하기 전 까진 다음 body의 내용으로 넘어가지 않는다.

즉, html 문서의 parsing이 지체되기 때문에 사용자 입장에선 스크립트 밑의 html 문서를 제대로 볼 수 없어서 웹페이지 속도가 느리다고 느끼게 된다.

이와 비슷한 방법으로는

2. <body> 안에 <script>를 별다른 조건 없이 넣는 경우

위와는 반대로 html 문서를 빠르게 읽어올 수 있다는 장점이 존재하지만 만약 웹페이지가 자바스크립트에 의존적이라면 (사용자가 자바스크립트가 서버에 있는 데이터를 받아와야 한다든지, 인터랙티브 등) 서버에서 자바스크립트를 받아오는 시간(fetching)과 실행하는 시간(executing) 모두 기다려야 하는 단점이 존재한다.

3. <script>에 defer 추가

<script defer src=""><script>

이 방법은 외부 script를 다운로드하면서 html parsing을 시작하는데 (비동기처리로 동시에 진행됨) 이 단계에선 fetching 만 하고 (일단 실행시키기 직전의 준비만 마쳐놓고) html 다운로드가 모두 끝나서야 미리 받아놨던 외부 script 파일을 실행한다.

즉 스크립트를 다운로드하는 도중에도 html parsing이 멈추지 않고 계속 진행된다.
외부 스크립트 파일을 여러 개 작성했다면 마지막에 작성된 스크립트 파일의 용량이 제일 작아 먼저 다운로드가 되어도 마지막에 작성되었기 때문에 제일 마지막에 실행된다 (script의 실행순서를 정할 수 있다)

defer 방식의 단점은 스크립트가 실행되기 전에 페이지가 화면에 출력된다는 점을 유의해야 한다. 만약 스크립트가 로딩 지연이 될 때 영향을 받는 영역에는 로딩 인디케이터가 존재해야 하며 관련 버튼도 사용 불가 처리를 해줘야 사용자에게 혼란을 주지 않을 수 있다.

  • 참고로 defer 속성은 외부 스크립트에만 유효하여 src 속성을 넣지 않으면 defer 은 무시된다. (내부 script 사용 불가)

4. <script>에 asyn 추가

<script async src=""><script>

위의 defer와는 다르게 async 속성은 페이지와 매우 독립적으로 동작하는 특징을 가진다.

이 방식은 웹브라우저에서 쭉 읽다가 script를 만나면 우선 병렬적으로 실행을 시켜놓은 후 (이것도 비동기처리) 기다리지 않고 그다음 코드들을 쭉 해석한다. 그러다 script 로딩이 완료되면 html parsing을 일단 멈추고 로딩이 완료된 자바스크립트를 실행시킨 후 다시 html parsing을 시작한다.

이로써 defer방식처럼 자바스크립트 다운로드하는 시간을 절약할 수 있다. 하지만 자바스크립트가 html 파싱이 완료되기 전에 실행이 되기 때문에 만약 자바스크립트 파일에서 쿼리셀렉터로 DOM 요소를 조작한다면, 조작하려는 시점에 우리가 원하는 html 요소가 아직 정의되어 있지 않을 수 있다 (위험 가능성 존재)
또한 자바스크립트를 실행하기 위한 html 파싱을 잠시 멈추기 때문에 웹페이지 로딩 속도가 살짝 느리다는 느낌을 받을 수도 있고, 스크립트가 (작성한 순서에 상관없이) 먼저 다운로드 되는 순서대로 실행을 하기 때문에 스크립트 실행 순서에 의존적이라면 문제가 될 수 있음. (a-b-c 순서로 실행되어야 하는데 b가 먼저 다운되면 b-a-c로 로딩되어버림)

5. async와 defer 차이점 명확하게 이해하기

defer

  • defer 방식은 스크립트 로딩이 완료돼도 무조건 html parsing이 끝난 후 스크립트를 실행시킨다
  • defer 방식은 먼저 작성된 스크립트가 마지막에 작성된 스크립트보다 늦게 로딩 되어도 먼저 실행시킨다 (실행 순서를 지킴)
  • defer방식은 DOM 전체가 필요한 스크립트나 실행 순서가 중요한 경우에 사용하는 것이 적합하다

async

  • async 방식은 스크립트 로딩이 완료되면 html parsing이 끝나지 않아도, 잠시 멈춰놓고 일단 스크립트를 실행시킨다
  • async 방식은 마지막으로 선언된 스크립트 파일이 제일 먼저 선언된 스크립트 파일보다 먼저 다운로드 되면 순서에 상관없이 먼저 실행되고, 이렇게 먼저 로드 된 스크립트가 먼저 실행되는 걸 'load-first order'라고 부른다
  • async는 '마이웨이'를 생각하면 된다.
  • 그래서 async 방식은 방문자 수 카운터, 광고 관련 스크립트처럼 각 독립적인 역할을 하는 서드파티 스크립트를 현재 개발 중인 스크립트에 통합하려 할 때 아주 유용하다 (async 스크립트는 개발 중인 스크립트에 의존하지 않고, 그 반대도 마찬가지이기 때문)

0개의 댓글