HTML, CSS, JS 파일들은 브라우저 안에서 어떤 과정을 거쳐 UI를 띄우는지

담당
김민재
완료
완료
유형
Frontend
비고

요약

어떠한 웹 페이지에 접속을 하게 되면, 네트워크를 통해 해당 웹 페이지의 HTML 문서를 얻어옵니다. 브라우저는 토큰화 된 HTML의 문자열들을 이용해 파스 트리를 생성합니다.
브라우저는 파스 트리를 이용해 DOM 트리를 새로 만듭니다.
일반적으로 CSS를 링크하는 코드가 HTML 코드 내에 삽입되어 있기 때문에 HTML을 파싱하는 도중에 CSS 파싱이 시작됩니다.
HTML로부터 DOM 트리를, CSS로부터 CSSOM 트리를 빌드합니다.
DOM 및 CSSOM을 결합하여 렌더 트리를 형성합니다.
렌더 트리에서 레이아웃을 실행하여 각 노드의 형태를 계산합니다.
개별 노드를 화면에 페인트 합니다.
 
 

렌더링 엔진의 동작 과정

네트워크를 통해 얻어온 HTML과 CSS의 해석을 시작하는것으로 본격적인 렌더링 작업 시작
notion image
브라우저 엔진마다 해석 방식이 다를수 있지만 크게 네 단계로 이뤄져있음.
  • 파싱(Parsing)
  • 렌더 트리(Render Tree) 구축
  • 레이아웃(Layout) or 리플로우(Reflow)
  • 페인트(Paint)
 
위에서 이야기한 모든 과정들을 일컬어 중요 렌더링 경로(Critical Rendering Path)라고 부름
 
→ 각 단계에서 리소스를 로드하는 순서나 작성한 스크립트의 내용에 따라 웹 페이지의 반응 속도가 달라질수 있으므로 최적화를 통해 프론트엔드 개발자는 렌더링에 걸리는 시간을 개선시키고 사용자 경험을 높일수 있음.
 

파싱

파싱은 토큰화 된 코드를 구조화하는 과정을 말함, 이러한 파싱 과정을 전문적으로 해주는 부분을 파서(Parser)라고 부름.
💡
정확하게는 어휘분석기를 통해 토큰화 된 코드가 생성되고, 이를 파서가 해석하는 순서로 이뤄짐. 토큰화라는것은 의미가 있는 최소 단위로 코드를 쪼개는것을 말함. 가령, <div></div> 라는 코드를 토큰화하면 [’<’,’div’,’>’,’</’,’div’,’>’] 가 됨. 필자 생각 : 이런거까지 물어보겠냐만은 그냥 그런갑다 하삼.
 
파싱 과정은 입력받은 문자열이 정해진 문법들을 모두 따르는지 확인하는 과정.
 
브라우저는 HTML, CSS, JS 세 종류의 언어를 해석할 수 있음.
JS는 렌더링 엔진 레이어가 아니라 JS 해석기라는 별도의 레이어에서 언어를 해석함.
 
따라서 렌더링 엔진에서는 HTML과 CSS를 파싱함.
 
 

HTML 파싱

notion image
브라우저는 토큰화 된 HTML의 문자열들을 이용해 파스 트리를 생성함.
파스 트리는 브라우저가 읽어야 할 HTML의 코드를 트리 모양으로 구조화 하여 나타낸 것.
파스 트리를 이용해 DOM 트리를 새로 생성함.
 
파스 트리는 토큰화 된 문자열을 단순하게 구조화한 트리에 불과함.
DOM 트리는 우리가 실제로 상호작용할 수 있는 HTML 엘리먼트로 이뤄진 트리.
→ JS로 상호작용할 수 있는 부분은 DOM 트리
 
HTML 파서의 특징 3가지
  • 오류에 너그러움 : HTML을 파싱하는 도중에 에러가 발생하면 브라우저는 자체적으로 에러를 복구하려 함.
  • 파싱 과정이 중단될 수 있음 : HTML은 파싱 도중 <script> , <link> 같은 외부 태그를 만나게 되면 HTML 파싱을 즉시 중단함, 그리고 해당 태그의 해석을 실행
    • 왜 이런 구조인가? → <script> 에 DOM을 직접 수정할 수 있는 내용이 있을수있음.
  • 재시작 : 2번째 이유처럼 HTML의 파싱 과정은 어떠한 외부 요인으로 인해 방해받을수있음. 파싱 중간에 외부의 요인으로 인해 DOM이 추가, 변경, 삭제 되면 HTML은 처음부터 다시 파싱 과정을 거침. → 처리해야할 HTML이 많을경우 파싱 시간이 오래 걸리게 됨.
 

CSS 파싱

일반적으로 CSS를 링크하는 코드가 HTML 코드 내에 삽입되어 있기 때문에, HTML을 파싱하는 도중에 CSS 파싱이 시작됨.
notion image
네트워크를 통해 먼저 받아온 코드부터 해석을 실행할 수 있는 HTML 파서와는 달리, CSS 파서는 전체 파일을 모두 다운로드할 때까지 파싱을 시작할수 없음.
→ 필자의 생각 : 순차적으로 적용하는 방법이였을경우 CSS를 다 해석하고 뒤에 나오는 CSS때문에 전체적으로 다시 해석을 거쳐야하는 비효율적인 방법때문에 다운을 다 받고 한번에 해석하기위함이 아닐까 싶음.
 
전체 CSS 파일을 다운로드한 후 CSS 파싱 과정이 끝나게 되면, 코드에서 명세한 내용과 순서를 바탕으로 DOM과 같은 트리를 구성하는데 이를 CSSOM(CSS Object Model) 트리라고 부름.
스타일, 규칙, 선택자 등의 정보가 노드에 들어가게 됨.
 

렌더 트리

DOM 트리가 구성되는 동안 브라우저는 렌더 트리를 구성하기 시작함.
notion image
렌더 트리는 화면에 나타나는 요소들을 결정하는 트리.
렌더 트리는 DOM 트리와 CSSOM 트리를 조합하여 만들어짐.
화면에 그려지지않는 요소들은 트리에 나타나지 않음
<head> , <script> 같은 태그나 display:none 스타일이 적용된 엘리먼트 등등 이러한 태그는 시각적으로 나타낼 것이 없기 때문에 렌더 트리에 그려지지 않음
즉, 렌더 트리는 DOM 트리와 정확하게 1:1로 매칭이 되지 않음
 

레이아웃 또는 리플로우

렌더 트리 구성이 끝나면 레이아웃 단계가 이어짐. (모질라에서는 리플로우라고 부르기도함) 레이아웃 단계에서는 렌더 트리에서 계산되지 않았던 노드들의 크기와 위치, 레이어 간 순서와 같은 정보를 계산하여 좌표에 나타냄
 
이 과정은 HTML의 루트 오브젝트로부터 재귀적으로 실행됨.
Video preview
 
 

페인트

레이아웃 단계를 통해 화면에 배치된 엘리먼트들에게 색을 입히고 레이어의 위치를 결정하는 단계.
 
💡
필자가 헷갈렸던 부분 리플로우에서 레이어의 좌표를 결정하는 단계 페인트에서 레이어의 위치를 결정하는 단계 이렇게 적혀서 뭐가 다른가 생각했는데 리플로우는 레이어의 좌표를 결정해서 레이어의 배치는 이미 됐다고 생각하면 되고 페인트는 단순히 그려내는거라고 생각하면 된다.