[Next] React.lazy, Dynamic import 와 startTrasition

gak·2023년 4월 4일
0

Dynamic import 와 React.lazy

code spliting 은 앱을 지연로딩하게 도와주고, 앱의 성능을 향상시켜준다.

React 에서는 dynamic import 를 아래와 같이 사용할 수 있다.

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

반면에 nextjs 에서는 dynamic 이라는 함수를 지원해주므로 dynamic 을 사용하면 된다.

import dynamic from "next/dynamic";
import { Suspense } from "react";
export default function Home() {
  const Navigation = dynamic(() => import("./components/Nav.js"), {
    suspense: true,
  });
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <Navigation />
      </Suspense>
    </div>
  );
}

Dynamic import 는 여러 이점이 있는데,

첫번째로 번들의 크기를 줄임으로써, 페이지의 로딩 속도가 빨라진다는 장점이 있다.

두번째로는 Low bounce rates 이다. 이는 페이지로딩속도가 빨라진다는 것과 일맥상통하며, 페이지 로딩 속도가 빨라짐에 따라서 유저가 로딩화면을 보고있는 시간이 줄어들어 이탈률이 낮아진다.

csr 에서의 Dynamic import

import dynamic from 'next/dynamic'

const HeroItem = dynamic(() => import('../components/HeroItem'), {
  ssr: false,
})

const App = () => {
  return (
    <>
      <HeroItem />
  )
    </>
}

dynamic 의 ssr 속성을 false 로 만들어주면 된다.
또한, dynamic 은 React Components 를 타겟으로 사용된다.

Nextjs dynamic 함수의 명세

export declare type DynamicOptions<P = {}> = LoadableGeneratedOptions & {
    loading?: (loadingProps: DynamicOptionsLoadingProps) => JSX.Element | null;
    loader?: Loader<P> | LoaderMap;
    loadableGenerated?: LoadableGeneratedOptions;
    ssr?: boolean;
    /**
     * @deprecated `suspense` prop is not required anymore
     */
    suspense?: boolean;
};

dynamic 된 컴포넌트를 렌더링할때, fallback 을 피하기 위한 방법

startTranstion이라는 리액트 v18 에서 만들어진 함수를 사용하면 된다.
startTransition 은 UI 를 바꾸지 않고 상태를 업데이트 시켜주는 함수이다.

예를들어 아래 코드의 경우에,
사용자가 tab 을 변경했을때, dynamic import 된 컴포넌트를 기다려야 하므로 잠시동안 suspense 의 fallback view 가 보여진다.

import React, { Suspense } from 'react';
import Tabs from './Tabs';
import Glimmer from './Glimmer';

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

function MyComponent() {
  const [tab, setTab] = React.useState('photos');
  
  function handleTabSelect(tab) {
    setTab(tab);
  };

  return (
    <div>
      <Tabs onTabSelect={handleTabSelect} />
      <Suspense fallback={<Glimmer />}>
        {tab === 'photos' ? <Photos /> : <Comments />}
      </Suspense>
    </div>
  );
}

하지만, fallback view 를 보여주지 않고 dynamic import 된 컴포넌트를 렌더링하려면 startTransition 을 사용하면된다.
이 함수는 UI 의 변경없이 State 를 바꿔주며 dynamic import 가 완료될때까지 기다린다음 UI 를 업데이트 시켜준다.

function handleTabSelect(tab) {
  startTransition(() => {
    setTab(tab);
  });
}

참고문서
https://ko.reactjs.org/docs/code-splitting.html

profile
Hello. I'm Front-End Developer Trying to Create Valuable Things.

0개의 댓글