jsNote 01: async와 defer

13567 단어 jsNotejsNote

Q. HTML에서 js를 어떻게 출력하는 것이 효율적인지?


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="js.js"></script>
</head>
<body></body>
</html>

(1) 위처럼 head 안에 script가 들어있으면 html을 parsing하다가 script가 나오면 바로 js를 다운로드(fetching), 실행(executing)한다. 이후 남은 html을 parsing 하게 되므로 시간이 많이 소요될 수 있다. 다시 말해 parsing html - parsing blocked while fetching/executing js - parsing html - page is ready 순으로 진행된다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script src="js.js"></script>
</body>
</html>

(2) body 끝에 script가 들어있으면 html을 전부 parsing 한 다음 script를 다운, 실행한다. 이 때 사용자가 기본적인 html의 컨텐츠를 빨리 볼 수 있지만 웹사이트가 js의 의존도가 높을 때 오래 기다려야 한다는 단점이 있다. parsing html - page's ready - fetching js - executing js 순으로 진행된다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script async src="a.js"></script>
    <script async src="b.js"></script>
    <script async src="c.js"></script>
</head>
<body></body>
</html>

(3) head 안에서 async 값(=boolean 타입)을 쓰면 html parsing을 하다가 병렬로 js를 다운받자고 명령만 해놓고 계속 parsing을 진행한다. 다운이 완료되면 html parsing을 멈추고 다운로드 된 js를 실행한 후 나머지 html을 실행한다. body 끝에 사용할 때보다 다운로드 받는 시간을 절약할 수 있다 하지만 js가 parsing 되기 전에 실행되므로 만약 js에서 queryselector를 이용해서 dom 요소를 조작한다면 html에서 정의되지 않았을 수도 있다. 사용자가 페이지를 보는데 여전히 시간이 걸린다. 먼저 다운받아진 js가 실행되기 때문에 js가 여러 개이며 a가 b보다 먼저 실행되어야 한다면 좋지 않을수도 있다. parsing html while fetching a/b/c - 다운된 a/b executing (parsing은 block) - parsing html - 다운된 c excuting - parsing html - page's ready 순으로 진행된다.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script defer src="a.js"></script>
    <script defer src="b.js"></script>
    <script defer src="c.js"></script>
</head>
<body></body>
</html>

(4) head 안에서 defer라는 옵션을 쓰면 중간에 다운 명령만 시켜놓고 html parsing이 끝나면 js 실행. 사용자에게 페이지를 보여준 뒤 다운된 js를 실행하며 가장 좋은 옵션이다. parsing html while fetching a/b/c - page's ready - executing a - excuting b - executing c 순으로 진행된다.

좋은 웹페이지 즐겨찾기