와플카드 서비스가 궁금하다면!
와플카드 서비스 둘러보기 : https://waffle-card.com/
와플카드 깃허브 둘러보기 : https://github.com/waffle-card
와플카드의 서비스에서 페이지는 크게 3가지로 분류된다.
이렇게 로그인 여부에 따라 페이지 라우팅을 처리하기 위해서 PrivateRoute
, PublicRoute
라우팅 컴포넌를 구현하였다.
PrivateRoute
로그인을 해야만 접근할 수 있는 페이지 라우팅한다.
인자로 라우팅 될 페이지 컴포넌트를 전달한다.
유저 전역상태에 의존하여 로그인시 인자로 전달받은 페이지로 라우팅한다.
로그인이 되어있지 않다면 로그인 페이지로 라우팅한다.
const PrivateRoute = ({
component: Component,
}: PrivateRouteProps): JSX.Element => {
const userInfo = useRecoilValue(userState);
return userInfo ? <Component /> : <Navigate replace to="/login" />;
};
PublicRoute
const PublicRoute = ({
component: Component,
restricted,
}: PublicRouteProps): JSX.Element => {
const userInfo = useRecoilValue(userState);
return userInfo && restricted ? <Navigate replace to="/" /> : <Component />;
};
// in Router.tsx
const Router = () => {
return (
<Suspense fallback={<Spinner />}>
<Routes>
<Route path="/" element={<PublicRoute component={HomePage} />} />
<Route
path="/login"
element={<PublicRoute restricted component={LoginPage} />}
/>
<Route
path="/signup"
element={<PublicRoute restricted component={SignUpPage} />}
/>
<Route path="/my-page" element={<PrivateRoute component={MyPage} />} />
<Route path="/guide" element={<PublicRoute component={GuidePage} />} />
<Route path="*" element={<PublicRoute component={NotFoundPage} />} />
</Routes>
</Suspense>
);
};
위에서 구현한 라우트 컴포넌트들을 위와 같이 Router 컴포넌트로 분리하여 라우팅을 처리해주었다.
React.lazy를 활용하여 페이지 컴포넌트 코드를 스플리팅하여 필요한 시점에만 로딩하도록 하였다. 비록 현재 와플카드의 번들 크기는 현업에 비하면 매우 작아서 눈에 띄는 성능 효과는 보이지 않을 수 있을 것 같다.
하지만 굳이 접근하지 않는 페이지를 초기에 로딩을 하는것은 비효율적이라 생각이 들었고 미비하지만 분명히 초기 로딩 속도는 개선될 것이라고 생각을 했다.
위의 Router 코드를 아래와 같이 Suspense와 lazy를 활용하여 지연 로딩을 적용하였다.
const HomePage = lazy(() => import('@/pages/HomePage/index'));
const LoginPage = lazy(() => import('@/pages/LoginPage/index'));
const SignUpPage = lazy(() => import('@/pages/SignUpPage/index'));
const MyPage = lazy(() => import('@/pages/MyPage/index'));
const GuidePage = lazy(() => import('@/pages/GuidePage/index'));
const NotFoundPage = lazy(() => import('@/pages/NotFoundPage/index'));
const Router = () => {
return (
<Suspense fallback={<Spinner />}>
<Routes>
<Route path="/" element={<PublicRoute component={HomePage} />} />
<Route
path="/login"
element={<PublicRoute restricted component={LoginPage} />}
/>
<Route
path="/signup"
element={<PublicRoute restricted component={SignUpPage} />}
/>
<Route path="/my-page" element={<PrivateRoute component={MyPage} />} />
<Route path="/guide" element={<PublicRoute component={GuidePage} />} />
<Route path="*" element={<PublicRoute component={NotFoundPage} />} />
</Routes>
</Suspense>
);
};