스크립트 로딩 전략

김동현·2023년 2월 27일
1

자바스크립트

목록 보기
6/22

스크립트를 로드하는 시간에 따라 여러 가지 문제점이 발생한다.

가장 흔한 문제점 중 하나는 HTML코드가 표시된 순서대로 로드되어서 생기는 문제점이다.

페이지의 엘리먼트를 조작하기 위해 (정확히는 DOM을 조작하는) 자바스크립트를 사용하는 경우를 생각해보자.

조작대상이 되는 엘리먼트보다 자바스크립트가 먼저 로드 및 구문 분석이 되어버리면 코드가 제대로 동작하지 않는다.

A라는 엘리먼트를 삭제 및 수정하는 스크립트일 경우 스크립트보다 A라는 엘리먼트가 먼저 로드가 되어야 하기 때문이다.

또한, 스크립트가 로드되는 동안엔 HTML 로드 및 구문분석이 중지되기 때문에 만약 용량이 큰 스크립트를 로드하게 된다면 페이지 렌더링이 늦어질 수 있다.

이 문제들을 해결하는 몇 가지 방법을 알아보자.

Internal Javascript

document.addEventListener('DOMContentLoaded', () => {
  // …
});

HTML body가 완전히 로그되고 구문분석이 되면 DOMContentLoaded 이벤트가 발생한다.

따라서 DOMContentLoaded 이벤트를 감지하는 이벤트 리스너를 document에 달아줌으로써, HTML이 모두 로드되었을때 해당 블록이 실행되게 만든다.

External Javascript

External Javascript에서도 Internal Javascript에서 처럼 "DOMContentLoaded"이벤트를 사용해서 작성할 수 있지만 좀 더 모던한 defer 라는 좋은 기능이 있다.

defer 는 script태그의 어트리뷰트이다.

이는 HTML 로드 도중에 defer가 적용된 script를 만나면 스크립트와 HTML을 동시에 다운로드하도록 시킨다.

<script src="script.js" defer></script>

External 케이스에서는 defer 덕분에 DOMContentLoaded 이벤트를 사용할 필요가 없다.
Internal 케이스에서는 defer 를 사용할 수 있는 방법이 없기 때문에 DOMContentLoaded 이벤트를 사용해야 한다.

이 문제대 대한 옛날식 해결방법은 모든 HTML 을 구문분석한 후에 script가 로드되도록 스크립트 태그를 body 태그의 닫는 태그 부분 바로 앞에 배치하는 것이다.

하지만, 이 방법의 문제점은 HTML DOM이 로드 완료될때까지 스크립트 로드 및 구문분석이 완전히 차단된다는 점이다.

자바스크립트가 많은 큰 사이트에서는 이로인해 주요 성능 문제가 발생하여 사이트 속도가 느려질 수 있다.

async and defer

차단 스크립트의 문제점을 우회하는데 사용할 수 있는 최신 기능이 2가지 있다.

그중 하나가 위에서 언급한 defer 이고 나머지 하나는 async 이다.

async 어트리뷰트를 사용한 스크립트는 스크립트를 가져오는 동안 HTML 로드 및 구문분석을 차단하지 않고 스크립트를 다운로드 한다.

이 까지는 defer 와 동일하다.

그러나 스크립트의 다운로드가 완료되면 바로 스크립트가 실행되면서 페이지 렌더링을 차단한다.

또한 async 는 스크립트가 특정 순서로 실행된다는 보장이 없다.

그러므로 페이지의 스크립트가 서로 독립적인 경우 async 를 사용하는 것이 가장 좋다.

그에 반해, defer 어트리뷰트는 페이지에 나타나는 순서대로 로드되고 실행된다.

또한 페이지 내용이 모두 로드될 때까지 실행되지 않는다.

따라서 스크립트가 DOM에 의존하는 경우에 defer 를 사용하는 것이 좋다.

아래의 이미지는 asyncdefer 의 로드 및 실행 시간을 시각적으로 보여준다.

async와 defer의 로드 및 실행 타이밍

예를 들어 다음과 같은 스크립트 태그가 있다고 가정해보자.

<script async src="js/vendor/jquery.js"></script>
<script async src="js/script2.js"></script>
<script async src="js/script3.js"></script>

HTML이 로드되면서 async가 적용된 스크립트 3개를 만나게 된다.

차례대로 로드를 시작하겠지만 먼저 로드완료된 스크립트가 먼저 실행된다.

따라서 순서에 의존적인 스크립트일 경우 오류가 발생한다.

async는 로드할 백그라운드 스크립트가 많이 있고 그것들이 가능한 빨리 로드되기를 원할 때 사용해야 한다.

예를 들어, 게임을 시작할때 필요한 게임 데이터 같은 경우 가능한 빨리 로드되어야 하지만, 당장은 게임 소개 및 제목만 보여주기때문에 독립적으로 로드되어도 상관없다.

이럴때 async 를 이용한다.

[참고] : MDN

profile
프론트에_가까운_풀스택_개발자

0개의 댓글