JavaScript

브라우저의 Re-Layout, Re-Paint 중 뭐가 더 안좋을까?

milliwonkim 2023. 3. 9. 19:28
반응형
SMALL

브라우저 성능 관점에서 볼 때, re-layout은 re-paint보다 더 비싸다고 일반적으로 여겨집니다.

re-layout은 페이지의 모든 요소의 위치와 크기를 다시 계산하는 작업으로, 계산에 상당한 비용이 들어갑니다.

이는 레이아웃이 하나의 요소에 대한 변경뿐 아니라 해당 요소의 부모 및 형제 요소에 대한 변경에도 영향을 받기 때문입니다.

결과적으로, re-layout은 전체 페이지가 다시 렌더링될 수 있으며,

이는 페이지 로드 시간이 더 느려지고 전체적인 성능이 감소할 수 있습니다.

 

반면, re-paint은 요소의 위치나 크기를 변경하지 않고 페이지의 시각적 모양만 업데이트하는 작업입니다.

이는 re-layout보다 적은 비용이 드는 작업이며, 페이지의 시각적 디스플레이만 변경하기 때문에 복잡한 계산이 필요하지 않습니다.

일반적으로, 브라우저 성능을 개선하기 위해서는 re-layout 및 re-paint 작업을 최소화하는 것이 좋습니다. 이는 불필요한 스타일을 피하고, DOM 요소의 수를 줄이고, 자바스크립트 기반 애니메이션 대신 CSS 애니메이션 및 전환을 사용하는 CSS 최적화 기술을 사용하여 달성할 수 있습니다. 또한, 브라우저 개발자 도구 및 성능 프로파일링 도구와 같은 도구를 사용하여 웹 애플리케이션의 성능 병목 현상을 식별하고 최적화하는 것이 도움이 됩니다.

 

이거를 리액트 코드로 설명해보겠습니다

import React, { useState, useRef, useLayoutEffect, useEffect } from "react";

function App() {
  const [count, setCount] = useState<number>(0);
  const [layoutTime, setLayoutTime] = useState<number | null>(null);
  const [paintTime, setPaintTime] = useState<number | null>(null);
  const [hasRendered, setHasRendered] = useState<boolean>(false);
  const buttonRef = useRef<HTMLButtonElement>(null);

  const handleClick = () => {
    if (buttonRef.current) {
      buttonRef.current.style.color = "red";
    }
    setCount(count + 1);
  };

  useLayoutEffect(() => {
    console.log("Re-layout");
    const startTime = performance.now();
    setLayoutTime(startTime);
    requestAnimationFrame(() => {
      setLayoutTime(performance.now() - startTime);
    });
  }, [count]);

  useEffect(() => {
    if (hasRendered) {
      console.log("Re-paint");
      const startTime = performance.now();
      setPaintTime(startTime);
      requestAnimationFrame(() => {
        setPaintTime(performance.now() - startTime);
      });
    } else {
      setHasRendered(true);
    }
  }, [count]);

  return (
    <div>
      <button onClick={handleClick} ref={buttonRef}>
        Increment Count
      </button>
      <p>{count}</p>
      {count % 2 === 0 && (
        <div
          style={{ width: "100px", height: "100px", backgroundColor: "blue" }}
        >
          <p>Re-layout Component</p>
        </div>
      )}
      {count % 2 !== 0 && (
        <div
          style={{ width: "100px", height: "100px", backgroundColor: "green" }}
        >
          <p>Re-paint Component</p>
        </div>
      )}
      {paintTime && <p>Re-paint Time: {paintTime.toFixed(2)}ms</p>}
      {layoutTime && <p>Re-layout Time: {layoutTime.toFixed(2)}ms</p>}
    </div>
  );
}

export default App;

re-layout은 re-paint보다 더 비싼게 보이네요!


 

import React, { useState, useEffect } from 'react';

const App = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log('Re-layout');
  }, [count]);

  useEffect(() => {
    console.log('Re-paint');
  });

  const incrementCount = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <button onClick={incrementCount}>Increment Count</button>
      <p>{count}</p>
    </div>
  );
};

export default App;

useEffect 훅을 사용하여 count 상태가 변경될 때마다 "Re-layout" 메시지를 출력하도록 하였습니다.

또한, useEffect 훅에 의해 감지되지 않은 상태 변경 시 "Re-paint" 메시지를 출력하도록 하였습니다.

 

이 코드를 실행하면 버튼을 클릭할 때마다 "Re-layout" 메시지가 콘솔에 출력됩니다.

이는 상태 변경으로 인해 레이아웃이 다시 계산되기 때문입니다. 반면, "Re-paint" 메시지는 매번 출력되며,

이는 상태 변경으로 인해 요소의 시각적 모양만 변경되기 때문입니다.

 

이 코드를 통해 상태 변경이 어떻게 레이아웃 및 페인팅 과정에 영향을 미치는지 확인할 수 있습니다.

 

반응형
LIST