Reflow와 Repaint

아코언니·2023년 10월 20일
0

CS

목록 보기
3/3
post-thumbnail

브라우저의 렌더링 과정을 공부하다보면 reflow와 repaint라는 단어들이 나오는데 오늘은 이 두 개념에 대해 알아보겠습니다!

우선 이 개념들을 알아보기 전에 브라우저의 렌더링 과정을 읽고 오시는걸 추천드려요!

리플로우와 리페인트는 DOM 요소가 시각적으로 변경됐을 때, 이 변화를 다시 계산하고 화면에 그려주는 작업을 말합니다.

Reflow

DOM 요소의 기하학적 속성이 변경될때, 브라우저 사이즈가 변할때, 스타일시트가 로딩되었을 때 등 발생하는 변화들을 다시 해주는 작업을 뜻하고 레이아웃(Layout)이라고도 합니다.

즉, 요소의 변화에 따라 Layout 과정을 다시 수행하는 것을 Reflow라고 합니다.

DOM 요소의 속성 등이 변화되면 그 주변의 모든 요소도 영향을 받게되는데
결국 DOM 요소 중 하나라도 시각적 변화가 발생되면 DOM 트리 전체에 대해 다시 계산을 해야합니다.

Reflow는 렌더 트리를 재생성하므로 무거운 작업에 속합니다.

Reflow가 발생하는 사례

  • 페이지 초기 렌더링 (최초 Layout 과정)
  • 윈도우 리사이징 (Viewport 크기 변경)
  • DOM 노드 추가, 제거
  • DOM 노드 위치, 크기 변경
  • 폰트 변경, 텍스트 내용 변경
  • 이미지 크기 변경
  • 애니메이션, 트랜지션

Repaint

Reflow가 발생한 후 새로 계산된 Render Tree를 다시 화면에 그려주는 과정이 필요합니다.
그래서 변경된 요소를 실제로 화면에 그려주는 작업인 Paint단계를 다시 수행하는 것을 Repaint라고 합니다.

Reflow가 발생하면 필연적으로 Repaint가 실행됩니다.

그렇다고 무조건 Reflow가 발생해야만 Repaint가 발생하는건 아닙니다.
background-color, visibility와 같이 레이아웃에 영향을 주지 않는 경우는 Repaint만 발생합니다.

리페인트도 굉장히 무거운 작업이긴 하지만 리플로우 처럼 모든 요소들에 대한 기하학적 정보들을 계산해주는 작업은 아니기 때문에 리플로우 보다는 상대적으로 훨씬 가벼운 작업입니다.

Reflow를 줄이기 위한 방법

  • 불필요한 노드는 display: none 사용하기

    • visibility 속성은 Layout 공간을 차지하기 때문에 Reflow의 대상이 된다.
    • display: none은 Layout 공간을 차지하지 않아 Render Tree에서 아예 제외된다.
    • 그러므로 불필요한 노드는 display: none을 활용하여 렌더링 성능을 향상할 수 있다.
  • Reflow 속성 사용 줄이기

    • 가능하면 Reflow보다는 Repaint만 발생하는 속성을 사용하는 것이 좋다.
    • Reflow, Repaint가 모두 발생하지 않는 transform, opacitiy와 같은 속성도 존재한다.
    • 자세한 속성 정보
  • DOM 속성 변경 코드 그룹핑 하기
    div별로 속성을 가져와 변경할 경우 Reflow가 호출 횟수만큼 발생한 것을 볼 수 있다.

    하지만 요소의 변경 할 부분을 바로 변경하지 않고 큐에 저장해뒀다가 후에 몰아서 변경하면 한 번에 처리하기 때문에 Reflow가 한번만 발생한 것이다.

  • 리플로우 유발 메서드는 별도 저장해 사용하기
    위의 예시처럼 리플로우를 유발시키는 메서드, 프로퍼티는 매번 호출하지 말고 변수에 저장한 후 사용합시다.
// 나쁜 예
for(let i=1; i<10; i++){
    div.style.left = (div1.getBoundingClientRect().left + i) + 'px';
}

// 좋은 예
let {left} = div1.getBoundingClientRect();  // reflow 유발 메서드는 변수에 저장해 사용 
for(let i=1; i<10; i++){
    div.style.left = (left + i) + 'px';
    left += i;
}
  • CSS 수정은 일괄로 변경 해주기
    스크립트로 CSS 속성을 여러번 수정하는 것은 그만큼 리플로우를 여러번 유발시키게 됩니다.
    그러니 CSS 수정이 많이 필요한 경우에는 클래스명을 수정하거나 cssText 속성을 이용해 일괄로 변경해줍시다.
<style>
    .my-div {
        width: 100px;
        height: 100px;
        padding: 5px;
        border: 5px solid blue;
        background-color: black;
        color: white;
    }
</style>
<body>
    <div id="div"></div>

    <script>
        // 나쁜 예
        div.style.width = "100px";   		  // reflow, repaint
        div.style.height = "100px";   		  // reflow, repaint
        div.style.padding = "5px";   		  // reflow, repaint
        div.style.border = "5px solid blue";      // reflow, repaint
        div.style.backgroundColor = "black";      // repaint
        div.style.color = "white";		  // repaint

        // 좋은 예1
        div.className = "my-div";

        // 좋은 예2
        div.style.cssText = "width: 100px; height: 100px; ...";
    </script>
</body>

참고 자료

https://kwangsunny.tistory.com/42

https://seokzin.tistory.com/entry/JavaScript-%EB%A0%8C%EB%8D%94%EB%A7%81-%EC%B5%9C%EC%A0%81%ED%99%94-Reflow%EC%99%80-Repaint#-%EF%B-%-F%E-%--%A-%--%EB%B-%--%ED%--%--%EC%-A%--%ED%--%-C%--%EB%--%B-%EB%--%-C%EB%-A%--%--display%-A%--none

https://falsy.me/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EC%9D%B4%ED%95%B4-1-reflow-repaint%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC-%EC%95%8C%EC%95%84%EB%B4%85%EB%8B%88%EB%8B%A4/

profile
항상 공부하는 개발자 되기

0개의 댓글

관련 채용 정보