먼저 브라우저의 구성요소를 알아보면,
브라우저 구성요소
그래서 렌더링이 뭔데?
요청받은 내용을 브라우저 화면에 표시하는 일을 렌더링이라고 하며,
이를 진행하는 프로그램을 렌더링 엔진이라고 한다.
렌더링 엔진 기본 구동 과정
파싱은 렌더링 엔진의 메일 쓰레드에서 진행되는데, script tag를 만나면 파싱을 일시중지하고 js 코드를 로딩하고 파싱해 실행하기를 기다린다.
따라서,
위와 같은 상황을 막기 위해 script 태그는 body 태그의 최하단에 두는 것이 script의 최적 위치라고 할 수 있다.
하지만 script 태그를 body 태그 최하단에 놓기 싫거나, 그럴 수 없는 상황에 있을 때 활용할 수 있는 다른 방법도 있습니다.
script
태그의 async
와 defer
속성을 활용하면 스크립트 로딩 순서를 제어할 수 있습니다.
<script async src="script.js">
script 태그의 async 속성은 스크립트가 나머지 페이지와는 비동기적으로 실행됨을 나타내며, 브라우저가 페이지를 파싱하는 동안에도 스크립트가 사용가능해지면 곧바로 실행됨을 명시합니다.
위와 같이 asnyc 속성이 더해진 script 태그가 HTML 태그 사이에 있는 경우 아래 그림과 같이 작동합니다.
script async flow
1. HTML parsing 도중 script 태그를 만나도 Script fetch(script 로드)와 HTML parsing이 함께 이루어지다가
2. script 로드가 끝나면 Script excution(script가 실행되는 시점)에 HTML parsing이 잠시 중단되고 실행이 끝나면
3. HTML parsing이 재개됩니다.
<script defer src="script.js">
script 태그의 defer 속성은 페이지가 모두 로드된 후에 해당 외부 스크립트가 실행됨을 명시합니다.
위와 같이 defer 속성이 더해진 script 태그가 HTML 태그 사이에 있는 경우 아래 그림과 같이 작동합니다.
script defer flow
HTML parsing 도중 script 태그를 만나도 script 로드의 시작부터 끝까지 html parsing이 중단되지 않으며, html parsing이 끝나고 난 뒤에 script가 실행됩니다.
DOMContentLoaded
와 onload
를 활용하면 javascript 자체에서 로딩 순서를 제어할 수도 있습니다.
DOMContentLoaded
내부의 코드는 DOM 생성이 끝난 후에 실행되고 onload
내부의 코드는 문서에 포함된 모든 콘텐츠(images, script, css, ...)가 전부 로드된 후에 실행됩니다.
따라서,
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>DOMContentLoaded</title>
</head>
<body>
<script>
// window.onload가 가장 앞에 위치!
window.onload = function(){
console.log("afterwindowload");
var target = document.querySelector("#test");
console.log(target);
}
// DOMContentLoaded가 두번째에 위치!
document.addEventListener("DOMContentLoaded", function() {
console.log("afterdomload");
var target = document.querySelector('#test');
console.log(target);
});
// 일반 script 코드가 가장 끝에 위치
console.log("바로시작")
var target = document.querySelector('#test');
console.log(target);
</script>
<div id="test">test</div>
</body>
</html>
위 코드의 console에 출력된 결과는
일반 script 코드 -> DOMContentLoaded 안의 코드 -> window.onload 안의 코드 순으로 출력됩니다.
Source:
https://velog.io/@grinding_hannah/Web-브라우저-작동-원리
https://d2.naver.com/helloworld/59361