브라우저 렌더링 과정을 공부하다가 렌더링이 무엇인지 관련 개념들을 정리를 해야겠다고 생각이 들었다.
서버로부터 HTML 파일을 받아 브라우저에 뿌려주는 과정
더 자세한건 3참고
렌더링이 완료된 상태에서 사용자의 인터랙션에 의해 화면의 일부 영역이 변경됐을 때 발생한다. 레이아웃이 변경될 경우 리플로우 리페인트를 거침, 레이아웃에는 영향을 주지 않지만 가시성에는 영향을 주는 엘리먼트가 변경될 때는 리페인트만 거침 (ex: opacity, background-color)
인라인 스타일은 가독성을 해칠뿐 아니라, 수차례 리플로우를 발생시킴. 외부 스타일을 사용할 경우 1회 리플로우를 발생시킴
DOM 요소의 정보를 요청하고 변경하는 코드는 같은 형태의 작업끼리 묶어 실행한다.
display의 속성 값을 none으로 하면, 렌더링 트리에서 노드가 빠지게 된다. 따라서 노드를 노출시킨채 스타일을 변경하는 것보다 노드를 감추고 스타일을 변경한 후 노드를 노출시키는 것이 리플로우와 리페인트 발생횟수를 줄이는 방법이다.
let element = document.getElementById("box1");
for(let i=50; i<100; i++) {
element.style.width = i + "px";
}
for(let i=1; i<=50; i++) {
element.style.borderWidth = i + "px";
}
// 아래와 같이 렌더링 트리에서 빼준 다음, 스타일을 적용하고 다시 노출.
// 이 경우 두번의 리플로우 리페인트만 발생
let element = document.getElementById("box1");
element.style.display = "none";
for(let i=50; i<100; i++) {
element.style.width = i + "px";
}
for(let i=1; i<=50; i++) {
element.style.borderWidth = i + "px";
}
element.style.display = "block";
변경하려는 요소의 노드를 복제한 후 복제된 노드에 작업을 하고, 교체를 해주면 리플로우와 리페인트는 한번만 발생함
여기서 말하는 캐싱은 별도의 변수에 자주 사용하는 값을 저장하는 것임. scrollWidth와 같은 값을 호출할 경우 리플로우를 유발하기 때문에, 반복 구문을 실행하기 전에 이를 변수에 담아놓으면 리플로우 발생을 최소화 할 수 있음
① 브라우저는 서버로부터 HTML 문서를 모두 전달 받는다.
② 렌더링 엔진은 전달받은 HTML 문서 파싱하여 DOM 트리를 구축한다.
③ 외부 CSS 파일과 함께 포함된 스타일 요소를 파싱한다.(CSSOM(CSS Object Model) 생성)
④ DOM 트리와 ③의 결과물을 합쳐 렌더 트리를 구축한다.
⑤ 렌더 트리의 각 노드에 대해서 화면 상에서 어디에 배치할 지 결정한다.
⑥ UI백엔드에서 렌더 트리를 그리게 되고, 화면에 우리가 볼 수 있도록 출력된다.
브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 것
렌더링을 위한 트리의 자료구조, 브라우저 화면에 표시할 노드들로만 구성되어 있으며 CSS에 비표시되는 노드들은 포함되지 않는다.
레이아웃을 계산하는데 사용되고, 브라우저 화면에 픽셀을 렌더링하는 페인팅 처리에 입력된다.
참고 글
https://velog.io/@ru_bryunak/%EB%A0%8C%EB%8D%94%EB%A7%81%EC%9D%B4%EB%9E%80
https://all-young.tistory.com/22