reflow와 repaint가 많을수록 성능저하를 유발한다고 알고있는데, 이론으로 말고 실제로 구현과 측정을 통해서 어떤 차이가 있는지 알아보고 싶어서 테스트를 작성해봤다.
1. DevTool에서 성능(performance)탭에서 알아본다.
2. 레이아웃이 다시 되는지 확인한다. -> reflow를 확인한다.
relfow
생성된 DOM 노드의 레이아웃(너비, 높이 등) 변경 시 영향받는 모든 노드(자식, 부모)의 수치를 다시 계산하여 렌더 트리를 재생성하는 작업입니다.
repaint
reflow 과정이 끝난 후, 재생성된 렌더 트리를 다시 그리는 작업으로 수치와 상관없는 background-color, visibility, outline 등의 스타일 변경시에는 reflow 과정이 생략 된 repaint 작업만 수행합니다.
그냥 쉽게 해서 종이에 상자 그림이 있고 그걸 다시 그린다고 가정했을 때 아래와 같지 않을까 싶다.
step1 : 종이에 그릴 상자의 너비, 높이, 위치를 다시 계산한다. -> reflow
step2 : 상자를 빨간색으로 다시 칠한다. -> repaint
left로 박스의 위치를 이동시켰을 때
HTML 코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
@keyframes reposition {
0% {
}
100% {
left: 200px;
}
}
body {
margin: 0;
}
#box {
width: 200px;
height: 200px;
background-color: black;
position: absolute;
left: 0;
}
.move {
animation: reposition 3s ease-in forwards;
}
</style>
</head>
<body>
<button id="button">Move!</button> // 버튼
<div id="box"></div> // 박스
<script>
const box = document.getElementById("box");
button.addEventListener("click", () => {
box.className = "move";
});
</script>
</body>
</html>
결과 영상
호출 트리를 보면 레이아웃에 11.0ms 가량 시간이 걸린 것을 확인할 수 있다.
결과 사진
이벤트 로그에서 "레이아웃"으로 검색하면 이동할 때마다 reflow가 발생함을 확인할 수 있다.
transform으로 박스의 위치를 이동시켰을 때
HTML 코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
margin: 0;
}
#box {
width: 200px;
height: 200px;
background-color: black;
position: absolute;
left: 0;
}
.move {
transform: translateX(200px);
transition: transform 3s ease-in;
}
</style>
</head>
<body>
<button id="button">Move!</button>
<div id="box"></div>
<script>
const box = document.getElementById("box");
button.addEventListener("click", () => {
box.className = "move";
});
</script>
</body>
</html>
결과 영상
결과 사진
이벤트 로그에서 "레이아웃"으로 검색하면 reflow가 발생하지 않는 걸 확인할 수 있다.
작성한 단순한 코드여서 레이아웃에 11.0ms의 차이가 있지만, 상자를 50개라면 어떨까 궁금했다. 🧐
상자 50개로 다시 테스트해 본 결과
left로 구현했을 때 레이아웃에 19ms가 걸렸다.
transform으로 구현했을 때는 역시나 레이아웃에 소모되는 시간이 없다.
결론
테스트용이라서 엄청 큰 차이는 없어보일 수 있으나, 코드가 복잡해지고 애니메이션이 많아진다면 영향을 미칠 수 있다는 생각이 들었다.
평소 애니메이션을 구현할 때 width, height, left, top 같은 property들을 지양하는 습관을 들이는 게 좋을 것 같다.
그럼 어떤 property가 reflow를 일으키는지 궁금할 수 있는데, 링크에서 참고할 수 있다.
transform은 composite로 구분되어 있는데, 이것도 나중에 알아봐야겠다.
'Developer > CSS' 카테고리의 다른 글
코드관리와 퍼포먼스 관점에서의 CSS-in-JS vs CSS in CSS (1) | 2024.07.03 |
---|---|
웹폰트 간단하게 적용하기 (0) | 2022.09.04 |
super cool 한 css4 :is 선택자 (2) | 2021.12.08 |