-
Notifications
You must be signed in to change notification settings - Fork 0
browser render
<!doctype html>
<html>
<head>
<title>Render Tree</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div>
<h1>Rendering Test</h1>
<p>Test for rendering tree</p>
<div>
<p>Test for rendering tree</p>
<div>
<p>Test for rendering tree</p>
</div>
</div>
</div>
</body>
</html>위의 간단한 HTML 을 예시로 간단하게 Rendering Engine이 어떤 작업을 수행하는지에 대해서 설명해보겠습니다. 우리가 특정 언어로 작업한 코드를 렌더하기 위해서 반드시 필요한 과정은 어떤 과정에 있을까요? 가장 먼저 Parsing 을 하는 과정이 필요합니다.
문서 Parsing 은 브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 것을 의미합니다. 현재 위의 html 은 우리 개발자들이 이해하고 사용하기에는 아주 적합한 구조를 갖고 있지만 브라우저가 이해하고 사용하기에는 적합하지 않기 때문에 Parsing을 진행하고 이러한 과정을 거쳐서 Parse Tree를 생성합니다.
Parsing을 하기 위해서 가장 먼저 수행되는 것은 tokenizer 입니다. 토큰은 의미 단위로 분리가 된 문자열을 의미합니다. tokenizer 는 사람에게 있어서 의미 있는 단위를 컴퓨터가 이해할 수 있게끔 변형 시키는 과정을 이야기 합니다.
예를 들어 설명해보겠습니다. 사람과 사람들의 의미는 같은 의미를 지니나요? 우리 사람들에게는 두 단어 모두 의미가 있습니다. 둘은 서로 다른 뜻을 갖고 있으니까요 하지만 컴퓨터는 그렇지 않습니다. 두 가지의 차이를 직접 분류해서 가르쳐주지 않는 이상 컴퓨터는 두 단어를 같은 의미로 해석할 수 있습니다.
DOCTYPE token
StartTag: html
StartTag: head
StartTag: title
Character: "Render Tree"
EndTag: title
...
그렇기 때문에 우리는 위와 같이 브라우저가 이해할 수 있는 의미의 단위로 html 을 쪼개는 과정 토큰화(Tokenization) 과정을 거치게 됩니다. 토큰화를 모두 끝낸 후 DOM 트리를 구축하는 작업을 수행합니다.

토큰화된 HTML 태그를 노드로 변화하는 과정을 갖습니다. 이 후 노드들을 트리 구조로 연결하여 위의 그림과 같은 DOM(Document Object Model) 트리를 생성합니다.

브라우저는 HTML을 파싱하여 DOM 트리를 구축하는 과정에서 CSS 파일을 발견하면, CSS 파일의 다운로드와 파싱을 병렬적으로 진행합니다. css 파일을 다운로드하는 작업은 효율적인 병렬 처리 방식으로 동작하기 때문에 기존에 DOM 트리 구축을 위해 수행하던 파싱 과정이 멈추지 않고 계속해서 진행됩니다.
또한 CSS는 다운로드와 함께 파싱이 시작되어 CSSDOM 트리 역시 DOM 트리와 함께 점진적으로 구축이 되고 있기 때문에 기존의 작업 성능에 영향을 주지 않습니다. 하지만 중요한 점은 CSS는 렌더 차단 리소스(render-blocking resource)라는 것입니다.
렌더링 차단 (Render-blocking) 은 사용자 인터페이스 렌더링을 차단할 때 웹 사이트를 로드하는 프로세스의 모든 부분을 나타냅니다. 렌더링 차단은 사용자가 사이트와 상호 작용(예, 콘텐츠 보기 또는 컨트롤과 상호 작용)할 수 있을 때까지의 시간을 늘리기 때문에 웹 성능에 좋지 않습니다.
이러한 렌더링 블로킹 차단 리소스는 대표적으로 CSS, Javascript 파일이 이에 해당합니다. 하지만 두 파일은 명확한 차이가 있습니다. CSS는 렌더 트리 구축을 차단하는 렌더 블로킹 리소스이며, JavaScript는 HTML 파싱을 중단시키는 파서 블로킹 리소스입니다.
CSS 가 렌더 트리 구축을 차단하는 리소스인 이유는 사용자가 화면을 직접 보는 대상인 렌더트리는 HTML을 파싱하여 생성된 DOM 트리와 CSS을 파싱하겨 생성된 CSSOM 트리를 결합하여 만들어지기 때문입니다. 이 두 가지가 같이 생성되어야 하는 이유는 DOM 트리는 생성이 되었는데 CSSOM 트리가 같이 생성되지 않을 경우 화면이 깜빡거리는 문제가 생기기 때문입니다.
그렇다면 HTML 파싱을 차단하는 이유도 알아 보겠습니다. JS 를 이용하여 우리는 DOM 트리 내에 생성된 DOM 을 직접 조작할 수 있습니다. JS 를 실행하기 이전까지 생성되어 있던 DOM 을 삭제할 수도 없던 DOM 을 추가할 수도 있기 때문에 파싱이 계속해서 일어 날 경우 잘못된 렌더 트리가 생성 될 수 있습니다.
이 뿐만 아니라 JS에서는 CSSOM 트리에도 접근이 가능합니다. 그렇기 때문에 잘못된 렌더 트리가 생성되는 것을 막기 위해서는 JS가 실행될 경우 기존의 HTML 파싱 자체를 중단 시키고 JS 작업이 모두 종료된 후 기존의 파싱과 DOM 트리 구축을 이어나가야 합니다.
Betting duck
- [지호] 베팅 생성 페이지에서 아이콘이 함께 리렌더링 되는 문제 해결
- [정민] 채팅 시스템을 위한 IRC 프로토콜
- [정민, 지호] 소켓 이벤트가 무한리필 되는 문제 해결하기
- [정민, 지호] 소켓 관리 실패로 인한 서버 다운 문제 개선하기
- [석호] 베팅 종료 API 개선하기
- [동교] 베팅 프로세스 흐름도
- [동교] 실시간 베팅에서 레디스 원자성 테스트
- [석호] Redis에서의 트랜잭션
- [석호] Redis를 이용한 메시지 큐 구현(1)
- [석호] Redis를 이용한 메시지 큐 구현(2)
- [동교] Redis에서 O(N) 관련 명령어는 주의하기
- [동교] 베팅덕에 적용한 다양한 캐시 전략
- [동교] 레디스의 메모리 설정 최적화
- [정민] 브라우저에서 렌더가 일어나는 방식
- [정민] Layered frontend application
- [정민] sessionStorage를 이용하여 전역 상태를 관리해도 될까?
- [정민] 왜 css는 내 마음대로 적용이 안될까?
- [공통] 브랜치에서 push 했는데 dev로 바로 병합된다?
- [공통] Cross-Origin WebSocket에서 쿠키 전송 문제: 삽질 기록과 해결
- [FE] Cannot find package 'prettier-plugin-tailwindcss'
- [BE] NestJS에서의 @Injectable() - WebSocketGateway 싱글톤 이슈
- 유저 스토리는 무엇인가?
- GitFlow vs Trunk-based 협업 방식
- The Front End Developer/Engineer Handbook 2024
- 코드 리뷰 in 뱅크샐러드 개발 문화
- Optimize Largest Contentful Paint
- The Looper Mini Web Machine
- Best practices for fonts
- React Folder Structure in 5 Steps [2024]
- Speeding up the JavaScript ecosystem - The barrel file debacle