웹 성능 최적화 - 1. animation

Jiwoo JEONG·2022년 8월 3일
1

성능 최적화

목록 보기
1/1
post-thumbnail

Animation 최적화

이전에는...


(*실행 화면 : mov를 gif로 변환한 이미지)

  • 이전에는 브라우저의 Rendering 과정에 대한 이해가 부족하여서 animation을 사용할 때 width, left, right과 같은 reflow, repaint를 발생 시키는 animation을 만들었다.
  • 이는 브라우저의 re-rendering을 발생시켜 성능을 악화 시킨다.
#reflow, repaint 발생

const Circle = styled.div<{ active: boolean }>`
  width: 20px;
  height: 20px;
  border-radius: 100px;
  background-color: ${BrandColor.white};
  animation: ${props => (props.active ? 'toActive' : 'toInactive')} 0.4s
    forwards;

  @keyframes toActive {
    0% {
      margin-left: 0;
    }
    100% {
      margin-left: 24px;
    }
  }
  @keyframes toInactive {
    0% {
      margin-left: 24px;
    }
    100% {
      margin-left: 0;
    }
  }
`;

그러면 브라우저의 Rendering 과정은?

  1. HTML을 기반으로 DOM을 그린다.
  2. DOM을 그리다가 style을 만나면 잠시 멈추고 CSSOM을 그린다.
  3. 1,2를 왔다갔다 하며 DOM tree, CSSOM tree를 생성한다.
  4. 3의 tree 두가지를 이용하여 Render tree를 생성한다.
  5. Layout을 그린다.
  6. Paint.

그래서 어떻게 변했나?

  • width, left 등 위치나 크기를 변경하는 animation의 경우에는 브라우저의 rendering 과정을 재실행하고 다시 그린다 -> Reflow, Repaint
  • color, background-color와 같이 위치나 크기가 아닌 색상을 변경하는 animation은 브라우저의 layout을 생략하고 paint한다 -> Repaint
  • 따라서 transform, opacity와 같이 브라우저가 아닌 GPU가 관여하는 요소를 animation으로 구성하여 reflow, repaint 과정을 생략한다.
const Circle = styled.div<{ active: boolean }>`
  width: 20px;
  height: 20px;
  border-radius: 100px;
  background-color: ${BrandColor.white};
  transform-origin: left;
  transform: translateX(${props => (props.active ? '24px' : 0)});
  transition: transform 400ms ease;

  box-shadow: ${props =>
    props.active
      ? `-2px 2px 4px rgba(0, 0, 0, 0.15)`
      : `2px 2px 4px rgba(0, 0, 0, 0.15)`};
`;
profile
FE Developer as Efficiency Maker

0개의 댓글