브라우저의 동작방식
위는 사파리 브라우저에서 처리되는 webkit 렌더링엔진의 처리과정이다.
Browser의 동작과정은 보통 이런 과정을 거친다.
HTML을 parsing해서 DOM Tree를 만들고, CSS를 parsing해서 CSS Object Model을 만든다.
그리고 이 둘을 합쳐서 rendering 해서 web page로 보여준다. 이 때, HTML코드에서 JavaScript를 언제, 어떻게 불러올지에 따라 웹페이지의 실행속도와 성능이 차이날 수 있다.
기본적으로 HTML에서 JS를 불러오면 js fetching(다운) js executing(실행)의 과정을 거쳐서 모든 HTML parsing이 끝나면 web page가 보여질 준비를 마치게 되고, js executing까지 끝나야 페이지가 정상적으로 동작된다.
1. head 끝부분
HTML head의 코드가 모두 실행된 뒤, body의 코드가 실행되기 전에 JavaScript를 다운받고 실행한 뒤, 나머지 HTML 코드들을 받아온다. JS의 크기가 큰 경우, 전체 웹 페이지를 보여주는데 시간이 매우 오래 걸릴 수 있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="main.js"></script>
</head>
<body>
</body>
</html>
2. body 끝부분
HTML만 먼저 보여주고 JS는 나중에 다운받고 실행하기 때문에 만약 JS가 화면에 필요한 여러 중요한 동작들을 수행한다면, 개발자가 의도한 페이지의 동작을 다 보여주기에는 여전히 느리다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div></div>
<script src="main.js"></script>
</body>
</html>
3. head + async
head에서 async를 사용하면 HTML을 parsing할 때 JS fetching도 병렬적으로 실행되기 때문에 동작시간을 그만큼 줄일 수 있는 장점을 가진다.
그러나 async를 사용할때 가장 큰 단점은 async를 여러개 사용했을때, 병렬적으로 js executing, js fetching이 동작하게 되고 fetching이 먼저 끝난 순서대로 JS가 실행되기 때문에 우리가 설정한 순서대로 프로그램이 동작하지 않을 가능성이 존재한다는 점이다.
아래 예제에서 b가 a보다 fetching이 먼저 끝난다면, b의 js executing이 a보다 먼저 실행된다.(순서 역전)
<!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>
4. head + defer
HTML parsing할때 모든 js fetching들이 병렬로 동작하고, HTML parsing이 완료되는 순간 js executing을 코딩한 순서대로 실행하기 때문에 가장 빠르고 순서도 지킬수 있는 방법이다.
<!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>
결론: head 끝부분에 defer를 사용해서 JavaScript를 불러오자!
참고자료
'JavaScript' 카테고리의 다른 글
[JS] reduce() 사용법 (0) | 2021.08.28 |
---|---|
[JS] All about Function (0) | 2021.07.31 |
[JS] forEach()와 map() 차이점 (2) | 2021.07.27 |
[JS] JavaScript Operator (0) | 2021.07.24 |
[JS] 'use strict' 사용 이유와 변수선언 const, let, var (0) | 2021.07.22 |