.
본문 바로가기
Web,HTML,CSS

브라우저 렌더링 동작 과정, script 태그 위치

by 와칸다개발자 2022. 6. 15.

ref

https://wormwlrm.github.io/2021/03/27/How-browsers-work.html

https://hahahoho5915.tistory.com/31

https://d2.naver.com/helloworld/59361

https://web.dev/critical-rendering-path-constructing-the-object-model/

https://web.dev/critical-rendering-path-render-tree-construction/

 

위 게시글들을 읽고 나름 정리한 것입니다.

 

프론트 엔드 개발자 라면 프레임 워크 단에서에 최적화 예를 들자면 (ex. React.memo, useCallback) 등 중요 하지만

 

브라우저의단 에서의 동작도 필수로 알아야 한다. 프론트와 브라우저는 아주 친밀한 사이여야 할 것이다.

 

브라우저 구성요소

https://d2.naver.com/helloworld/59361

브라우저는 이제는 하나의 미니 OS라고 불릴만큼 아주 방대하고 복잡하다.

 

프론트엔드 개발자에게 특히 중요한 부분은 렌더링 엔진이라고 볼 수 있다.

 

렌더링 엔진은 HTML과 CSS, JavaScript를 파싱하고 브라우저에 그려내는 역할을 한다. 

 

엔진 동작과정

 

https://d2.naver.com/helloworld/59361

 

url 에 주소를 입력하면 서버는 HTML 페이지를 보내준다. 브라우저 렌더링 엔진은 위 과정을 거쳐 HTML 문서를 파싱한다.

 

렌더링 엔진은 HTML문서와 CSS문서를 파싱 후 둘이 합쳐 렌더링트리를 구축한다.

 

렌더트리 구축 후 레이아웃 또는 리플로우의(용어의 차이) 과정을 거쳐 그리게 된다.

 

https://d2.naver.com/helloworld/59361

 

HTML 파싱, DOM(Document Object Model) 트리 생성

다음과 같은 HTML 문서를 서버에서 받아 왔다고 가정한다.

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="style.css" rel="stylesheet" />
<title>Critical Path</title>
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
</body>
</html>

 

 

 

1. 브라우저가 HTML의 원시 바이트를 읽어와서, HTML에 정의된 인코딩 방법에 따라 문자열로 변환합니다.

<meta charset="utf-8">

기본 값은 UTF-8 입니다.

 

2. 문자열을 W3C 표준에 지정된 고유 토큰으로 변환합니다.

 

3. 이제 토른화된 문자열들을 이용해서 트리 형태로 구조화된 DOM 트리를 생성합니다. 

 

DOM 트리는 우리가 실제로 접근할 수 있는 HTML 엘리먼트로 이루어진 객체 트리이다. 실제로 JS로 DOM API를 이용할 수 있는 DOM 객체 트리 인것이다.

 

파싱 과정에서 중요한 특징이 있는데 파싱 과정이 중단될 수 있다는 점이다.

 

파싱 도중 <script>, <link> 같은 외부 태그를 만나게 되면 HTML 파싱을 중단한다.

 

그리고 해당 태그의 해석을 실행한다. 만약 해당 태그가 외부 파일을 참조하고 있다면 다운로드를 한 후

해석을 시작한다. 

 

CSSOM(CSS Object Model) 트리

CSS 파일은 인라인 방식으로 작성하거나 head 태그 외부 파일을 참조한다. 

css 파싱은 css 파일 전체를 다운로드 하기 전까지 파싱을 시작할 수 없다.

DOM 트리를 생성하는 과정과 비슷하다. 

최종 CSSOM 트리는 다음과 같다.

 

렌더링 트리(Rendering Tree)

DOM 트리와 CSSOM 트리가 만들어 졌으니 이 둘을 결합해서 렌더링 트리를 생성한다.

 

렌더링 트리는 실제로 브라우저에 뷰포트에 나타날 요소들을 나타내는 트리이다.

 

위치와 크기 그리고 스타일, 그리는 순서들을 담고 있다.

 

이 과정에서 head, script 태그나 display:none 속성이 명시된 요소는 렌더링 트리에 추가되지 않는다.

 

여기서 visibility: hidden 속성은 display:none 속성과 다른데 전자는 뷰포트 내에서 위치만을 가진다.

 

즉 투명한 상자라고 생각하면 된다. 반면 후자는 요소가 보이지도 않고 위치도 나타내지 않는다.

 

 

레이아웃, 리플로우 단계

레이아웃 단계 모질라에서는 리플로우 라고 부르기도 한다.

 

이제까지 과정은 노드가 어떤 위치에 크기를 가지고 있는지 스타일은 어떤지 계산만 했지 실제 뷰포트 내에서 

계산하지는 않았다.

 

이 단계에서는 노드들의 위치와 크기, 레이어 간 순서와 같은 정보를 계산하고 이를 BOX 모델로 뷰포트 내에 나타낸다. 

 

이 과정은 HTML문서의 루트 객체로 부터 재귀적으로 실행이 된다.

 

https://www.youtube.com/watch?time_continue=26&v=ZTnIxIA5KGw&feature=emb_title 

페인트

말그대로 렌더링 트리의 각 노드를 뷰포트내에 실제 픽셀로 변환하고 스타일을 입히는 과정이다. 

 

역시 루트 노드로부터 재귀적으로 실행이 된다. 

 

 

script 태그위치 삽입

script 태그는 async , defer 속성을 사용하지 않는 이상 body 태그 밑에 위치하는 것이 좋다.

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="style.css" rel="stylesheet" />
<title>title</title>
<script src="app.js"></script>
</head>
<body>
<div class='container'>
</div>
</body>
</html>

위에서 설명했듯이 파싱과정에서 script 태그를 만나게 되면 파싱을 멈추고 script 파일을 다운로드 하고 실행한다.

 

이 과정에서 브라우저는 다른 작업을 수행하지 않기 때문에 스타일이 입혀지지 않는 상태가 되고 이렇게 되었을 때

 

화면 레이아웃이 제대로 나타나지 않은 상태로 유저에게 뷰를 보여주게 된다.이는 곧 최악의 UX를 제공하게 된다.

 

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>title</title>
<script>
console.log(document.querySelector('.container')); // null
</script>
</head>
<body>
<div class='container'>
</div>
</body>
</html>

 

또한 다음과 같은 문제를 야기 할 수 있는데 script 태그를 만나 DOM 트리가 완전히 구축된 것이 아니므로

 

container class를 가져오는 다음의 코드는 null을 반환하게 된다. 

 

 

'Web,HTML,CSS' 카테고리의 다른 글

CSS pointer-event 속성  (0) 2022.07.14