본문 바로가기

FrontEnd/React

Code splitting(코드 스플리팅)에 대하여

공부동기: 제로초 영상시청중 소개됨 https://www.inflearn.com/course/lecture?courseSlug=%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-%EC%8B%A4%EC%8B%9C%EA%B0%84%EC%B1%84%ED%8C%85&unitId=71103&tab=community

출처: https://www.nextree.io/code-splitting/

 

요약: Code splitting이란 UX(사용자 경험)를 좋게 하기 위한 것으로 초기 페이지 로딩속도를 계선하기 위한 방법이다. Code splitting의 구체적 방법으로 lazy, suspense가 사용된다.

(페이지 로딩속도 개선에 대해 언급하니 이 영상이 생각남

https://www.youtube.com/watch?v=uZHjGw-dppI&list=PLcqDmjxt30RtqbStQqk-eYMK8N-1SYIFn&index=74 )

 

 

 

import React, { lazy, Suspense } from "react";
import { Route, Routes } from "react-router-dom";
import Main from "./comp/Main";
import { DummyPageSkeleton } from "./comp/Skeleton";

const Dummy1 = lazy(async () => await import("./comp/Dummy/Dummy1"));
const Dummy2 = lazy(async () => await import("./comp/Dummy/Dummy2"));
const Dummy3 = lazy(async () => await import("./comp/Dummy/Dummy3"));

function App() {
  return (
    <Routes>
      <Route path="/" element={<Main />} />
      <Route
        path="/dummy1"
        element={
          <Suspense fallback={<DummyPageSkeleton />}>
            <Dummy1 />
          </Suspense>
        }
      />
      <Route
        path="/dummy2"
        element={
          <Suspense fallback={<DummyPageSkeleton />}>
            <Dummy2 />
          </Suspense>
        }
      />
      <Route
        path="/dummy3"
        element={
          <Suspense fallback={<DummyPageSkeleton />}>
            <Dummy3 />
          </Suspense>
        }
      />
    </Routes>
  );
}

export default App;

 

// 번들링된 index 파일에 정의된 Dummy1
const Dummy1 = react.exports.lazy(
  async () =>
    await __vitePreload(
      () => import("./Dummy1.57256fcb.js"),
      true ? [] : void 0
    )
);
  • 그러나 사용자가 '/dummy1'로 이동하기 전에 프로젝트를 다시 빌드하고 배포하면 기존의 Dummy1.[첫번째hash값].js는 지워지고 새로운 hash 값을 가진 Dummy1.[두번째hash값].js로 빌드되어 배포됩니다.
  • 이 상태에서 사용자가 '/dummy1'로 진입하면 현재 불러와진 index.js를 따라 Dummy1.[첫번째hash값].js 찾아 서버에서 불러오려고 하지만 이미 없어진 뒤여서 오류가 나게 됩니다.

이러한 문제는 페이지를 새로고침하는 등의 새로운 index 파일을 가져오도록 하는 행위를 하

import { lazy } from "react";

const lazyWithRetry = (componentImport) => {
  lazy(async () => {
    const pageHasAlreadyBeenForceRefreshed = JSON.parse(
      window.localStorage.getItem("page-has-been-force-refreshed") || "false"
    );

    try {
      const component = await componentImport();

      window.localStorage.setItem("page-has-been-force-refreshed", "false");

      return component;
    } catch (error) {
      if (!pageHasAlreadyBeenForceRefreshed) {
        window.localStorage.setItem("page-has-been-force-refreshed", "true");
        return window.location.reload();
      }

      throw error;
    }
  });
};

const Dummy1 = lazyWithRetry(async () => await import("./comp/Dummy/Dummy1"));