본문 바로가기
FrontEnd/2024

css 성능 향상

by cariño 2024. 3. 5.
728x90
반응형

 

 

 

브라우저 렌더링은  뷰포트가 변경되거나 자바스크립트에서 노드를 만지는 일이 있거나 HTML내에서 스타일을 변경하거나 할 때 반복적으로 동작한다. 이러한 순간마다 화면을 새로 화면을 그리고( reflow, repaint), 이 행동이 반복적으로 사용되게 되면 성능을 저하시킨다. 그렇기 때문에 렌더링은 최적화 시키는 방법을 알아두는 것이 중요하다.

 

 

[Reflow (layout)]

 

레이아웃 단계는 렌더트리를 생성하면서 계산된 노드와 스타일을 기기의 뷰포트에 맞게 어떻게 위치 시켜 보일지를 결정하는 단계이다. 

상대적인 측정값도 모두 절대적인 픽셀로 변환이 된다.

리플로우는 레이아웃 요소들의 수치를 계산해서 새로운 위치에 나타나게 하는 동작이 일어날 때마다 반복해서 실행되게 된다. 

또한 DOM 하위, 상위에 있는 후속 요소들에게도 리플로우를 유발 시킨다.

즉 성능저하 이슈가 발생하게 되는데 결론적으론 최대한 composite 속성만 변경할 수 있도록 해야한다.

 

[layout]
position, width, padding, top, font, white-space, clear, display, height, margin, bottom, font-family, line-height, overflow, min-width, border, left, font-size, vertical-align, overflow-y, min-height, border-width, right, font-weight, float

 

 

 

 

- paint : 레이아웃에 영향을 미치지 않는 요소들을 실제 화면에 그려지도록 픽셀로 변환하는 과정을 거치는 과정을 페인트 과정이라고 한다. 색상, 사이즈 등 이 과정에서 렌더 트리에 포함된 이미지, 텍스트 들이 실제로 픽셀로 그려진다. 

 

[Repaint]

reflow보다는 부하가 크지 않지만,  repaint는 reflow가 발생했을 때 다시 실행된다.  또한 상속된 속성이 변경될 경우 repaint가 발생한다.

ex) DOM 요소만 숨겼을 때 visibility: hidden -> visibility: visible (위치 변경없이 repaint),

       요소의 스타일만 변경할 때 background-color, outline 등

 

[paint]
color, background, visibility, text-decoration, background-image, background-position, background-repeat, background-size, outline, outline-color, outline-style, outline-width, border-radius, border-style, box-shadow

[composite]
transform, opacity

 

* 성능개선 *

 

1. reflow, repaint  횟수 줄이기

렌더링을 최소화 하기 위한 코드 작성를 작성하려면  일차적으로는 남용되는 div태그, 불필요한 태그는 줄이는 것과 영향받는 노드의 연결성은 최소화시키는 것이 좋다. css규칙이 적을 수록 렌더트리가 작아지기 때문에 리렌더링이 발생하더라도 비용은 줄일 수 있다. 

1) 같은 규칙스타일을 갖고있는 class 중 변화가 자주 발생하는 class 요소에는 공통의 이름 대신 별도의 이름을 부여해서 사용할 수 있다. 

2) 하위 선택자를 최소화 한다. depth가 깊을 수록 렌더트리를 만드는 시간이 오래 걸리게 된다. 

2) documentFragment를 사용해서 DOM사용을 최소화 시킨다.  documentFragment은 가상 메모리에 존재하는 DOM 노드 객체이다. DOM트리 외부에서 경량화 된 DOM을 만들 수 있기 때문에 브라우저의 리페인팅 영향 없이 메모리 상에서 돔 조작이 가능한 객체이다. 

3) position의 absolute, fixed 사용을 줄인다. 

4) table 레이아웃은 콘텐츠 값에 따라 테이블 너비가 계산되기 때문에 변경되는 작은 값만 있어도 다시 계산되고 노드들이 다시 리플로우 된다. 데이터 표 사용은 table-layout: fixed를 추천!

5) 스타일을 변경할 경우 가장 하위 노드 클래스를 변경한다. 

 

 

2. display와 visibility

display:none은 reflow가 발생하지 않는다. 숨겨진 노드의 콘텐츠를 먼저 변경한 후 화면을 그리면 레이아웃의 발생을 최소한으로 줄일 수 있다.  단, 스크린 리더기에서 해당 요소는 읽을 수 없게 된다는 단점이 있다. 보통 디자인적인 요소에 사용할 때 많이 쓰인다. 또는 clip-path를 사용하는 방법도 있다. 

visiblility: hidden은 속성 자체를 보이지 않게 하기 때문에 렌더 트리를 다시 그리게 된다. repaint가 발생하지 않지만 레이아웃은 발생하게 된다. 즉 완전히 없애는 차이점을 두고 둘 중 하나를 사용하면 될 거 같다. 

 

3. 애니메이션 최적화

애니메이션을 사용할 때 reflow의 비용이 많이 발생하게 된다. 그렇기 때문에 

애니메이션에 있는 노드는 position fixed 또는 absolute로 지정해서 사용하고 변화가 있는 노드에만 reflow가 발생할 수 있도록 제한할 수 있다. 

composite : transform과 opacity는 reflow와 repaint를 발생시키지 않는다.

position의 left,right,top,bottom 대신 transform을 사용하고  display와 visibility대신 opacity를 사용한다. 

 

 

 

참고 

https://ekimnida.tistory.com/45

https://velog.io/@nala723/CSS-애니메이션-vs-JS-애니메이션

 

728x90

댓글