프론트엔드
[Web] 렌더링 엔진은 어떻게 동작할까?
seomoon
2022. 2. 10. 17:47
렌더링 엔진
- 렌더링 엔진 : 요청 받은 내용을 브라우저 화면에 표시함.
- 렌더링 엔진은 HTML, XML 문서, 이미지를 표시할 수 있고, 플러그인이나 브라우저 확장 기능을 이용해 PDF 등 다른 유형도 표시할 수 있다.
- 렌더링 엔진은 통신을 제외한 거의 모든 경우에 단일 스레드로 동작한다. 통신은 몇 개의 병렬 스레드에 의해 진행될 수 있다. 병렬 연결의 수는 보통 2개에서 6개로 제한된다.
- 브라우저의 주요 스레드는 이벤트 루프를 유지하기 위해 무한 반복된다. 이벤트 루프는 배치, 그리기 등의 이벤트를 리스닝하고 처리한다.
렌더링 엔진의 종류
- 파이어폭스 : 모질라의 게코(Gecko) 엔진
- 사파리, 크롬 : 웹킷(Webkit) 엔진
- 웹킷 엔진 : 처음에는 리눅스 플랫폼에서 동작하도록 제작된 오픈소스 엔진인데, 애플이 Mac, Windows에서 사파리 브라우저를 지원하기 위해 수정했다.
렌더링 엔진 동작 과정
1) HTML 문서 파싱해 DOM 트리 구축, CSS 및 스타일 요소 파싱
- HTML 파서로 HTML 문서를 파싱해 DOM 트리 생성
- CSS 파서로 CSS 문서를 파싱해 스타일 정보 생성
2) 렌더 트리 구축
- 어태치먼트(attachment) : DOM 트리와 스타일 정보(시각 정보)를 연결해 렌더 트리 생성
3) 렌더 트리 배치
- 생성한 렌더 트리의 각 노드를 화면 상 정확한 위치에 표시한다.
4) 렌더 트리 그리기
렌더링 엔진은 좀 더 나은 사용자 경험을 위해 가능하면 빠르게 내용을 표시한다.
렌더링 엔진은 모든 HTML을 파싱할 때까지 기다리지 않고, 배치와 그리기 과정을 시작한다.
네트워크로부터 나머지 내용이 전송되는 동안, 받은 내용의 일부를 먼저 화면에 표시하는 것이다.
2) 렌더 트리 구축
- HTML과 CSS 파싱이 끝나면, attachment 과정으로 넘어가서 실제 화면에 그려질 정보를 담은 Render Tree를 생성하게 된다.
- Render Tree vs DOM Tree
- DOM Tree : HTML을 파싱해 생성한 Document 객체 모델이 부모 - 자식 관계로 구성된 트리 형태의 객체 데이터
- Render Tree : DOM Tree와 각 DOM 요소들에 상응하는 Style을 참조하여, 화면에 그려질 정보들이 담긴 데이터'
- Render Tree는 다음과 같은 이유로 DOM Tree와 일대일로 대응되지 않는다.
- 비시각적인 요소가 제외됨 :
Render Tree는 화면에 그려질 정보들을 담은 데이터이기 때문에, 화면에 그려지지 않는 비시각적인 요소들은 렌더 트리에 포함되지 않는다. (예:<head>
태그,display: none
속성을 가진 엘리먼트 요소 등) - 하나의 엘리먼트에 여러 개의 렌더러가 필요할 수 있음 :
(예:<input type='select'>
태그를 그리려면 표시 영역, 드롭다운 목록, 버튼 표시를 위한 3개의 렌더러가 필요함. / 한 줄로 작성했던 문장에 공간 부족으로 줄 바꿈이 생겼을 때 새로운 줄은 별도의 렌더러로 추가됨. /position
이나float
속성으로 인해 변동되는 자리 배치도에 의해 별도의 렌더러가 생성되기도 함)
- 비시각적인 요소가 제외됨 :
- 렌더 트리의 루트 객체는 RenderView라고 부른다. (웹킷에서. 파이어폭스 렌더링 엔진은 ViewPortFrame이라고 부름)
3) 렌더 트리 배치
- 렌더 트리를 구성하는 렌더러가 생성되어 트리에 추가될 때, 렌더러의 크기와 위치 정보는 정해져있지 않다. 배치란 렌더 트리의 각 렌더러의 크기와 위치 정보에 대한 계산을 하는 과정이다.
- 렌더 트리를 생성할 때, 각 렌더러가 어떻게 그려질지는 전부 정해지지만, _자신과 형제, 자식 렌더러들의 위치 및 크기 등을 고려_해 화면 상에 자신이 어느 위치에 얼마나 공간을 차지해 그려질지에 대해서는 정해지지 않은 상태이다. (즉, 화면 상에서의 상대적 크기, 위치가 정해지지 않은 상태)
- 배치 계산 과정은 왼쪽에서 오른쪽, 위에서 아래 순으로 진행된다. 따라서 시작점인 (0, 0) 픽셀은 브라우저 창의 제일 왼쪽 상단에서부터 배치를 시작한다.
- 배치 방식에는 전역 배치와 점증 배치 두 가지가 있다.
- 전역 배치 : 모든 렌더러에 영향을 주는 전역 스타일 변경이 발생할 때 일어나는 배치 과정 (예: 해당 페이지의 글꼴 크기나 스타일이 변경되는 것). 전역 배치는 동기적으로 한 번에 처리된다.
- 점증 배치 : 더티 렌더러(다시 배치할 필요가 있는 요소 또는 추가된 요소와 그 자식 요소들. 브라우저가 변경해야하는 특정 렌더러)가 배치되는 경우 일어나는 배치 과정. 점증 배치는 비동기적으로 일어난다. (브라우저는 일부가 변경되었을 때 페이지 전체를 다시 배치하지 않기 위해서 더티 비트 체제를 사용한다. )
4) 렌더 트리 그리기
- 렌더 트리를 이용해 실제 페이지에 그리는 과정이다.
- 그리기 단계에서는, 화면에 내용을 표시하기 위해 렌더 트리를 탐색하고, 렌더러의
paint
메소드가 호출된다. 그리고 UI 백엔드 (<input>
태그 등 기본적으로 정해져있는 UI) 요소들을 기반으로 그리기를 시작한다. 그리기도 배치와 마찬가지로 전역 또는 점증 방식으로 수행된다. - 각각의 요소들은, 블록 렌더러 순서에 따라 그리기 시작한다. (CSS 명세 기반)
배경 색 -> 배경 이미지 -> 테두리 -> 자식 -> 아웃라인 - 브라우저는 변경에 대해 가능한 한 최소의 동작으로 반응하려고 노력한다.
- 모든 요소가 그려진 후 일부 변경할 요소가 생긴 경우에는, 해당 렌더러와 그 자식의 배치 과정이 실행되고
repaint
메서드가 호출된다. - 웹킷에서는 리페인팅 전에 기존의 영역을 비트맵으로 저장하여 새로운 영역과 비교하고, 차이가 있는 부분만 다시 그리는 과정을 통해, 불필요한 그리기 요소를 최소화시킨다.
- 모든 요소가 그려진 후 일부 변경할 요소가 생긴 경우에는, 해당 렌더러와 그 자식의 배치 과정이 실행되고
(Velog에서 이동 중입니다.. )