브라우저 렌더링

김윤진·2022년 3월 1일
1

브라우저

목록 보기
1/4

나는 요즘 성능 최적화에 관심이 많다

그래서 성능 최적화 강의도 찾아보고 공부하고 있다

이번 과제에서도 성능 최적화할 부분이 보여서 진행해 보았다

성능 최적화를 위해 먼저 Reflow, Repaint를 알아야 한다

일단 브라우저 렌더링 과정을 살펴보면

첫 번째로 HTML, CSS를 가공해서

각각 DOM, CSSOM 데이터 구조로 바꾼다

DOM은 요소들과의 관계를 트리 구조로 만든 것도

CSSOM은 각 요소의 스타일을 트리 구조로 만든 것이다

그 후 DOM과 CSSOM을 조합해서 최종적으로 Render Tree라는 데이터 구조를 만든다

Render Tree에는 요소에 대한 콘텐츠나 스타일들이 트리 구조로 만들어져 있다

그 후 Layout 에서는 요소에 대한 위치, 크기를 계산을 한다

화면에 Layout을 잡는다고 생각하면 된다

그 후 Paint는 스타일을 요소에 적용한다

마지막으로 Composite은 각 레이어를 합성을 합성한다

위에 Layout이나 Paint는 각 레이어로 쪼개져서 작업이 되기 때문에

이것들을 하나로 합성해주고 화면을 만들어 주는 단계이다

Reflow는 모두 재실행

Repaint는 Layout 생략

Reflow나 Repaint를 들어 봤다면

이러한 표를 봤을 것이다

그래서 이번 과제에도 적용해야지 생각하고

후훗 나는 성능 최적화를 하는 개발자라고 생각이 드는 순간

  • opacity: 0 -> opaciy: 1

  • display: none -> display: block

띠용?

아니 opacity를 적용했는데 layout, paint가 발생하잖아?

opacity라는 스타일의 변경은 reflow부터 발생하기도 하지만 어느 때는 repaint부터 발생하기도 하고 또 어느 때는 reflow, repaint 없이 composite 단계에서 GPU의 도움을 받기도 한다

참고로 tailwind.css 에서는 class를 추가할 때 GPU 도움을 받을 수 있게 지정할 수 있다

어느 때, 조건이 있다는 것이다

이 문제를 해결해보면 opacity를 변경했는데 reflow가 발생한 원인은 주어진 값이 1이어서 이다

  • opacity: 0 -> opacity: 0.99

위에서 보이는 layout이 없어졌다!!

왜왜왜죠?

일단 Layer에 대해 좀 더 알아보자

위에서 말한 것처럼 HTML을 가공해서 DOM Tree를 구성하고 CSS 가공해서 CSSOM을 구성하고

이 둘을 합쳐 Render Tree가 구성되고 Render Tree를 바탕으로 화면에 나타낼 레이어가 구성되는데

이 레이어 개념이 브라우저 렌더링 시 도입되는 이유는 z 축을 활용하는 3차원 개념을 렌더링 과정에 삽입하기 위해서이다
좀 더 어렵게 말하자면 Paint Layer는 Stacking Context를 구현하기 위한 적용 방식이다

stacking context, 쌓임 맥락은 가상의 z 축을 사용한 HTML 요소의 3차원 개념화이다

z 축은 사용자 기준이며, 사용자는 뷰포트 혹은 웹 페이지를 바로 보고 있을 것으로 가정한다

각각의 HTML 요소는 자신의 속성에 따른 우선순위를 사용해 3차원 공간을 차지한다

특정 요소의 렌더링 순서는 자신의 z-index 속성 값에 영향을 받는다

이는 그 요소들이 가진 특별한 속성으로 인해 쌓임 맥락이 생성되기 때문이다

쌓임 맥락은 문서 어디에서나 다음 조건을 만족하는 요소가 생성된다

  • 문서의 루트 요소. (<html>)
  • position이 absolute 또는 relative이고, z-index가 auto가 아닌 요소.
  • position이 fixed 또는 sticky인 요소. (sticky는 모든 모바일 브라우저에서는 해당하지만 구형 데스크톱 브라우저에서는 해당하지 않음)
  • 플렉스(flexbox) 컨테이너의 자식 중 z-index가 auto가 아닌 요소.
  • 그리드(grid) 컨테이너의 자식 중 z-index가 auto가 아닌 요소.
  • opacity가 1보다 작은 요소.
  • mix-bottom-mode 가 normal이 아닌 요소.
  • 다음 속성 중 하나라도 none이 아닌 값을 가진 요소.
    • transform
    • filter
    • perspective
    • clip-path
    • mask / mask-image / mask-border
  • isolation이 isolate인 요소.
  • webkit-overflow-scrolling 이 touch인 요소.
  • will-change의 값으로, 초깃값이 아닐 때 새로운 쌓임 맥락을 생성하는 속성을 지정한 요소.
  • contain 이 layout, paint, 또는 둘 중 하나를 포함하는 값(strict, content 등)인 요소.
  • 화면에 보이지 않지만 층을 이룰 때

쌓임 맥락 안의 자식 요소는 위의 규칙(조건)과 동일하게 사용해 쌓인다

하나의 쌓인 맥락은 부모 쌓임 맥락 안에서 통째로 하나의 단위로 간주된다

자신의 쌓임 맥락을 만들지 않는 요소는 부모의 쌓임 맥락에 동화된다고 표현할 수 있다

z-index를 예로 들어보자

루트

div#1 position: relative, z-index: 3
div#2 position: absolute, z-index: 2
div#3 position: absolute, z-index: 4
div#4 position: absolute, z-index: 1

div#3, div#4는 div#2의 자식이므로 div#2 내부에서만 둘의 쌓임 처리를 한다

div#2 내부의 쌓기와 렌더링이 끝난 후에는 형제 div와 쌓는다

div#3 은 div#1 보다 z-index가 크지만 div#1이 위에 렌더링 된다

왜냐하면 div#3의 z-index는 div#2의 쌓임 맥락 안에서만 유효하고

부모 엘리먼트의 쌓임 맥락에서의 z-index는 div#1 이 크기 때문이다

아까 opacity를 0.99로 변경했을 때 repaint가 발생하지 않는 것은 위의 규칙을 따랐기 때문이다

위의 규칙을 바탕으로 Paint Layer를 층층이 구성할 수 있다

별도의 Paint Layer를 구성할 수 있다는 것이다

이 별도의 Paint Layer로 구성되는 층에서 GPU가 처리해야 하는 층이 있다면 Graphics Layer를 구성하게 된다

또 Graphics Layer의 규칙이 있다

  • video 태그, canvas 태그 사용
  • 3D transform 요소 적용
  • animaition이나 transition 사용
  • will-change로 opacity, transform, top, left, bottom, right가 적용된 경우
  • iFrame인 경우
  • backface-visibility(요소가 뒷면이 사용자를 향할 때 보여야 하는지를 지정)가 hidden 일 경우

사실 하고 싶은 말은 위에 있는 말이 아니다

브라우저 렌더링, 성능 최적화 등등 보다 중요한 것은 알고 쓰자는 것이다

opacity transform을 쓰면 속도가 빨라진다는 것을 듣고 무조건적으로 쓰는 것이 아니라

진짜 이게 동작하는 것인지 의심하고 왜 이렇게 동작하는지 알아보는 자세를 갖추는 것이 중요한 것 같다

https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context

https://d2.naver.com/helloworld/5237120

0개의 댓글