[React Study] 렌더링 최적화

Mayton·2022년 7월 10일
0

React

목록 보기
7/10
post-thumbnail
post-custom-banner

React의 렌더링

  1. 자신의 state가 변경된다.
  2. 부모에게서 받는 props가 변경 되었다.

참고

함수가 렌더링 된다는 것은 누구가 그 함수를 호출하여 실행되는 것
함수가 실행될 때마다 내부에 선언되어 있던 표현식들도 매번 다시 계산된다.

useMemo

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

첫번째 인자로는 함수, 두번째 인자로는 dependency를 전달한다.

useMemo는 의존성이 변경되었을 때에만 메모이제이션된 값을 반환한다.

useCallback

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

useCallback은 메모이제이션 된 콜백을 반환한다.

함수가 다시 선언되고 실행되는 것을 방지한다.

함수형 컴포넌트 안에서, 함수가 실행 될 때마다 내부에 선언되어 있는 표현식들이 매번 다시 계산되기 때문에, 함수에서 밖으로 뺄 수 있는 것들은 미리미리 밖으로 빼 놓아야 한다.

React.memo

컴포넌트 자체를 메모하는 방법

const MyComponent = React.memo(function MyComponent(props) {
  /* props를 사용하여 렌더링 */
});

React.memo는 컴포넌트 자체를 memo 하는 것으로, props의 변화에 의해서만 동작한다.
동일한 props로 동일한 결과를 낸다면, 메모이제이션 된 마지막 렌더링 결과를 사용한다.
따라서, React.memo는 props 변화에만 영향을 준다. React.memo로 감싸진 함수 컴포넌트 구현에 useState, useReducer 또는 useContext 훅을 사용한다면, 여전히 state나 context가 변할 때 다시 렌더링된다.

CodeSplitting

대부분 React 앱들은 Webpack, Rollup 또는 Browserify 같은 툴을 사용하여 여러 파일을 하나로 병합한 “번들 된” 파일을 웹 페이지에 포함하여 한 번에 전체 앱을 로드 할 수 있습니다.
따라서 번들된 파일들이 크게되면, 최초에 로딩하는데 시간이 굉장히 많이 걸린다.

해결방법으로 코드분할을 해서 "지연 로딩"을 하도록 도와주는 것이다.

Before

import { add } from './math';

console.log(add(16, 26));

After

import("./math").then(math => {
  console.log(math.add(16, 26));
});

React.lazy()

React.lazy 함수를 사용하면 동적 import를 사용해서 컴포넌트를 렌더링 할 수 있습니다.

Before

import OtherComponent from './OtherComponent';

After

const OtherComponent = React.lazy(() => import('./OtherComponent'));
import React, { Suspense } from 'react';

const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <OtherComponent />
      </Suspense>
    </div>
  );
}

위와 같이 suspense로 감싸주며,렌더링 되는 동안 fallback 안의 컴포넌트가 보여지게 된다.

코드분할은 대부분 라우트 장소에 실시하여, 페이지 전환에 렌더링하게 되어, 다른 요소와 상호작용 하지 않도록 한다.

import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';

const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Suspense>
  </Router>
);
profile
개발 취준생
post-custom-banner

0개의 댓글