script, script async, script defer

Hyeon·2021년 11월 25일
0

script

브라우저가 html 문서를 파싱하다 script 태그를 만나면, 파싱을 중단하고 javascript 파일을 로드, 실행한다. 과정이 완료되면 그 후에 HTML 파싱을 계속한다.

script 태그의 위치에 따른 차이점에 대해 정리해보자.

script태그는 html 파일 내부 어디든 위치할 수 있지만, 크게 head내부와 body태그의 마지막으로 나눌 수 있다.

head 내부의 script

body 태그 내부를 파싱해 DOM트리를 생성하기전에 먼저 script를 로드하고 실행한다.

문제점

  1. script 파일이 크거나 개수가 많으면 로드, 실행하는데 시간이 오래걸리고 그만큼 사용자가 화면을 보는것(렌더링)이 지연된다.
  2. script 에 dom 요소를 조작하는 로직이 있다면 존재하지 않는 dom에 접근하려고 했기 때문에 문제가 생길수 있다.

해결방안

  1. DOMContentLoaded 이벤트를 사용한다. DOM 생성이 끝난다음 실행된다.
  2. window 객체의 onload 메서드를 오버라이딩한다. 문서에 포함된 모든 리소스(img, style, script..)가 로드된 후 실행된다. 따라서 DOMContentLoaded가 더 빠르다.
  3. body 하단에 script를 사용한다.
  4. async, defer 속성을 사용한다.

body 하단의 script

html 파싱이 끝난 다음 script를 다운로드하고, 실행한다.

장점- script를 다운로드하기 전 html 코드를 파싱하기 때문에 사용자가 화면을 빨리 볼 수 있다.

문제점

  1. html이 script에 의존적(데이터 패칭, dom 조작, 이벤트..)라면 사용자가 보는 시점에 아직 완성되지 않은, 의미가 없는 페이지를 볼 수 있다.
  2. html 문서, 크다면 브라우저가 HTML 문서 전체를 다운로드 한 다음에 스크립트를 다운받게 했을 때 페이지가 느려진다. script가 커도 마찬가지.

해결방안 - async, defer 속성을 사용한다.

head에 async 속성의 script

async는 html파일을 파싱하다 script 태그를 만나면 html를 파싱하는 동시에 script를 로드한다. 이후 실행시키는데, 실행시키는 동안에는 html파싱이 멈추게 된다. 실행이 완료된 이후 나머지 html을 파싱한다.

장점 - body 태그의 끝에 위치시켰을 때와 달리 script의 로드가 html파싱과 병렬적으로 이루어지기 때문에 다운로드 시간을 단축시킬 수 있다.

문제점

  1. script 로드가 완료되면 html 파싱을 멈추고 스크립트를 실행한다. 따라서 존재하지 않는 dom에 접근 할 수 있다.
  2. 순서에 상관 없이 먼저 다운로드 받아지는 script를 먼저 실행시키기 때문에 해당 프로젝트가 script파일의 실행순서에 영향을 받으면(scope등) 문제가 될 수 있다.

따라서 async 스크립트는 DOM에 직접 접근하지 않거나, 다른 스크립트에 의존적이지 않은 스크립트들을 독립적으로 실행해야 할 때 효과적이다. ex) google analytics

head에 defer 속성의 script

defer는 HTML을 파싱하다 script 태그를 만나면 async와 마찬가지로 html을 파싱하면서 script를 로드한다. 다만 이를 바로 실행시키는 async와 달리 html파싱이 모두 완료된 이후 스크립트를 실행한다.

장점

  1. 파싱 모두 완료된 후 실행되기 때문에 존재하지 않는 dom에 접근 하지 않는다.
  2. 로드와 파싱이 동시에 이루어지기 때문에 body태그를 마지막에 위치시키는 것보다 의미없는 페이지를 보고있는 시간이 줄어든다.
  3. 다수의 script태그를 사용했을 때, script가 순서대로 실행된다. 따라서 실행순서에 영향을 받아도 무관하다.

결론

무조건 defer가 좋은것은 아니다.

DOM이나 다른 스크립트에 의존성이 없고, 실행 순서가 중요하지 않은 경우라면 async

DOM이나 다른 스크립트에 의존성이 있고, 실행 순서가 중요한 경우라면 defer

0개의 댓글