들어가며
HTML의 스크립트 요소 <script>는 JavaScript 코드를 포함하거나 외부 스크립트 파일을 불러오는 역할을 수행합니다. 우리는 이러한 <script> 요소를 통하여 웹 페이지에 동적 기능과 인터랙티브한 요소들을 추가할 수 있습니다.
이러한 script 요소에는 많은 속성이 존재하는데 본 포스팅에서는 그 중에서 async와 defer에 대하여 알아보고자 합니다.
async와 defer 속성을 사용하는 이유는 무엇일까?
https://what-time.tistory.com/50
[SEO] script 태그는 html에서 어디에 넣는 것이 가장 좋을까?
시작하며 현재 진행 중인 프로젝트의 성능 개선을 위하여 가장 많은 사용자가 진입하고, 많은 로직을 처리하는 홈 부분부터 차근차근 개선을 시작하기로 하였습니다. Request Waterfall을 보며 특별
what-time.tistory.com
이전에 포스트로 한 번 다룬 적이 있었던 내용과 연관이 있습니다. 기본 <script> 요소는 스크립트 로드 및 실행을 동기로 진행하게 되기 때문에 html 문서 속 위치에 따라 html 문서 파싱이 블로킹될 수 있는 위험을 가지고 있습니다.
이러한 Parser Blocking 현상을 피하기 위해서는 html 문서 속 <script> 요소의 위치를 body 태그 최하단으로 이동시키거나 async, defer 속성을 부여하는 방법을 채택할 수 있습니다.
async 스크립트 vs defer 스크립트
async 스크립트와 defer 스크립트의 차이점은 위 사진을 통하여 시각적으로 간단하게 확인이 가능합니다(편의상 async 스크립트는 비동기, defer는 지연이라고 하겠습니다).
지연 스크립트는 HTML 파싱과 병렬로 다운로드(fetch)가 되며, 파싱이 완료될 때까지 실행(excute)이 '지연'됩니다. 사진 속에서도 fetch가 완료되었으나 parse가 완료될 때까지 excute가 지연되는 것을 볼 수 있습니다.
- 지연 스크립트는 DOM이 준비된 후(HTML 파싱이 완료된 후)에 실행됩니다.
- 지연 스크립트는 DOMContentLoaded 이벤트 발생 전에 실행됩니다.
- 여러 지연 스크립트가 있으면 작성된 순서대로 실행되어 실행 순서가 보장됩니다.
비동기 스크립트는 HTML 파싱과 병렬로 다운로드(fetch)가 되며, 스크립트가 완료된 시점에서 실행(excute)됩니다. 즉, 지연 단계가 따로 없으며 스크립트를 실행되는 동안에는 Parser Blocking이 됩니다.
- 동적 스크립트는 다른 요소 어느 것도 기다리지 않으며 역으로 다른 요소들도 동적 스크립트를 기다리지 않습니다.
- 동적 스크립트는 다운로드가 완료된 것 먼저 실행이 되기 때문에 실행 순서가 보장되지 않습니다.
+ ) next/script 덤으로 알아보기
next/script에도 async, defer처럼 선택적으로 strategy를 부여할 수 있습니다. 기본 값은 afterInteractive로 로드는 HTML 파싱 과정과 병렬로 진행하지만 페이지에 hydration이 발생한 뒤에 실행하게 됩니다. 즉, 이 경우에는 Parser Blocking이 발생하지 않으며 defer script와 유사합니다(둘의 차이점은 defer script는 스크립트 실행 시점이 HTML 파싱 이후이며 afterInteractive script는 hydration 이후입니다).
beforeInteractive는 async script와 유사합니다. HTML 파싱 도중 로드와 실행을 둘다 한다는 점에서는 같지만 beforeInteractive의 경우엔 해당 스크립트를 순차적으로 실행한다고 합니다. async script는 로드가 완료된 후에 즉시 실행한다는 점에서 순서가 보장되지 않는다는 차이점이 있습니다.
추가로 lazyOnLoad까지 가볍게 알아보자면 이는 window.onload 이벤트가 발생한 직후에 실행하는 스크립트와 유사하다고 볼 수 있습니다. 해당 스크립트가 중요한 초기화 스크립트가 아닌 경우에는 해당 전략도 적용해볼 수 있을 것 같습니다.
'Web' 카테고리의 다른 글
[Github Action] 공짜로 Github Organization 저장소 vercel 배포하기 (0) | 2024.12.05 |
---|---|
[Pattern] Ealry return pattern에 대하여 알아보자 (0) | 2024.12.04 |
[UX/UI] '마지막으로 로그인한 소셜 계정' 어떻게 관리하는 것일까? (0) | 2024.12.03 |
[Webview] foreground, background 전환 감지하기 (0) | 2024.12.02 |
[Next.js] next/head 안에 next/script를 넣으면 동작하지 않는다? (0) | 2024.11.27 |