<script>요소의 위치에 따른 차이점

holang-i·2023년 2월 14일
1

참고

defer, async 스크립트
DOMContentLoaded, load, beforeunload, unload 이벤트

모던 JavaScript 튜토리얼을 학습하고 정리한 글입니다.

모던 웹브라우저에서 돌아가는 스크립트들은 대부분 HTML보다 '무겁고' 용량이 크기 때문에 다운로드 받는 데 시간이 오래 걸리고 처리하는 것도 마찬가지로 오래걸릴 수 있다.

브라우저는 HTML을 읽다가 <script>...</script> 태그를 만나면 스크립트를 먼저 실행해야 하기 때문에 DOM 생성을 멈추게 된다.

이는 src 속성이 있는 외부 스크립트 <script src="..."></script>를 만났을 때도 마찬가지로 동작한다.

<p>... 스크립트 앞에 있는 컨텐츠</p>
<script src="https://..."></script>
<p>... 스크립트 뒤 컨텐츠</p>

위와같은 브라우저의 동작 방식은 두 가지 중요한 이슈를 만드는데
1. 스크립트에서는 스크립트 아래에 있는 DOM 요소에 접근할 수 없다. 따라서 DOM 요소에 핸들러를 추가하는 것과 같은 여러 행위가 불가능하다.
2. 페이지 위쪽에 용량이 큰 스크립트가 있는 경우 스크립트가 페이지를 '막아버립니다.' 페이지에 접속하는 사용자들은 스크립트를 다움받고 실행할 때 까지 스크립트 아래쪽 페이지를 볼 수 없게 된다.

이런 부작용들을 피할 수 있는 몇 가지 방법이 있다.

첫 번째 방법으로는 태그가 끝나기 바로 직전에 놓는 방법이다.

스크립트를 페이지 맨 아래 놓는 것이 하나의 방법이 될 수 있다. 이 방법을 사용하면 스크립트 위에 있는 요소에 접근할 수 있고, 페이지 컨텐츠 출력을 막지 않는다.

<body>
  ... 스크립트 위 컨텐츠들...
  <script src="https://..."></script>
</body>



defer, async 스크립트

위에서 정리한 첫 번째 방법은 완벽한 해결책이 될 수 없다. HTML 문서가 아주 큰 경우를 가정했을 때 브라우저가 HTML 문서 전체를 다운로드한 뒤 스크립트를 다운받게하면 네트워크 속도(또는 모바일 네트워크 접속)가 열악한 곳의 경우 페이지가 느려질 수 있다.

이러한 문제를 해결할 수 있는 <script> 속성이 있는데 deferasync이다.

defer

브라우저는 defer 속성이 있는 스크립트를 '백그라운드'에서 다운로드 한다.
따라서 defer(지연) 스크립트를 다운로드하는 도중에도 HTML 파싱이 멈추지 않는다. 그리고 defer 스크립트 실행은 페이지 구성이 끝날 때 까지 지연된다.

  • 지연 스크립트는 일반 스크립트와 마찬가지로 HTML에 추가된 순(상대순, 요소순)으로 실행된다.
  • 길이가 긴 스크립트가 앞에, 길이가 짧은 스크립트가 뒤에 있어도 짧은 스크립트는 긴 스크립트가 실행될 때 까지 기다린다.
  • 작은 스크립트는 먼저 다운되지만, 실행은 나중에 된다.
  • defer 속성은 외부 스크립트에만 유효하다. (<script>src가 없으면 defer 속성은 무시된다.)



async

async 속성이 붙은 스크립트는 페이지와 완전히 독립적으로 동작한다.
async 스크립트는 defer 스크립트와 마찬가지로 백그라운드에서 다운로드 된다. 따라서 HTML 페이지는 async 스크립트 다운이 완료되길 기다리지 않고, 페이지 내 컨텐츠를 처리, 출력한다. (하지만 async 스크립트 실행중에는 HTML 파싱이 멈춘다. - 옮긴이)

  • 다른 스크립트는 async 스크립트를 기다리지 않는다. async 스크립트 역시 다른 스크립트들을 기다리지 않는다.
  • 이러한 특징으로 페이지에 async 스크립트가 여러 개 있는경우, 그 실행 순서가 제각각이 된다. (실행은 다운로드가 끝난 스크립트 순으로 진행된다.)



요약

asyncdefer 공통점

asyncdefer 스크립트는 다운로드 시 페이지 렌더링을 막지 않는다는 공통점이 있다.
따라서, asyncdefer를 적절히 사용하면 사용자가 오래 기다리지 않고 페이지 컨텐츠를 볼 수 있게 할 수 있다.


asyncdefer 차이점

비교순서DOMContentLoaded
asyncload-first order. 문서 내 순서와 상관없이 먼저 다운로드 된 스크립트가 먼저 실행된다.비동기 스크립트는 HTML 문서가 완전히 다운로드 되지 않은 상태라도 로드 및 실행될 수 있다. 스크립트 크기가 작거나 캐싱 처리 되어있을 때 혹은 HTML 문서 길이가 아주 길 때 발생한다.
defer문서에 추가된 순지연 스크립트는 문서 다운로드와 파싱이 완료된 후에, DOMContentLoaded 이벤트 발생전에 실행된다.
profile
🌿 주니어 프론트엔드 개발자입니다! 부족하거나 잘못된 정보가 있다면 알려주세요:)

0개의 댓글