header wave

Post

JS) 효율적으로 script를 fetch하는 방법

2022-09-20 AM 06/47
#javascript
#study

HTML을 parsing 하는 중 script 태그에서 효율적으로 fetching 후 실행하는 방법은 과연 무엇일까?

1) 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="main.js></script>
</head>
<body>

</body>
</html>

일반적인 방법으로 head 태그의 밑에서 js파일을 다운 받는다면 어떻게 될까?

img.png

  1. 브라우저가 한 줄씩 태그들을 분석한다.

  2. CSS와 병합하여 DOM 요소들로 변환한다.

  3. script 태그가 보이면 자바스크립트 파일을 다운 받는다(이때 parsing은 잠시 멈춘다)

  4. 자바스크립트 파일이 실행된다.(이때 parsing은 잠시 멈춘다)

  5. HTML parsing이 계속된다.

단점 : JS 파일 용량이 크다면 fetching 및 사용자가 완성된 페이지를 보는데 시간이 오래 걸린다.

2) body 태크 제일 하단의 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>

</head>
<body>
			<div></div>
    	<script src="main.js></script>
</body>
</html>

img.png

  1. 브라우저가 HTML 태그들을 다 parsing 한 후 script 파일을 다운받아 실행한다.

장점 : JS 파일을 다 fetching 하기 전 페이지를 볼 수 있다.

단점 : : JS파일을 다운 받기 전까지 페이지가 제대로 실행되지 않는다.

(DOM과 연동되는 JS코드가 필요하다면, parsing이 완료 되어도 JS코드가 없으니 실행이 안된다! )

3) 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 asyn src="main.js></script>
</head>
<body>

</body>
</html>

(asyn는 boolean 값이므로 선언하는 것만으로도 true로 설정되어 사용할 수 있다)

img.png

  1. HTML을 parsing 하다가 asyn를 만나면 병렬로 js파일을 다운(이떄 HTML parsing은 잠시 중단) - 실행한다.

  2. 이후 HTML parsing을 계속 한다.

장점 : parsing을 하면서 fetching을 할 수 있기 때문에 다운로드 받는 시간을 줄일 수 있다.

단점

  1. 자바스크립트가 HTML이 parsing 되기 전에 실행되기 때문에 자바스크립트에서 querySelector를 통해 DOM 요소를 조작해야 한다면? 에러위험이 있다.

  2. js 파일을 fetching 및 exectuing 하는 동안 HTML parsing이 blocked 되기 때문에 사용자가 페이지를 보는데 시간이 걸린다.

4) script 태그 + 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 defer src="main.js></script>
</head>
<body>

</body>
</html>

img.png

  1. HTML parsing을 하다가 defer을 만나면 JS를 fetching하면서 HTML parsing 계속된다.

  2. HTML parsing이 끝난 이후 executing이 된다.

async와 defer

async가 여러개 있다면, 정의된 순서가 아닌 다운로드 순서대로 실행된다.

(만약 b.js 전에 a.js가 실행되어야 한다면 에러가 발생할 수 있다)

defer은 parsing 하는 동안 필요한 JS 파일을 다 fetching해둔다.

parsing이 끝난 이후, 스크립트 순서대로 js 파일이 실행된다.

참고 : https://www.youtube.com/watch?v=tJieVCgGzhs (드림코딩 엘리 유튜브 영상)