불필요한 태그는 쓰지 않는다.
wrapper 역할로만 사용되는 <div>
,
div 안에 데이터를 넣기 위한 <span>
들을 많이 봤다.
써야 한다면 쓰는게 옳다.
하지만 하나의 노드가 추가될 때마다 DOM tree도 깊어진다.
최대한 DOM depth가 많아지지 않도록 해야 한다.
동적인 스타일 변화는 부모에 주지 않는다
변화가 발생하면 repaint는 자식 요소, reflow는 부모와 자식 요소 관계없이 일어난다.
그러니까 동적인 변화를 줘야 한다면 그 요소만 타겟해야 한다.
또한 그 요소에도 최대한 자식 요소가 없도록 구조하는 것이 좋다.
inline style 보다는 클래스명이 낫다
클래스명의 변화도 reflow를 일으킨다.
여러 스타일을 인라인으로 추가한다면 스타일 하나 하나가 reflow를 유발한다.
모든 스타일들을 한 개의 클래스로 합쳐야 한다.
display: none
, display: block
도 방법이다.
<div class="wrapper">
...
</div>
렌더링 될 때 비동기 요청이 여러번 발생하거나, 100번의 변화가 발생해야 한다면?
최소 100번의 reflow나 repaint(혹은 둘다)가 일어난다.
- 요청 전에
.wrapper
를display: none
한다..wrapper
를 백그라운드로 빼 놓는다. - none인 요소는 DOM tree에 영향을 주지 않는다. 이 때 지지고 볶고 한다.
- 요청이 완료되면
display: block
으로 바꾼다.
그러면 none(reflow 1, repaint 1)과 block(reflow 1, repaint 1) 총 4번만 일어난다.
하위 요소들은 5번 수정이 되었지만 말이다.
100번의 DOM 탐색 횟수 보다 4번이 낫다.
태그 선택자 보다는 class 기반이 좋다.
.wrapper {
.card {
.card-content {
div {}
span {
img {}
}
}
}
}
클래스명을 직접 작성해야 할 때 보이는 코드다.
좋은 클래스명 아이디어도 없고, 큰 의미도 없는 요소여서 저렇게 작성된다.
클래스명이 없고 태그를 선택자로만 사용한다면 브라우저는 바빠진다.
그 DOM 전체에 div, span이 얼마나 많을까?
reflow가 일어날 때 전체 페이지에서 해당하는 태그명을 검색해야 한다.
변수에 할당한다.
const element = documnet.querySelector('.wrapper');
while (element.offsetWidth < 500) {
뭔가 스타일에 변화주는 코드
}
이 반복문의 횟수가 크다면 성능에 영향을 주는 코드다.
반복이 돌 때마다 요소의 offsetWidth를 확인해야 한다.
offestWidth
처럼 계산되야 하는 스타일이 있다면 반복문 외부에서 변수에 할당해 주는 것이 좋다.
성능 확인
개발자 도구를 통해 reflow, repaint가 발생하는 요소를 알 수 있다.
몇 번의 렌더링이 되는 지도 알 수 있다.
chrome으로 기준했을 때 performance 탭의 event log에서 볼 수 있다.
또한 DOM tree의 selector나 css의 갯수는 css overview에서 확인할 수 있다.
성능 측정에 대해 아직은 모르는 부분이 많다.
이 부분은 실제로 테스트 해보고 다시 포스팅하려 한다.
'Web' 카테고리의 다른 글
Repaint와 Reflow (0) | 2023.05.23 |
---|---|
Polling이란 (Polling과 API 호출은 같지 않다) (0) | 2023.04.24 |
맥북 M1 scss 에러 해결방법 (0) | 2021.07.31 |
맥북 M1에 homebrew로 node랑 vscode, 카카오톡 설치하기 (0) | 2021.07.31 |
맥북 M1에 homebrew 개발환경 설정하기 (0) | 2021.07.31 |