Skip to content

Latest commit

 

History

History
217 lines (159 loc) · 7.35 KB

Layer_Model.md

File metadata and controls

217 lines (159 loc) · 7.35 KB

Layer Model

브라우저의 layer model에 대해 알아보자.

layer란

브라우저는 크게 layer를 두가지로 분류한다.

  • RenderLayer
  • GraphicsLayer

RenderLayer

렌더 레이어는 DOM의 subTree에 대응되는 rendering critical path의 render tree(frame tree)의 결과를 말한다.

GraphicsLayer

그래픽스 레이어는 그 외의 레이어를 말한다. 이 글에서 render layer는 크게 중요하지 않으니 그래픽스 레이어만 다루도록 하자.

그래픽스 레이어는 GPU에 텍스쳐로 업로드된다.(GraphicsLayers are what get uploaded to the GPU as textures)

이 GPU의 텍스쳐에 대해 조금 알아보자.

GL - GPU

texture는 RAM(주기억장치)에서 GPU의 VRAM(비디오메모리)으로 이동하는 image라고 생각하면 된다. image가 GPU에 올라가게 되면 mesh geometry라는 것과 매핑된다.

이 mesh는 아래 그림처럼 3차원 모델을 만들 때 다각형의 집합으로 이루어진 모델같은 것이다.

mesh

출처: unity documentation

layer-texture

크롬은 각 그래픽스 레이어를 texture로 취급하여 GPU에 올린다.

즉 한 장의 image 파일처럼 취급하여 GPU에게 위임한다. GPU에서 texture는 사각형의 메쉬로 만들어진다. 그래서 layer의 position을 수정한다거나 변형(transformation)하는 경우 매우 저렴한 비용으로 매핑될 수 있다.

3D CSS는 이러한 방식으로 작동한다.

layer 생성 기준

이러한 layer가 생성되는 기준은 다음과 같다.

  • 3D나 perspective를 표현하는 CSS transform 속성을 가진 경우
  • 하드웨어 가속 디코딩을 사용하는
  • 3D 컨텍스트(WebGL) 혹은 하드웨어 가속 2D 컨텍스트를 가지는 엘리먼트
  • (플래시와 같은) 플러그인 영역
  • 투명도(opacity) 속성 혹은 webkit transform의 애니메이션의 사용
  • 가속 가능한 CSS 필터를 가진 경우css filter
  • 합성 레이어(Compositing Layer)를 하위 노드로 가진 경우
  • 낮은(lower) z-index를 가진 형제 노드(Sibling)가 합성 레이어(Compositing Layer)를 가진 경우

layer 눈으로 확인하기

layer를 확인하는 가장 좋은 방법은 개발자 도구를 이용하는 것이다. 개발자 도구를 열어서 rendering - layer borders 옵션을 켜면 오렌지색 테두리로 레이어를 보여준다.

단일 layer

<!DOCTYPE html>
<html>
  <body>
    <div>this is single layer</div>
  </body>
</html>

singleLayer

transform 사용하여 layer 나누기

css transform 속성을 사용하면 layer가 나뉘게 된다.

<!DOCTYPE html>
<html>
  <body>
    <div style="transform: rotateY(30deg) rotateX(-30deg); width: 200px;">
      this is detached layer
    </div>
  </body>
</html>

transformLayer

transform을 사용하면 div와 body가 구분되어 layer를 가지는 것을 확인 할 수 있다.

animation

layer를 분리하면 가장 좋은 점은 reflow(relayouting)와 repaint를 하지 않는다는 점이다.

<!DOCTYPE html>
<html>
  <head>
    <style>
      div {
        animation-duration: 5s;
        animation-name: slide;
        animation-iteration-count: infinite;
        animation-direction: alternate;
        width: 200px;
        height: 200px;
        margin: 100px;
        background-color: gray;
      }
      @keyframes slide {
        from {
          transform: rotate(0deg);
        }
        to {
          transform: rotate(120deg);
        }
      }
    </style>
  </head>
  <body>
    <div>this is animation</div>
  </body>
</html>

animation

위 사진에서는 초록색 부분이 페인트다. 레이어가 분리되어 다르게 동작하기때문에 paint는 처음에만 일어나며 다시 일어나지 않는다.

reflow repaint

<!DOCTYPE html>
<html>
  <head>
    <style>
      div {
        animation-duration: 5s;
        animation-name: slide;
        animation-iteration-count: infinite;
        animation-direction: alternate;
        width: 200px;
        height: 200px;
        margin: 100px;
        background-color: gray;
      }
      @keyframes slide {
        from {
          transform: rotate(0deg);
        }
        to {
          transform: rotate(120deg);
        }
      }
    </style>
  </head>
  <body>
    <div id="foo">I am a strange root.</div>
    <input id="paint" type="button" value="repaint" />
    <script>
      var w = 200;
      document.getElementById('paint').onclick = function() {
        document.getElementById('foo').style.width = w++ + 'px';
      };
    </script>
  </body>
</html>

다음의 코드는 버튼을 클릭하면 1px씩 증가한다.

따라서 화면을 재 계산해야 하기 때문에 reflow(relayouting) 후 repaint를 하게 된다.

위 코드는 직접 개발자도구를 실행시켜 확인해보자.

종합

레이아웃을 중심으로 브라우저가 DOM을 렌더링 하는 과정은 다음과 같다.

  1. DOM을 얻고 그것들을 레이어들로 분리합니다.
  2. 이 레이어들 각각을 독립적인 소프트웨어 비트맵으로 출력합니다.
  3. 그것들을 GPU에 텍스쳐로써 업로드합니다.
  4. 다양한 레이어를 최종 스크린 이미지로 함께 합성(composite)합니다.

강제로 레이어를 분리하여 코딩하면 repaint를 일으키지 않고 동작하기 때문에 성능에 매우 유리하다.

좋은 예로는 네이버 모바일페이지에서 화면을 좌/우로 변경하면서 layer를 확인해보자.

처음에만 paint를 하고 그 뒤로는 layer만 변경되는 것을 찾아볼 수 있다.

단점

만능은 아니다.

당연히 레이어별로 메모리를 다르게 할당한다.

또한 GPU의 video memory는 RAM과 물리적으로 다른 공간에 위치한다. 따라서 texture를 옮기는 데이터 송수신의 손실도 발생한다.

또한 RAM => VRAM으로 이동하려면 결국 CPU -> RAM에서 texture 로드 -> GPU VRAM으로 전송의 과정이 필요하다.

CPU가 연산하지 않으면 안된다. CPU가 직접 처리하지 않을 뿐 CPU가 작동하지 않는 것은 아니다.

texture 데이터를 다루는 시간도 고려해야 한다.


참고자료