웹사이트의 성능을 향상시키는 것은 중요하다. 페이지의 로딩 속도와 콘텐츠 로딩속도가 사용자 경험에 영향을 미치기도 하고, Google의 연구에 따르면 FID(First Input Delay), CLS(Cumulative Layout Shift) 등의 성능을 개선하면 페이지 이탈률이 24% 감소한다고 한다.
보고서 링크
https://blog.chromium.org/2020/05/the-science-behind-web-vitals.html
이러한 성능 지표를 개선하는 한 방법은 JavaScript 로딩 전략을 최적화하는 것이다. <script>, <script async>, <script defer>는 페이지 로딩 속도에 영향을 미치는 스크립트 태그 옵션들이다. 이 세 가지 옵션의 동작 방식과 각기 다른 상황에서 어떤 옵션을 선택해야 하는지 알아보자.
<script> 만 사용할 경우<head> 또는 <body>안에 있을 수 있다.<head>보다는 <body> 태그 끝에 위치시키는 게 좋다.<script async><head>태그안에 위치한다.<script async>은 다운로드가 완료되는 즉시 실행되기 떄문에 script가 여러개인 경우 이들의 실행순서가 보장되지 않는다.따라서 <script async>를 여러 개 사용할 경우 script 간의 의존성을 먼저 확인하고, 가능한 한 각 script가 독립적으로 기능하도록 하여야 한다.<script defer>위치: 주로 <head>태그안에 위치한다.
동작: script의 다운로드와 HTML 파싱이 병렬로 진행된다. async와 달리 HTML 파싱이 전부 끝난 후 DOMContentLoaded 이벤트가 발생하기 바로 전에 실행된다.
사용: 외부 script를 불러올 때 사용한다. DOM이 준비된 후 실행되기 때문에 DOM 조작이 필요한 script에 적합하다.
주의할 점
1. 외부 script를 불러오는 것이 아니라 Inline Script에 defer속성을 사용하면 무시된다. Inline Script는 HTML 문서가 파싱될 때 해당 위치에서 즉시 실행되기 때문이다.
2. 브라우저는 <script defer> 태그를 발견한 순서대로 script를 실행하기 때문에, 서로 의존성을 가진 여러 개의 script가 있다면 올바른 순서로 배치하는 것이 중요하다. 이렇게 하면 script들이 의도한 순서대로 실행될 수 있다.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Script Loading Demo</title>
<script>
console.log("1. Without async or defer, in head");
</script>
<script async src="async-script.js"></script>
<script defer src="defer-script.js"></script>
</head>
<body>
<script>
console.log("2. Without async or defer, in body");
</script>
<script>
// HTML이 완전히 로드되었을 때(DOM트리가 구성되었을 때) 발생
document.addEventListener("DOMContentLoaded", function () {
console.log("4. DOMContentLoaded event raised");
});
</script>
<script>
// 모든 요소(이미지, 스타일, 폰트, 스크립트 등)가 로드되었을 때 발생
window.onload = function () {
console.log("5. Load event raised");
};
</script>
</body>
</html>
async-script.js
console.log("3. Async script loaded");
defer-script.js
console.log("3. Defer script loaded");

만약 부정확한 내용이 있다면 댓글로 알려주세요. 수정하겠습니다.