본문 바로가기
Web programming/JavaScript & jQuery

<script>요소 defer와 async : HTML에서 스크립트 불러오기

by Hyonixk 2021. 3. 29.
728x90

 

 

HTML에서 JavaScript를 포함할 때, 어느 위치에 어떻게 참조시키는 것이 효율적인 방법일까?


브라우저가 HTML을 분석하여 화면에 출력하는 과정을 생각해보자.


우선 브라우저에서는 다운로드한 HTML의 구문을 분석(*parsing)을 하게된다.

브라우저가 HTML을 다운받아서 코드를 한 줄씩 parsing 하다가 <script>를 만나게 되면 parsing 하는 것을 멈추고, script를 서버에서 받아오고 실행(fetching)하게 된다.

 

* parsing

HTML 태그에는 시작과 끝이 있고 속성 이름과 값이 있는데, parser는 이 문서에 대한 입력을 parsing(구문 분석)하여 문서 트리를 구축한다. (해당 파일을 브라우저 화면으로 볼 수 있는 일련의 과정)

HTML parser는 이미지 같은 non-blocking 리소스를 찾으면 해당 리소스를 요청하고 parsing(구문 분석)을 계속한다. CSS 파일을 만나게 돼도 구문 분석을 계속하지만, <scrpt>태그(async 또는 defer)를 만나면 렌더링을 차단하고 HTML 구문 분석을 일시 중지하게 된다.

브라우저가 CSS 스타일을 발견하면 텍스트를 CSS 개채 모델로 parsing(구문 분석)한 다음 레이아웃 스타일 지정 및 페인팅에 사용하는 이런 데이터 구조이다. 브라우저는 컨텐츠를 화면에 출력할 수 있도록 이 두 구조에서 렌더 트리를 만든다. 
그리고 JavaScript를 발견하면 다운로드하고 parsing(구문 분석)한다. JavaScript parsing은 컴파일 시간 또는 메서드 호출과 같이 파서가 호출될 때마다 수행된다.

 

 

<head> 內 하단에 삽입 

브라우저가 HTML을 다운받아서 코드를 한 줄씩 parsing하다가 <script>를 만나면 parsing하는 것을 멈추고 스크립트를 서버에서 받아오고(fetching) 실행하게 된다. 
만일 JavaScript파일이 크거나 인터넷이 느리다면 사용자는 아마 웹사이트 화면이 뜨기까지 오래 기다려야 할 것이다. 따라서 <head>에 포함시키는 것은 효율적이지 못하다. 

 

 

<body> 內 하단에 삽입 

HTML 화면이 준비된 다음에 스크립트를 패칭하여 실행하게 되므로 사용자가 기본적인 HTML 컨텐츠를 빨리 볼 수 있다는 장점이 있다.

하지만 자바스크립트에 의존적인 컨텐츠로 DOM 요소를 가져와 꾸며준다던지 자바스크립트를 이용해서 서버에 있는 데이터를 가져오도록 동작하는 웹사이트라면 이 역시 사용자가 정상적인 페이지를 보기 전까지는 패칭과 실행을 반복할 텐데 그 시간 동안 사용자가 기다려야 하는 상황이 벌어질 수 있다.

 

 

<script>에 async 속성 명시

<head>
        <meta charset="UTF-8" />
        <title>Document</title>
        <script asyn src="main_a.js"></script>
        <script asyn src="main_b.js"></script>

</head>
<body>
        <div></div>
</body> 

브라우저가 HTML을 parsing하는 중에 asyn 속성을 만나면 스크립트를 병렬로 다운로드하라고 명령하고 다시 파싱한다. 스크립트가 다운로드 완료 되면 파싱하는 것을 멈추고 스크립트를 실행한 후에 다시 나머지 HTML을 파싱하게 된다.

즉, 브라우저가 HTML parsing하는 중에도 스크립트를 가져와 실행시키기 때문에 사용자가 정상적인 페이지를 보기 전에 스크립트가 실행될 수 있다.

 

- 정의된 스크립트가 여러 개일 경우, 정의한 기준이 아니라 파싱하는 동안 먼저 (fetching된) 다운 받아진 스크립트 순으로 실행하게 된다. 만일 순서에 의존적인 스크립트일 경우 asyn가 아닌 defer를 사용하는 것이 좋다.

 

- <head> 내에 속성을 명시하도록 한다.

 

 

<script>에 defer 속성 명시

<head>
        <meta charset="UTF-8" />
        <title>Document</title>
        <script defer src="main_a.js"></script>
        <script defer src="main_b.js"></script>

</head>
<body>
        <div></div>
</body>

브라우저가 HTML을 parsing하는 중에 defer 속성을 만나면 스크립트를 다운로드하라고 명령만 하고, HTML parsing을 모두 마친 후에 스크립트를 실행한다.

 

- 정의된 스크립트가 여러 개일 경우, 파싱 하는 동안 필요한 스크립트를 모두 다운로드하여 놓은 다음에 개발자가 정의한 순서대로 스크립트가 실행된다. 따라서 계획한 데로 어느 정도 예상하면서 작업이 가능하다.

 

 

결론

<head> 내에 defer 속성을 사용하는 것이 가장 안전하고 효율적인 방법인 것 같다.

스크립트를 포함시킬 때 async과 defer 속성을 모두 명시하지 않으면, 브라우저는 HTML 구문분석하기 전에 스크립트를 가져와 바로 실행시키므로, async이나 defer 속성 등을 적절히 사용하는 것이 좋겠다.

 

 

 

 

 

 

참조 MDN, DreamCoding

 

 

반응형

'Web programming > JavaScript & jQuery' 카테고리의 다른 글

[JavaScript] JSON  (0) 2021.04.14
[JavaScript] Strict mode  (0) 2021.04.10
window.open(); 윈도우팝업 제작 및 호출  (1) 2020.12.19
jQuery 기본 문법 사용, 선택자와 메서드  (0) 2020.11.17
jQuery란  (0) 2020.10.26