브라우저 작동 원리(5)-레이아웃
렌더러
가 생성되어 트리에 더해질 때 크기
와 위치
에 대한 정보는 가지고 있지 않습니다. 이러한 값을 계산하는 게 배치(layout)
과 리플로우(reflow)
입니다
HTML은 흐름(flow)에 기반한 배치(layout) 모델
을 사용하는데 이는 보통 단일 경로(single-pass)를 통해 위치 정보를 계산할 수 있다는 것을 말합니다
일반적으로 흐름
속에서 나중에 등장하는 요소들은 먼저 등장한 요소의 위치와 크기에 영향을 주지 않기 때문에, 배치는 좌->우
나 위->아래
로 진행됩니다. HTML의 table
은 하나 이상의 경로를 요구하기 때문에 예외사항에 포함 됩니다
좌표계(coordinate system)
는 기준점(root frame)
으로부터 상대적인 위치를 정하기위해 상단(top/y)과 좌단(left/x) 좌표를 사용합니다
배치
는 반복적인 과정으로, HTML 문서의 html
요소에 해당하는 root 렌더러
에서 시작됩니다. 배치
는 프레임 계층의 일부나 전부를 통해서 반복되며, 각 렌더러
를 위한 크기
나 위치
정보를 계산합니다
root 렌더러
의 좌표는 0,0
이고 브라우저의 창이 보이는 만큼의(viewport) 면적을 가집니다
모든 렌더러
는 layout
이나 reflow
메소드를 가지는데 각 렌더러
는 배치해야할 자식의 layout
메소드를 호출합니다
더티 비트 시스템(Dirty bit system)
간단한 변경 때문에 전체를 다시 배치하지 않기위해 브라우저는 더티 비트 시스템을 사용합니다. 변경되거나 추가된 렌더러
는 자신과 자기의 자식들을 더럽다고
표시합니다 (더러움 = 재배치가 필요함)
두가지 종류의 flag
가 사용됩니다 : 각각 더티
와 자식이 더티함
(렌더라 자신은 괜찮지만 자식 중 적어도 하나는 재배치가 필요하다는 의미)
전역(Global) 배치와 점증(incremental) 배치
배치
는 전체 렌더 트리
에서 발생할수도 있는데 이걸 전역 배치
라고 합니다. 이런 상황은 다음과 같은 경우에 발생합니다
- 글꼴 크기 변경과 같이 모든
렌더러
에 영향을 주는전역 스타일
변경- 화면 크기 변경에 의한 결과
배치
는 더티 렌더러
가 배치되는 경우만 점증
되는데, 추가적인 배치가 필요하기 때문에 약간의 손실이 발생할 수 있습니다
점증 배치
는 렌더러
가 더티일때 비동기적으로 이루어집니다. 예를 들어 네트워크로부터 추가 내용을 받아서 DOM 트리
에 추가된 다음 새로운 렌더러
(더티로 취급됨)가 렌더 트리에 추가되는 경우입니다
비동기 배치와 동기 배치
점증 배치
는 비동기로 실행됩니다
파이어폭스
는 점증 배치
를 위한 reflow
명령을 쌓아놓고 스케쥴러는 이 명령을 한번(batch 방식)에 실행합니다. 웹킷
도 점증 배치
를 실행하는 타이머를 가지는데 트리를 탐색해 더티 렌더러
를 배치합니다
offsetHeight
같은 스타일 정보를 요구하는 스크립트는 점증 배치
를 동기적으로 실행합니다. 전역 배치
는 주로 동기적으로 수행됩니다
가끔식 배치는 스크롤 위치변화 같은 일부 속성들 때문에 처음 배치된 이후 callback
으로 실행됩니다
최적화
배치
가 크기 변경이나 렌더러 위치 변화 때문에 실행되는 경우, 렌더러
의 크기는 다시 계산하지 않고 캐쉬에서 가져옵니다
어떤 경우에는 root로부터 시작하지않고 하위 트리만 수정이 되는 사례도 있습니다. 이건 입력 필드에 텍스트를 입력하는 것처럼 변화되는 범위가 한정적(local)이여서 주변에 영향을 주지 않는 경우에 발생합니다. 만약 입력 필드 외부에서 텍스트가 입력됬다면 root부터 시작됩니다
배치과정
배치 과정은 주로 다음과 같은 형태로 진행됩니다
- 부모 렌더러가 자신의 너비 결정
- 부모가 자식을 검토
2-1. 자식의 렌더러 배치 (x
,y
설정)
2-2. 필요하다면 자식의 배치 호출하여 높이를 계산(부모와 자식이 더티하거나, 전역 배치 상태이거나 등등)- 부모는 자식의 중첩된 높이에
여백(margin)
,패딩(padding)
을 사용해 자신의 높이를 설정합니다. 이 값은 부모 렌더러의 부모가 사용합니다- 더티 비트 플래그를 제거합니다
파이어 폭스
는 상태(state) 객체(=nsHTMLReflowState)
를 배치(=reflow
)를 위한 매개변수로 사용합니다. 상태 객체는 부모의 너비를 포함합니다
파이어 폭스
의 배치 결과는 매트릭스(metrics) 객체(=nsHTMLReflowMetrics)
입니다. 이 객체는 렌더러
의 계산된 높이를 가지고 있습니다
너비 계산
렌더러
의 너비는 컨테이너(포함하는 블록)의 너비
와 렌더러의 너비(width), 여백(margin), 경계선(border)
를 가지고 계산됩니다
예를 들어 다음과 같은 div
요소가 있을 때
<div style="width: 30%"/>
웹킷
은 다음과 같이 계산합니다(RenderBox
클래스의 calcWidth
메소드)
컨테이너의 너비는
availableWidth
와 0 사이의 최대 값입니다. 이 경우의availableWidth
는 다음과 같이 계산됩니다
clientWidth() - paddingLeft() - paddingRight()
clientWidth
와clientHeight
는 경계선과 스크롤바를 제외한 내부의 영역을 의미합니다요소의 너비는
width
속성의 값입니다. 여기서는 컨테이너 너비의 백분율이 절대값으로 변환될 것입니다수평(좌우)의 너비와 패딩 값이 추가됩니다
여기까지가 미리 획득한 너비(clientHeight)
의 계산이고, 이제 최소 너비
와 최대 너비
를 계산해야합니다
만약 미리 획득한 너비
가 최대 너비보다 크다면 최대너비가 사용되고, 만약 미리 획득한 너비
가 최소 너비(더 나눠지지 않는 가장 작은 단위)보다 작으면 최소 너비가 사용됩니다
배치
가 필요한 경우 값들은 캐쉬에 저장되지만 너비는 변경되지 않습니다
줄바꿈(Line Breaking)
렌더러
가 배치되는 동안 줄을 바꿀필요가 있을 때, 배치
는 중단되고 그 필요를 부모에게 전달(propagates)합니다. 부모는 그러면 추가 렌더러
를 생성하고 이것들의 배치
를 호출합니다
참고 및 출처
https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/
https://d2.naver.com/helloworld/59361
Author And Source
이 문제에 관하여(브라우저 작동 원리(5)-레이아웃), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@trollering12312/브라우저-작동-원리5-레이아웃저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)