[javascript] repaint / reflow

Yongwoo Cho·2022년 2월 4일
0

TIL

목록 보기
58/98
post-thumbnail
post-custom-banner

browser의 작동방식


위의 그림은 렌더링 엔진이 어떻게 화면을 표시하는지에 대한 그림이다.

렌더링 엔진은 HTML 문서를 파싱 한다. 그리고 DOM tree를 구축한다. 다른 한쪽에서는 CSSOM tree를 구축한다. DOM tree와 CSSOM 결합되어 렌더 트리를 구성한다. 그리고 각각의 노드가 화면에 정확한 위치에 표시되도록 layout(화면에 배치)을 시작한다. 그리고 브라우저는 paint(화면에 그리기)를 실시한다.

DOM tree


HTML 마크업이 여러 태그 간의 관계(html > head > body...)를 정의하기 때문에 생성된 객체는 트리 구조로 연결된다.

CSSOM tree


HTML과 마찬가지로 CSS를 브라우저가 이해하고 처리할 수 있도록 동일한 과정으로 변환한다. 그 결과 CSS Object Model(CSSOM)이라는 트리 구조가 생성된다.

Render tree (=Attachment)


렌더 트리는 DOM과 CSSOM의 결합으로 생성된다. 렌더 트리는 페이지에 표시되는 모든 DOM 콘텐츠와 각 노드에 대한 모든 CSSOM 스타일 정보를 담고 있다.

❗ DOM Tree에 있는 모든 노드가 Render Tree로 추가되는 것이 아니다.

비시각적 DOM의 요소들은(meta, head 등) 렌더 트리에 추가되지 않는다. 또한, display 속성의 'none'값이 할당된 요소는 렌더 트리에 추가되지 않는다.

layout(reflow)

Layout(reflow) 단계에서는 브라우저의 Viewport 내에서 생성된 Render Tree의 각각의 노드들의 위치와 크기를 계산한다.
즉, 생성된 Render Tree 노드들이 가지고 있는 스타일과 속성에 따라서 브라우저 화면의 어느 위치에 어느 크기로 출력될지 계산하는 단계이다. 이를 통해 %와 같이 상대적인 위치, 크기 속성은 실제 화면에 그려지는 pixel단위로 변환된다.

paint

Layout 단계를 통해 위치, 크기 속성이 pixel단위로 변환되면, 즉, 레이아웃이 완료되면 브라우저는 'Paint Setup' 및 'Paint' 이벤트를 발생시킨다. 이 이벤트를 통해 렌더링 트리를 화면의 픽셀로 변환한다. 이 과정을 거친 후 브라우저 화면에 UI가 나타나게 된다.

reflow란 ?

어떠한 액션이나 이벤트에 의해 DOM 요소의 크기나 위치 등을 변경하면 해당 노드의 하위 노드와 상위의 노드들을 포함하여 Layout 단계를 다시 수행하게 된다. 즉 변경하려는 특정 요소의 위치와 크기뿐만 아니라 연관된 요소들의 위치와 크기도 재계산을 하기 때문에 브라우저의 퍼포먼스를 저하시키는 요인이다.

repaint란?

Render Tree를 다시 화면에 그려주는 과정이다. 즉 paint 과정이 다시 수행되는 것이다.
위에서 설명한 Reflow가 발생하면 변경된 Render Tree를 화면에 다시 그려줘야 한다. 이때, Repaint가 발생한다.
또한 레이아웃에 영향을 주지 않는 color, background-color 등과 같은 스타일 속성을 변경했을 때 발생한다. Repaint 역시 Reflow와 같이 연산이 필요하기 때문에 브라우저의 퍼포먼스에 영향을 준다.

reflow / repaint 의 주요원인

  • 윈도우 리사이징 (뷰포트 변화는 Global Layout에 영향)
  • 폰트의 변화 (height계산에 영향을 주므로 Global Layout에 영향)
  • 스타일 추가 또는 제거
  • 내용 변화 (인풋박스에 텍스트 입력 등..)
  • :hover와 같은 CSS Pseudo Class
  • 클래스 Attribute의 동적 변화
  • JS를 통한 DOM 동적 변화
  • 엘리먼트에 대한 offsetWidth / offsetHeight (화면에서 보여지는 좌표) 계산시
  • 스타일 Attribute 동적변화

reflow / repaint 최소화

  1. 최대한 DOM 구조 상 말단 노드에만 클래스를 사용
  2. 인라인 스타일 자제
  3. 애니메이션은 positon을 absolute와 fixed로 하기
    (주변 레이아웃 영향을 주지 않기 때문)
  4. 퀄리티와 퍼포먼스를 타협
  5. 테이블로 구성된 레이아웃 자제 (테이블 전체 노드가 reflow 발생)
  6. CSS에서의 JS표현식 자제 (Reflow될 때마다 표현식이 다시계산됨)
  7. JS를 통한 스타일 변화는 최대한 grouping
  8. CSS 하위 선택자는 필요한 만큼만 쓰기
  9. 일부 속성과 메서드는 자주 사용할 때 캐싱하기
  10. position: relative; 주의!
    -일반적인 경우: Box model → Normal flow
    -position:absolute or fixed: Box model → Out of flow(Positioning)
    -position:relative: Box model → Normal flow → Positioning
profile
Frontend 개발자입니다 😎
post-custom-banner

0개의 댓글