“스크립트를 만나게 되면 어떻게 되는 것인가”
###
브라우저의 랜더링 과정 요약
- DOM TREE 구축 => 랜더트리 구축 => 랜더트리 배치 => 랜더 트리 그리기
- 의 순서로 HTML과 CSS를 처리하게 된다.
그렇다면, HTML 파싱 과정 중 마주하게 되는 JS코드는 어떻게 처리하는가?
- (일반적인 경우에)
멈춘다. 처리한다. 다시 시작한다.
- CSS와 같은 Style sheet는 이론적으로 DOM 구조를 변경시키지 않기 때문에 DOM 파싱을 중단시키지 않는다.
- 그러나, 브라우저는 JS
<script>
태그를 만나면 스크립트가 해석 및 실행되는 동안 문서의 파싱을 중단시키고 JS 코드의 실행 및 외부 네트워크로부터 자원을 가져오게 된다. - 이때문에
<script>
태그는<body>
태그 내부의 최하단에 위치하는 것이 권장된다.
async
<script async src="user.ui.js"></script>
와같이async
속성 추가를 통해서, 스크립트 파일을 비동기적으로 실행시킬 수 있다.- 스크립트 태그를 만나면 스크립트 가져오기를 실행하고, 가져오기가 끝나면 JS를 사용하게 된다.
<script async src="jquery.js"></script> <script async src="user.ui.js"></script>
- ui 스크립트가
jquery
에 대하여의존성(dependency)
을 갖고 있는 경우,ui
스크립트의 다운로드가jquery
의 다운로드보다 빠르다면 오류가 발생하게 된다. - 따라서 스크립트 문서간 의존성이 존재하는 경우
async
사용에 주의해야 한다. <script async>
가 HTML default 라는 글들이 많아서 추가적인 테스트를 해보았다.- default
<script src="./src/first.js"></script> <script src="./src/second.js"></script>
- async
<script async src="./src/first.js"></script> <script async src="./src/second.js"></script>
- 위 차트에서 파란선은
Domcontents Loaded
선이다. default
설정의 경우 스크립트가 dom contents의 일부로 인식되어 스크립트의 실행이 모두 끝난 후Domcontents Loaded
가 완료된다.- 반면
async
의 경우에는 dom 로드와는 무관하게defer
<script defer src="user.ui.js"></script>
와같이async
속성 추가를 통해서, 스크립트 파일을 비동기적으로 실행시킬 수 있다.- HTML 파싱이 모두 끝난후 스크립트가 실행된다.
참고
- https://webclub.tistory.com/630
- https://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html