브라우저는 어떻게 콘텐츠를 렌더링하고 있는가?

웹 브라우저는 HTML 등으로 쓰여진 문장을 해석하고, 텍스트와 이미지를 배치하는 소프트웨어이다. 텍스트나 이미지 등의 개체를 렌더링하는 렌더링 엔진의 구조를, 사용자 세션 분석 및 UX 최적화 서비스를 제공하고 있는 SessionStack의 CEO 인 Alexander Zlatkov 씨가 설명하고 있다.



▼브라우저의 주요 구성 요소는 "사용자 인터페이스"와 "브라우저 엔진", "렌더링 엔진", "네트워킹", "JavaScript 엔진", "UI 백엔드", "데이터 스토리지" 등이 있다. 


"사용자 인터페이스"는 주소 표시줄이나 뒤로 앞으로가기 버튼, 북마크 메뉴 등 Web 페이지 이외의 부분 전부이다. "Render Engine"은 HTML과 CSS를 분석하여 화면에 표시한다. "브라우저 엔진"은 사용자 인터페이스와 렌더링 엔진의 ㅈ어보 전달을 담당한다. "네트워킹"은 HTTP 요청과 같은 네트워크 호출을 담당하고, "UI 백엔드"는 확인란이나 창 같은 핵심 위젯을 그린다. "JavaScript 엔진"은 JavaScript를 움직이고 "데이터 스토리지"는 Cookie 등의 데이터가 저장된다.




이 중, 언급 한 바와같이 "렌더링 엔진"의 일은 "열어 본 페이지를 브라우저 화면에 표시한다"라는 것. 기본적으로는 HTML과 XML 문서 및 이미지를 표시하기 위한 엔진으로, 플러그인과 확장 기능을 사용한다면 PDF 등도 표시 할 수 있다. 


또한 브라우저마다 사용되는 렌더링 엔진은 다르고, Firefox는 "Gecko", Safari는 "WebKit", 그리고 Chrome은 "Blink"라는 엔진을 사용하고 있다. 


▼"네트워킹"에서 오픈 한 페이지의 문서를 받는 곳에서부터 렌더링 작업이 시작된다. 우선 "HTML을 DOM 트리라는 구조체로 변환"하고 "렌더 트리를 구성" 한다. 그리고 "렌더 트리를 배치"하고 "렌더 트리를 그리기" 하는 단계이다. 


▼먼저 DOM 트리를 구성하는 과정을 살펴보면...예를 들어 다음과 같이 "Hello, friend"라는 문자열과 gif 이미지 "smiley.gif"를 표시하는 입력이 있다고 하자. 


▼그러면 DOM 트리는 아래의 그림과 같이 각 요소가 바로 아래에 존재하는 요소의 직계 부모가 되는 트리로 된다. 


▼CSS를 사용하는 페이지의 경우, HTML을 DOM 트리로 변환하는 것과 마찬가지로 CSS를 CSSOM 트리로 변환한다. 예를 들어 다음 그림과 같이 "body", "p", "span", "p span", "img"라는 선택기를 사용한 CSS의 경우....


▼아래와 같은 그림과 같은 트리로 변환된다. 또한, 아래의 트리 전체 CSSOM 트리가 아닌, 스타일 시트에서 재정의되는 스타일만 보여준다. 모든 브라우저에 기본 스타일 세트가 준비되어 있으며, 그 중 CSS에서 지정한 부분 만이 기본 스타일에서 삽입되어 바꾸어 표시된다.


렌더링 엔진은, 위의 DOM 트리와 CSSOM 트리를 사용하여 렌더링 트리를 구성한다. 렌더링 트리 콘텐츠를 올바른 순서대로 렌더링 할 수있도록 하기 위해 트리에서 "실제로 표시되는" 콘텐츠 인 렌더러의 구조를 나타낸 트리이다. 따라서 <HEAD>와 같은 렌더링되지 않는 요소는 렌더링 트리에 존재하지 않는다. 방금 전의 DOM 트리와 CSSOM 트리를 사용하여 렌더링 트리를 구축하면 다음과 같이 된다.


다음 렌더링 트리의 레이아웃을 실행한다. 이것은 방금 렌더링 트리에 추가 된 렌더러에 "위치"와 "크기"의 정보를 추가하는 작업이다. 먼저 렌더링 트리의 최상위에 위치하는 루트 노드가 배치되어 반복적으로 하위 요소가 배치되어 간다.




▼마지막으로 렌더링 트리의 그리기가 이루어진다. 그리기에는 2가지 방법이 있는데, 하나는 트리 전체를 다시 그리는 "글로벌"이라는 것이고, 다른 하나는 일부 렌더러만 다시 그리는 "인크리멘털"이라는 방법이다. 현재의 브라우저는 보다 빨리 화면에 내용을 보이게 하려고 하기 위해, HTML의 해석이 진행됨과 동시에 분석 할 만큼의 렌더링을 실시하는 것이 일반적이다.


또한 Web은 동기적이기 때문에, 분석하는 도중에 <scrip> 태그를 만나면, 스크립트가 실행될 때까지 HTML의 해석을 그 자리에서 정지해버린다. 스크립트가 네트워크에 있는 경우 네트워크에서 다운로드해야 하지만, 그동안도 분석이 중지되어 있다. 또한 HTML5 이후는 스크립트를 비동기 적으로 설정하고 다른 스레드에서 작업을 수행하도록 할 수 있다.


이러한 지식을 가지는 것으로, Web 페이지의 표시를 최적화하기 위한 단서를 얻을 수 있다. 주요 포인트는 "Javascript", "스타일 설정", "레이아웃", "그리기", "합성"의 5가지. 먼저 "Javascript"에서는 "외형을 바꿀 때에 setTimeout과 setInterval을 사용하지 않는다", "무거운 스크립트는 Web 작업자에 처리하도록", "DOM을 수정하고 싶을 때는 Web으로 처리 할 수 없기 때문에 큰 작업을 세밀하게 나눌 수 있도록 한다" 등이 효과적인 것 같다.


▼"스타일 설정"에서는, "CSS의 셀렉터를 간결하게 하기", "스타일 설정을 적용 할 요소의 수를 줄이기"라는 방법이 권장되고 있다. 전체 페이지에서 스타일을 적용하는 것이 아니라, 약간의 요소에 직접 스타일을 적용하는 것이 좋은 것.


또한 "레이아웃"이라는 점에서는, "레이아웃의 수를 가능한 한 줄이고, width나 height 등의 요소를 변경하지 않는다"거나 "Flexbox를 사용하는 것", "강제 동기화를 피하기" 등이 기재되어 있다.


"그리기"는 실행 시간이 길기 때문에 특히 중요도가 높은 것. "transform과 opacity 이외의 요소를 변화시키지 않는 것"과 "레이어 프로모션을 사용해 렌더링 범위를 줄인다"는 것으로 사이트를 최적화 할 수 있다는 것이다.