[WEB] 스크립트의 로드 시점 - async & defer
📙 브라우저가 HTML을 해석(Parsing)할 때 어떤일이 일어나는가 ?
스크립트의 로드 시점을 알기전에 브라우저가HTML
문서를 해석(Parsing)할 때 일어나는 일들에 대해서 이해하면 좋을것 같다.
- 불러오기 및 데이터 파싱
HTTP
모듈 또는 파일시스템으로 전달받은 리소스 스트림(resource stream)을 읽는 과정을 거치고 파싱을 통해DOM(Document Object Model)
트리를 생성한다. - CSS 스타일 결졍
문서의 요소를 어떻게 보여줄 것인지 결정하는 요소를 파싱한다. - 렌더링 트리 만들기
파싱으로 DOM 트리가 생성되는 동안 렌더링 트리를 만든다. 표시해야할 순서와 문서의 시각적인 요소로써 올바른 순서로 내용을 그리기 위해 별도의 트리구조가 필요한데 이를 렌더링 트리라고 부른다. - 레이아웃
렌더링 트리가 생성될 때, 각 랜더링 객체가 위치와 크기를 갖게되는 과정을 레이아웃이라고 한다. - 그리기
그리기 단계에서는 렌더링 트리를 탐색하면서 특정 메모리 공간에 RGB값을 체우는 과정이다.
파싱(Parsing )?
문서를 파싱한다는 것은 문서에서 읽어낸 데이터를 이해하고 사용할 수 있는 형태로 변환하는 것을 의미한다. 이러한 동작을 하는 기능또는 프로그램을 파서(Parser) 라고 한다.
브라우저에서 HTML 문서를 파싱한 결과를 파싱트리(parse tree) 또는 문법트리(syntax tree)라고 부른다.
📕 일반적인 스크립트의 로드
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>Title</title>
<link rel="stylesheet" type="text/css" href="default.css" />
<link rel="stylesheet" type="text/css" href="dark.css" />
<script src="jquery.js"></script>
<script src="main.js"></script>
</head>
<body>
...
</body>
</html>
위와 같은 문서를 불러올 때 브라우저는 먼저 HTML
을 파싱하고 외부자원인 CSS, JS 파일을 로드하게 된다.
DOM 트리가 완성되면 이미지 파일이나 외부 리소스를 로드하면서 모든 작업이 완료된다.
여기서 중요한 점은 브라우저가 script
를 해석할 때 어떻게 되는 것인가 인데, 일반적인 경우에는 자바스크립트는 인라인 코드의 경우 즉시 실행되고 파일로 전달했을 때는 전달이 완료된 시점에 실행된다. 문제는 아래의 그림과 같이 브라우저가 자바스크립트 다운로드 및 실행하는 동안은 문서의 파싱은 중단된다.
한편 CSS는 DOM트리를 변경하지 않기 때문에 문서파싱을 기다리거나 중단하지 않는다.
위의 코드에서는 스타일을 먼저 불러온 뒤 스크립트를 로드하지만 만약 스크립트 파일을 먼저 로드하게 될 경우에 스크립트에서 스타일 정보를 요청하게 된다면 잘못된 결과를 내놓기 때문에 결과적으로 사용자경험(UX)을 떨어뜨리게 될 것이다. 이런 문제는 흔치않은 것처럼 보이지만 매우 빈번하게 발생한다.
따라서 위 코드를 다음과 같이 스크립트 태그를 body 태그 끝에 두는것을 권장한다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>Title</title>
<link rel="stylesheet" type="text/css" href="default.css" />
<link rel="stylesheet" type="text/css" href="dark.css" />
</head>
<body>
...
<script src="jquery.js"></script>
<script src="main.js"></script>
</body>
</html>
📘 스크립트 로드 방식 async, defer
async 속성을 사용할 때
async
속성을 사용하여 스크립트 파일이 비동기적으로 실행될 수 있음을 나타낼때 사용할 수 있다. 즉, 브라우저가 async
속성이 있는 스크립트 태그를 만났을 때 HTML 파싱을 멈추지 않고 스크립트가 실행할 준비가 되었을 때 실행시킨다.
<script async src="main.js"></script>
스크립트의 실행순서가 다운로드 완료된 시점에서 결정이 되므로 실행 순서가 중요한 스크립트들에 async
속성을 사용할 때는 유의해야한다.
defer 속성을 사용할 때
defer
속성은 HTML 파싱이 종료되었을 때 스크립트 파일을 실행하도록 브라우저에게 지시하게 된다.
<script defer src="main.js"></script>
위 그림과 같이 브라우저가 스크립트를 다운로드를 완료하더라도 스크립트는 바로 실행되지 않는다. 또한 async
와 다른점은 호출된 순서대로 실행이 된다는 점이다.
언제 사용하면 좋을까 ?
스크립트의 의존성 여부에 따라 결정하면 유용하게 사용할 수 있을 것이다. 의존성이 없는 스크립트의 파일을 실행할 때는 async
를 적절하게 사용하고, 의존성과 실행순서가 중요하다면 defer
를 사용해 주면 유용할 것이다.
✏️ 정리
- 브라우저가 HTML 문서를 파싱할 때 스크립트를 만나게 되면 파싱을 중지한다.
- 스크립트태그의 async, defer 속성을 적절히 활용하여 스크립트가 실행되어야 할 순서를 제어할 수 있다.
📚 참고링크
Author And Source
이 문제에 관하여([WEB] 스크립트의 로드 시점 - async & defer), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jimmy0417/WEB-스크립트의-로드-시점-async-defer저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)