브라우저의 렌더링

이지훈·2021년 11월 18일
0

공부한것들

목록 보기
12/15

브라우저 렌더링 과정

오늘 공부한 것은 브라우저 렌더링에 대한 것으로 네이버 D2에 게시된 글을 보고 많은 걸 배웠다.
너무나 많은 내용이 있어서 다 알진 못하지만 그래도 중요하다고 생각하는걸 정리해봤다.

브라우저 구성


브라우저의 주요 구성은 사용자 인터페이스, 브라우저 엔진, 렌더링 엔진, 통신, UI백엔드, 자바스크립트 해석기, 자료저장소로 이루어져있다고 한다.

사용자 인터페이스 - 주소 표시줄, 이전/다음 버튼, 북마크 메뉴 등. 요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분이다.
브라우저 엔진 - 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어.
렌더링 엔진 - 요청한 콘텐츠를 표시. 예를 들어 HTML을 요청하면 HTML과 CSS를 파싱하여 화면에 표시함.
통신 - HTTP 요청과 같은 네트워크 호출에 사용됨. 이것은 플랫폼 독립적인 인터페이스이고 각 플랫폼 하부에서 실행됨.
UI 백엔드 - 콤보 박스와 창 같은 기본적인 장치를 그림. 플랫폼에서 명시하지 않은 일반적인 인터페이스로서, OS 사용자 인터페이스 체계를 사용.
자바스크립트 해석기 - 자바스크립트 코드를 해석하고 실행.
자료 저장소 - 이 부분은 자료를 저장하는 계층이다. 쿠키를 저장하는 것과 같이 모든 종류의 자원을 하드 디스크에 저장할 필요가 있다. HTML5 명세에는 브라우저가 지원하는 '웹 데이터 베이스'가 정의되어 있다.

렌더링 엔진

렌더링 엔진은 브라우저마다 다른데, 대표적으로 파이어폭스에선 게코(Gecko) 엔진, 사파리와 크롬은 웹킷(Webkit)엔진을 사용한다.

엔진의 동작 과정

렌더링 엔진은 통신으로부터 문서의 내용을 얻는 것으로 시작하는데 보통 8KB단위로 전송된다.

다음은 렌더링 엔진의 기본적인 동작 과정이다.

렌더링 엔진은 HTML문서를 파싱하여 태그를 DOM 노드로 변환한다. 그 다음 외부 CSS 파일과 함께 포함된 스타일 요소도 파싱한다. 이후 스타일 정보와 HTML 표시 규칙은 렌더 트리라는 트리를 생성한다.

렌더 트리 생성 후에는 배치가 시작된다. 배치는 각 노드가 화면의 정확한 위치에 표시되는 것이다. 다음은 UI백엔드에서 렌더 트리의 각 노드를 통해 형상을 만들어 내는 그리기 과정이다.

렌더링 엔진은 좀 더 나은 사용자 경험을 위해 모든 HTML을 파싱할 때 까지 기다리지 않고 배치와 그리기 과정을 시작한다. 네트워크로 나머지 내용이 전송되기를 기다리는 동시에 받은 내용 일부를 먼저 화면에 표시하는 것이다.

동작 과정 예의 그림이다.
1.웹킷
웹킷
2.모질라의 게코

동작 과정은 동일하다. 하지만 웹킷과 게코는 용어를 다르게 사용하고 있다.

시각적으로 처리되는 렌더 트리를 게코는형상트리(frame tree), 각 요소를 형상(frame)이라고 하지만 웹킷은 렌더 객체(render object)로 구성된 렌더 트리(render tree)라고 부른다.

요소 배치를 게코는 리플로(reflow), 웹킷은 배치(layout)이라 한다.

웹킷은 렌더 트리를 생성하기 위해 DOM 노드와 시각 정보를 연결하는 과정인 어태치먼트(attachment)가 있다.
게코는 HTML과 DOM트리 사이에 콘텐츠 싱크(content sink)라고 부르는 과정이 있는데 이는 DOM 요소를 생성하는 공정으로 웹킷과 비교해 큰 차이점은 아니다.

파싱과 DOM 트리 구축

사실 파싱은 내용이 너무 많기도 하고 나에겐 어려워서 읽어보았지만 이해하지 못했다. 내가 이해하고 렌더링 과정에서 중요하다고 생각하는 부분만 추려보았다. 자세한 부분은 원문을 참고해주시면 좋겠다.

파싱은 문서에 작성된 언어 또는 형식의 규칙에 따르는데, 파싱 할 수 있는 모든 형식은 정해진 용어와 구문 규칙에 따라야하고 이를 문맥 자유 문법이라고 한다. 인간의 언어는 이렇지 않아 기계적 파싱이 불가능하다.

HTML 파서

HTML파서는 HTML마크업을 파싱 트리로 변환한다.

전통적인 파서는 HTML에 사용할 수 없다. 파싱은 CSS, 자바스크립트를 파싱하는데 사용된다.

하지만 HTML은 문맥 자유 문법이 아니다! HTML정의를 위한 공식적인 형식으로 DTD(문서 형식 정의)가 있지만 이것은 문맥 자유 문법이 아니다.

HTML은 XML과 유사하고, 사용가능한 XML 파서는 많다. XHTML도 있는데 무슨 차이점일까.

차이는 HTML이 더 너그럽다는 점이다. HTML은 뻣뻣하고 부담스러운 XML에 비해 더 "유연"하다. HTML에서는 암묵적으로 태그에 대한 생략이 가능하고, 시작 또는 종료 태그를 생략하기도 한다.

웹 제작자의 실수를 너그럽게 용서하고 편하게 만들어주는 이 점이 HTML이 더 인기있던 이유이기도 하다. 하지만 이렇게 되면 문법 작성이 어려워지고 HTML은 파싱하기 어렵고 전통적인 구문 분석이 불가능해 문맥 자유 문법이 아니라는 것이다. XML파서로도 파싱하기 쉽지 않다.

이렇게 HTML파서는 여러 오류들을 처리하며 HTML을 분석해 DOM을 만든다.

CSS 파싱


CSS 파서는 CSS파일을 스타일 시트 객체로 파싱하고 각 객체는 CSS 규칙을 포함한다. CSS 규칙 객체는 선택자와 선언 객체 그리고 CSS문법과 일치하는 다른 객체를 포함한다.

이렇게 구축된 트리를 CSSOM(CSS Object Model)이라고 한다.

렌더 트리 구축

DOM 트리와 CSSOM트리를 통해 렌더 트리를 구축한다.

DOM 트리가 구축되는 동안 브라우저는 렌더 트리를 구축한다. 표시해야 할 순서와 문서의 시각적인 구성 요소로써 올바른 순서로 내용을 그려내기 위함이다.

DOM 트리와 렌더 트리의 관계

렌더러는 DOM요소에 부합하지만 1:1대응은 아니다. "head"요소와 같은 비시각적인 DOM요소는 렌더 트리에 추가되지 않는다. 또한 display속성에 "none"값이 할당된 요소는 트리에 나타나지 않는다.(그러나 visibility 속성이 "hidden"값이 할당된 요소는 트리에 나타난다)

여러 개의 시각 객체와 대응하는 DOM 요소도 있다. 예를 들면 "select"요소는 '표시 영역, 드롭다운 목록, 버튼' 표시를 위한 3개의 렌더러가 있다. 또한 한 줄에 충분히 표시할 수 없는 문자가 여러 줄로 바뀌게 되면 새 줄은 별도의 렌더러로 추가된다. 또 다른 예는 깨진 HTML이다. CSS명세에 의하면 인라인 박스는 블록 박스만 포함하거나 인라인 박스만을 포함해야하는데 그 둘이 섞여있는 경우 인라인 박스를 감싸기 위한 익명의 블록 렌더러가 생성된다.

렌더 객체가 DOM노드에 대응은 하지만 트리에서 동일한 위치에 있지 않은 경우도 있다. float처리된 요소 또는 position 속성 값이 absolute로 처리된 요소는 흐름에서 벗어나 트리의 다른 곳에 배치된 상태로 형상이 그려진다. 대신 자리 표시자가 원래 있어야 할 곳에 배치된다.


렌더 트리와 DOM 트리의 대응. 뷰포트는 최초의 블록으로 웹킷에서는 RenderView가 이 역할을 한다.

배치

렌더러가 생성되어 트리에 추가될 때 크기와 위치 정보는 없다. 이런 값을 계산하는 것을 배치 또는 리플로라고 한다.

모든 상대적인 측정값은 화면에서 절대적인 픽셀로 변환된다.

페인팅

렌더링 트리의 각 노드를 화면의 실제 픽셀로 변환하게 된다. 배치 단계에서 모든 계산이 완료되면, 화면에 요소들을 그리게 되는데, 이 단계를 페인팅 또는 레스터화라고 한다.

이미 배치 단계에서 각 노드들의 위치, 크기, 색상 등 스타일이 모두 계산되었기에 화면에 실제 픽셀로 변환하게 된다.

리플로우(Reflow), 리페인트(Repaint)

새로운 HTML요소가 추가되거나, 기존 요소의 스타일이 바뀌는 경우 영향을 받는 모든 노드에 대해 렌더링 트리 생성과 배치 과정을 다시 수행한다. 이 과정을 리플로우(Reflow)라고 한다

리플로우에서는 변경사항 반영을 위해 렌더링 트리 생성, 배치 과정을 다시 수행하고 실제 이 결과를 화면에 그리기 위해서는 다시 페인팅 단계를 수행해야 한다. 이 과정을 리페인트(Repaint)라고 한다.

무조건 리플로우-리페인트로 이어지는것은 아니고, 레이아웃에 영향을 미치지 않는 단순한 색상변경 등은 리플로우 없이 리페인트만 일어나게 된다. 이러한 점을 이용해 리플로우를 하지않고 리페인트만 할 수 있게 최적화를 진행할 수도 있다.

리플로우가 일어나는 속성들:
position, width, height, margin, padding, border, border-width, font-size, font-weight, line-height, text-align, overflow

리페인트만 일어나는 속성들:
background, color, text-decoration, border-style, border-radius

더 알아봐야할 것

  • 브라우저의 파싱 과정
  • 각 과정에 대한 상세 정보.
    원래는 모든 내용을 정리해 담을 생각이었지만 생각보다 너무나 많은 정보가 있어서 한번에 담기에는 무리가 있어 전체 과정을 위주로 급하게 마무리 했다. 각 단계별 자세한 정보를 한번씩 더 알아보며 공부해야겠다. 브라우저의 가장 기본적인 동작들이지만 내가 모르는부분이 많아 아직 부족함을 느낀다.

도움, 출처

profile
안녕하세요! 대학교 졸업한 이지훈입니다.

0개의 댓글