익명의 개발노트

[Browser] async, defer 차이 본문

코딩일기/TIL

[Browser] async, defer 차이

캡틴.JS 2021. 9. 3. 21:38
반응형

브라우저가 Html파일을 랜더링 할 때,  맨 위에서 아래로 한줄한줄 읽으면서 실행한다.

script 태그가 없으면, 브라우저는 parsing HTML만 진행을 할 것이다.

그럼 아래와 같이 head 부분에 script가 있으면??

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="test.js"></script>
</head>
<body>
    
</body>
</html>

head에 스크립트 태그가 있을때 과정

위와 같이 HTML을 먼저 파싱하고, 자바스크립트를 fetch, executing 하는동안 HTML 파싱은 잠시 중지하고, 스크립트 실행이 끝나면

남은 HTML을 파싱한다.

아래와 같이 Body에 있는 경우는 어떠할까?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
     <script src="test.js"></script>
</body>
</html>

위와 같이 HTML 파싱이 다 끝나면, 스크립트를 fetch, executing한다.

body에는 위와 같은 순서대로 진행되기때문에 async, defer가 거의 의미가 없다.

그러면, async와 defer를 쓰면 무슨차이가 있을까?

우선 Async를 먼저 보자.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="test.js" async></script>
</head>
<body>
    
</body>
</html>

HTML parsing과 Script fetch가 병렬로 실행되면서, fetch가 끝나면 스크립트를 실행한다. 그리고 실행하는동안 멈췄던 HTML을 마저 parsing한다.

헤더부분에서 미리 필요한 js를 다운받기때문에 시간절약이 가능하지만, 자바스크립트 파일에 DOM 조작 부분이 있으면 시점을 맞추는데 애로사항이 있고, script를 실행하는 시간동안 사용자가 페이지를 보는데 시간이 걸린다.

순서대로 실행하는 스크립트를 실행하는 곳에는  async를 쓰지 않는다.

만약 스크립트가 여러개라면? 아래와 같이 작동할 것이다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="A.js" async></script>
    <script src="B.js" async></script>
</head>
<body>
    
</body>
</html>

head에 defer를 사용하게 되면?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="test.js" defer></script>
</head>
<body>
    
</body>
</html>

defer를 사용하면, 스크립트 fetch까지만 병렬로 진행되며, HTML parsing이 끝난 후에 스크립트를 실행할 것이다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="a.js" defer></script>
    <script src="b.js" defer></script>
    <script src="c.js" defer></script>
</head>
<body>
    
</body>
</html>

여러개인 경우는 HTML 파싱이 끝난 후 스크립트를 등록한 순서대로 실행을 한다. (a-> b-> c)

프로세스 상으로 봤을때, head+defer를 사용하는게 제일 효율적이다.

반응형
Comments