스크립트를 <body>태그 위에 연결하게되면 아직 브라우저가 HTML을 다 읽지 못한 상태여서 DOM요소에 접근할 수 없는 문제가 생긴다. 문제를 해결하기 위해 body태그 최하단에 넣어줬는데 강의를 듣다가 defer를 사용하는 방법도 있다는걸 알게 되었다.

실제로 defer를 사용하는지 궁금해서 찾아보다가 link태그에 사용되는 rel=”preload”와 rel=”prefetch”도 보게 되었다.

그럼 defer와 async, preload, prefetch는 어떻게 다르고 어떤 경우에 사용할까?

먼저 defer와 async를 정리하자면,

defer를 넣어주게 되면 브라우저가 스크립트를 다운로드 받게되는데 HTML을 다 읽고나서 스크립트를 읽기 시작한다.

만약 여러개의 스크립트라면 defer는 순서를 지켜서 sample1 > sample2 순으로 스크립트를 읽는다.

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

async는 브라우저가 스크립트를 다운받게되는데 만약 HTML을 아직 다 읽지 못한 상태에서 스크립트 다운로드가 완료되면 브라우저는 HTML읽는 것을 중단하고 스크립트를 읽게된다. 이렇게되면 defer나 asnyc가 없을때처럼 DOM요소에 접근 할 수 없게 된다.

그리고 여러개의 스크립트를 만나면 asnyc는 스크립트 순서와 상관없이 먼저 다운받아지는 스크립트를 읽게된다.

sample2에서 sample1에 있는 함수를 사용하고 있는데 sample2가 먼저 실행된다면 문제가 된다.

<script async src="sample1.js"></script>
<script async src="sample2.js"></script>

참고

async and defer are two attributes for the <script> tag but preload and prefetch are valid values for rel attribute of the <link> tag.

Async