React Suspense Lazy Loading 없이 Fallback 사용하기

제목: 후출 번들 없이 React Suspense Lazy Loading 문제 해결하기 소개 React Suspense는 컴포넌트의 게으른 로딩을 가능하게 해주는 강력한 도구입니다. 이를 통해 응용 프로그램의 초기 번들 크기를 개선하고, 코드 분할을 통해 컴포넌트를 필요에 따라 동적으로 …

title_thumbnail(React Suspense Lazy Loading 없이 Fallback 사용하기)

제목: 후출 번들 없이 React Suspense Lazy Loading 문제 해결하기

소개

React Suspense는 컴포넌트의 게으른 로딩을 가능하게 해주는 강력한 도구입니다. 이를 통해 응용 프로그램의 초기 번들 크기를 개선하고, 코드 분할을 통해 컴포넌트를 필요에 따라 동적으로 로드할 수 있습니다. 그러나 React Suspense의 한 가지 제한은 로딩을 위한 대체 컴포넌트의 사용을 요구한다는 것입니다.

이 블로그 게시물에서는 React Suspense에서 대체 없이 컴포넌트를 게으르게 로드하는 다양한 해결책을 탐구합니다. 이 문제를 해결하기 위한 가능한 해킹 방법, 진행 중인 토론 및 React에서 예상되는 개선 사항에 대해 논의할 것입니다. 시작해봅시다!

해결책 1: Null 대체 사용하기

하나의 가능한 해결책은 Suspense 컴포넌트에 null 대체를 전달하는 것입니다. 이것은 상술과는 반대로 보일 수 있지만, 실제로는 화면에 어떤 로딩 애니메이션이나 대체 UI도 표시되지 않아 깜박임이 없어집니다. 다음은 예시입니다:

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

<Suspense fallback={null}>
    <MyLazyComponent />
</Suspense>

이 방식은 대체 UI를 건너뛰면서 컴포넌트의 게으른 로딩을 성취할 수 있도록 해줍니다.

해결책 2: 동시 모드를 지원하는 미래 업데이트

이 문제의 또 다른 잠재적인 해결책은 React의 다가오는 동시 모드에서 찾을 수 있습니다. 현재 React-Router나 React를 사용하면 깔끔한 해결책이 없지만, 동시 모드는 이 문제를 해결하기 위해 만들어졌습니다. React의 주요 기여자 중 한 명인 Dan Abramov에 따르면, 동시 모드는 컨텐츠가 이미 HTML에 있는 경우 대체를 표시하지 않는 기능을 도입할 예정입니다. 이를 통해 컨텐츠의 불필요한 깜박임을 막고 게으른 로딩을 더욱 원활하게 만들 수 있습니다. 이러한 해결책은 아직 사용할 수는 없지만, 미래의 업데이트에서 기대할 수 있는 내용입니다.

이 문제가 중요하지 않거나 프로젝트에 대한 기다릴 여유가 있다면, 현재까지의 라우트 게으른 로딩을 생략하고 동시 모드의 출시를 기다릴 수도 있습니다.

해결책 3: 커스텀 게으른 로딩 HOC 사용하기

React 17에서 null을 fallback 속성에 전달하는 것은 어떤 깜박임도 일어나지 않습니다. 나는 사용에 유용한 해결책은 커스텀 High Order Component (HOC)를 사용하는 것입니다. 다음은 TypeScript에서의 예시입니다:

type LazyLoadHOC = {
   component: React.LazyExoticComponent<any>,
   fallback?: React.ComponentType | null,
   [x:string]: any
};

export const LazyLoad: React.FC<LazyLoadHOC> = ({
     component: Component, fallback = null, ...props
}) => {
  return (
    <React.Suspense fallback={fallback}>
        <Component {...props} />
    </React.Suspense>
  );
};

이 커스텀 LazyLoad HOC는 대체 컴포넌트가 필요하지 않고, 깜박임이나 불필요한 로딩 애니메이션 없이 컴포넌트를 게으르게 로드할 수 있게 해줍니다. 그럼 다음과 같이 애플리케이션에서 사용할 수 있습니다:

const AddressFormModel = React.lazy(() => import('@components/address/address-form-modal'));

<Modal show={isOpen} backdrop={'static'} dialogClassName='custom-modal'>
    <ModalBody>
       {view === 'ADDRESS-FORM' && <LazyLoad component={AddressFormModel} />}
    </ModalBody>
</Modal>

이 방법을 사용하면 필요하지 않을 때 전역 Suspense 컴포넌트가 작동되지 않으므로 게으른 로딩 경험이 더욱 부드럽게 됩니다.

해결책 4: Loadable 컴포넌트 래퍼 사용하기

기본 React Suspense 동작으로 인해 발생하는 깜박임을 피하기 위해 다른 접근 방식은 컴포넌트 내에서 로더를 래핑하고 Loadable 컴포넌트 래퍼를 사용하여 게으른 컴포넌트를 로드하는 것입니다. 이 설정을 통해 로딩 애니메이션이나 대체 UI가 표시되지 않고 컨텐츠가 로딩 과정 동안 계속해서 보여집니다. 다음은 예시입니다:

loadable.js:

import React, { Suspense } from 'react';

const Loadable = (Component) => (props) => (
  <Suspense fallback={<></>}>
    <Component {...props} />
  </Suspense>
);

export default Loadable;

route.js:

import React, { lazy } from 'react';
import Loadable from './components/Loadable';

const Home = Loadable(lazy(() => import('./pages/home')));

const routes = [
    {
        path: "dashboard",
        element: <Layout />,
        children: [
            {
                path: "",
                element: <Home />,
            },
        ]
    },
]

Loadable 컴포넌트 래퍼를 활용함으로써 애니메이션 없이 컴포넌트를 게으르게 로드할 수 있습니다. 이 해결책은 특히 로드되는 React 컴포넌트에 해당하는 컨텐츠가 표시될 때 더 나은 사용자 경험을 제공합니다.

결론

React를 사용하여 컴포넌트를 게으르게 로딩하는 것은 응용 프로그램의 성능을 최적화하는 강력한 기술입니다. 현재 구현 방식은 대체 컴포넌트를 요구하지만, 대체 UI를 건너뛰고 깜박임을 제거하고 더 부드러운 사용자 경험을 제공하는 여러 해결책이 있습니다. null 대체를 전달하는 것, 동시 모드의 미래 출시를 기다리는 것, 커스텀 HOC를 사용하는 것 또는 Loadable 컴포넌트 래퍼를 활용하는 것과 같은 문제를 해결하는 여러 옵션 중에 프로젝트 요구 사항에 가장 적합한 접근 방식을 선택하는 것을 기억하세요. 더욱 우아한 해결책을 제공할 수 있는 React의 향후 업데이트에 주의를 기울이세요. 즐거운 게으른 로딩되세요!

참고 자료 : 

reactjs

Leave a Comment