HTML에서 스크립트를 포함할 때 어떤게 더 효율적인 방법일까?
사용자가 HTML을 다운 받았을 때 브라우저는 HTML 마크업을 위에서부터 한 줄 씩 분석하고 이해한 것을 CSS와 병합해서 DOM 요소로 변환하게 된다.
<head> 안에 스크립트를 포함한 경우
HTML을 파싱하는 동안 브라우저가 <script>를 만나는 경우 파싱이 중지되며 스크립트를 로드하는 시간, 실행하는 시간만큼 렌더링이 지연된다.
위에서부터 한 줄 씩 HTML 파싱(구문분석) > script 태그 발견 > html 파싱하는 것을 멈추고 필요한 스크립트를 서버에서 다운 > 스브립트 실행 > 다시 html 파싱
- 단점 : 스크립트가 준비될 때 까지 HTML 파싱을 멈추기 때문에 사용자가 웹페이지를 보는데까지 많은 시간이 소요된다.
<html lang="en">
<head>
<meta charset="UTF-8">
<title> head 태그 안에 script </title>
<script src="main.js"></script>
</head>
<body></body>
</html>
<body> 끝부분에 script를 넣는 경우
body의 내용이 렌더링 된 이후 <script>를 만나 로드하고 실행하기 때문에 위의 경우보다 렌더링 시간이 빨라진다.
스크립트가 DOM 요소를 조작하는 내용을 포함한다면 스크립트가 렌더링된 DOM에 접근할 수 있도록 위보단 아래에 작성하는 것이 좋다.
HTML 파싱 > 파싱완료 > 스크립트 다운 > 스크립트 실행
- 장점 : HTML을 전부 파싱하고 스크립트를 다운, 실행하기 때문에 스크립트가 준비되기 전에 사용자가 웹페이지 컨텐츠를 볼 수 있다.
- 단점 : 사용자가 기본적인 HTML 콘텐츠는 빨리 볼 수 있지만 서버에서 스크립트를 다운하고 실행하는 시간도 기다려야하므로 JS가 큰 역할을 하는 웹페이지일 경우 사용자는 정상적인 웹페이지를 볼 수 없다.
<html lang="en">
<head>
<meta charset="UTF-8">
<title> body 태그 안에 script </title>
</head>
<body>
..
..
..
<script src="main.js"></script>
</body>
</html>
async 속성 사용
브라우저가 <script>를 만나면 다운로드와 동시에HTML 파싱이 진행되며 스크립트 다운이 완료되면 스크립트를 실행하고 HTML 파싱은 멈춘다.
async 속성의 스크립트는 DOM 요소를 조작하지 않고 앞뒤에 로드되고 실행될 스크립트와 의존성이 없는 코드를 포함시키는 것이 좋다.
HTML 파싱 > 스크립트 발견 > 파싱과 동시에 스크립트 다운 > 스크립트가 로드되면 HTML 파싱을 멈추고 스크립트 실행 > 나머지 HTML 파싱
- 장점: 스크립트 다운이 HTML 파싱과 병렬적으로 일어나기 때문에 다운로드 받는 시간을 절약 가능
- 단점: 스크립트가 HTML이 파싱이 되기 전에 실행되기 때문에 자바스크립트에 DOM요소를 조작하는 코드가 들어있을 경우 원하는 요소가 정의되있지 않을 수 있다.
<html lang="en">
<head>
<meta charset="UTF-8">
<title> head 태그 안에 script </title>
<script async src="main.js"></script>
</head>
<body></body>
</html>
defer 속성 사용
defer 속성을 가진 script는 브라우저가 script를 만났을 때 html 파싱을 막지 않고 스크립트 다운을 시작하여 /html 태그를 만났을 때 스크립트가 실행된다.
defer 속성은 스크립트가 DOM 요소를 조작하는 내용을 포함시킬 때 사용하면 좋다.
HTML 파싱 > 스크립트 발견 > 스크립트 다운로드와 HTML 파싱 > 파싱완료 되면 스크립트 실행
- 장점 : 다운과 파싱을 동시에 하며 HTML 파싱을 사용자에게 보여준 뒤 다운로드 한 스크립트를 이어서 실행하기 때문에 가장 효율적이다.
<html lang="en">
<head>
<meta charset="UTF-8">
<title> head 태그 안에 script </title>
<script defer src="main.js"></script>
</head>
<body></body>
</html>
async vs defer
async는 다수의 스크립트를 다운로드 받게 될 경우, 스크립트를 정의한 순서에 상관 없이 먼저 다운로드 한 스크립트를 실행하기 때문에 순서에 의존적인 스크립트라면 문제가 생길 수 있다.
반면 defer은 파싱하는 동안 필요한 스크립트를 모두 다운하고 순서대로 실행하기 때문에 정의한 순서가 지켜지므로 원하는 방향으로 스크립트를 실행할 수 있다.
'Programming > JavaScript' 카테고리의 다른 글
[JS] 자바스크립트의 역사 (0) | 2022.12.13 |
---|