diff --git a/src/App.tsx b/src/App.tsx index 7f3a6b92..1b4f138f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,7 +3,7 @@ import { sessionReplayPlugin } from '@amplitude/plugin-session-replay-browser'; import { MutationCache, QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import { AxiosError } from 'axios'; -import { useEffect, useRef, useState } from 'react'; +import { lazy, Suspense, useEffect, useRef, useState } from 'react'; import { RouterProvider, createBrowserRouter } from 'react-router-dom'; import Layout from '@components/Layout'; @@ -11,16 +11,20 @@ import DeviceTypeProvider from 'contexts/DeviceTypeProvider'; import RecruitingInfoProvider from 'contexts/RecruitingInfoProvider'; import ThemeProvider, { useTheme } from 'contexts/ThemeProvider'; import { dark, light } from 'styles/theme.css'; -import { SessionExpiredDialog } from 'views/dialogs'; -import ErrorPage from 'views/ErrorPage'; -import MainPage from 'views/MainPage'; -import PasswordPage from 'views/PasswordPage'; -import ResultPage from 'views/ResultPage'; -import ReviewPage from 'views/ReviewPage'; -import SignupPage from 'views/SignupPage'; +import BigLoading from 'views/loadings/BigLoding'; import 'styles/reset.css'; +const SessionExpiredDialog = lazy(() => + import('views/dialogs').then(({ SessionExpiredDialog }) => ({ default: SessionExpiredDialog })), +); +const MainPage = lazy(() => import('views/MainPage')); +const PasswordPage = lazy(() => import('views/PasswordPage')); +const ResultPage = lazy(() => import('views/ResultPage')); +const ReviewPage = lazy(() => import('views/ReviewPage')); +const SignupPage = lazy(() => import('views/SignupPage')); +const ErrorPage = lazy(() => import('views/ErrorPage')); + const router = createBrowserRouter([ { path: '/', @@ -113,7 +117,9 @@ const App = () => {
- + }> + +
diff --git a/src/views/ApplyPage/index.tsx b/src/views/ApplyPage/index.tsx index fca7b4e9..45add81a 100644 --- a/src/views/ApplyPage/index.tsx +++ b/src/views/ApplyPage/index.tsx @@ -1,5 +1,5 @@ import { track } from '@amplitude/analytics-browser'; -import { useCallback, useEffect, useRef, useState } from 'react'; +import { lazy, useCallback, useEffect, useRef, useState } from 'react'; import { FormProvider, useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; @@ -9,8 +9,6 @@ import useCheckBrowser from '@hooks/useCheckBrowser'; import useDate from '@hooks/useDate'; import useScrollToHash from '@hooks/useScrollToHash'; import { useDeviceType } from 'contexts/DeviceTypeProvider'; -import { DraftDialog, PreventApplyDialog, SubmitDialog } from 'views/dialogs'; -import NoMore from 'views/ErrorPage/components/NoMore'; import BigLoading from 'views/loadings/BigLoding'; import ApplyCategory from './components/ApplyCategory'; @@ -29,6 +27,13 @@ import { buttonWrapper, container, formContainerVar } from './style.css'; import type { ApplyRequest } from './types'; +const DraftDialog = lazy(() => import('views/dialogs').then(({ DraftDialog }) => ({ default: DraftDialog }))); +const PreventApplyDialog = lazy(() => + import('views/dialogs').then(({ PreventApplyDialog }) => ({ default: PreventApplyDialog })), +); +const SubmitDialog = lazy(() => import('views/dialogs').then(({ SubmitDialog }) => ({ default: SubmitDialog }))); +const NoMore = lazy(() => import('views/ErrorPage/components/NoMore')); + interface ApplyPageProps { onSetComplete?: () => void; } diff --git a/src/views/MyPage/index.tsx b/src/views/MyPage/index.tsx index 9c3831de..3d1a8399 100644 --- a/src/views/MyPage/index.tsx +++ b/src/views/MyPage/index.tsx @@ -1,4 +1,5 @@ import { track } from '@amplitude/analytics-browser'; +import { lazy } from 'react'; import Button from '@components/Button'; import Callout from '@components/Callout'; @@ -6,7 +7,6 @@ import Title from '@components/Title'; import useDate from '@hooks/useDate'; import { useDeviceType } from 'contexts/DeviceTypeProvider'; import { useRecruitingInfo } from 'contexts/RecruitingInfoProvider'; -import NoMore from 'views/ErrorPage/components/NoMore'; import BigLoading from 'views/loadings/BigLoding'; import { @@ -19,6 +19,8 @@ import { buttonWidthVar, } from './style.css'; +const NoMore = lazy(() => import('views/ErrorPage/components/NoMore')); + const MyInfoItem = ({ label, value }: { label: string; value?: string | number | boolean }) => { const { deviceType } = useDeviceType(); const isMasking = label !== '지원서'; diff --git a/src/views/PasswordPage/components/PasswordForm/index.tsx b/src/views/PasswordPage/components/PasswordForm/index.tsx index 95578add..4b45499e 100644 --- a/src/views/PasswordPage/components/PasswordForm/index.tsx +++ b/src/views/PasswordPage/components/PasswordForm/index.tsx @@ -1,5 +1,5 @@ import { track } from '@amplitude/analytics-browser'; -import { useRef } from 'react'; +import { lazy, useRef } from 'react'; import { FormProvider, useForm, type FieldValues } from 'react-hook-form'; import Button from '@components/Button'; @@ -7,11 +7,12 @@ import { TextBox비밀번호, TextBox이름, TextBox이메일 } from '@component import { VALIDATION_CHECK } from '@constants/validationCheck'; import useVerificationStatus from '@hooks/useVerificationStatus'; import { useRecruitingInfo } from 'contexts/RecruitingInfoProvider'; -import { CompleteDialog } from 'views/dialogs'; import useMutateChangePassword from 'views/PasswordPage/hooks/useMutateChangePassword'; import { formWrapper } from './style.css'; +const CompleteDialog = lazy(() => import('views/dialogs').then(({ CompleteDialog }) => ({ default: CompleteDialog }))); + const PasswordForm = () => { const completeDialog = useRef(null); const { diff --git a/src/views/PasswordPage/index.tsx b/src/views/PasswordPage/index.tsx index 7c34ad82..8959e0d8 100644 --- a/src/views/PasswordPage/index.tsx +++ b/src/views/PasswordPage/index.tsx @@ -1,12 +1,15 @@ +import { lazy } from 'react'; + import Title from '@components/Title'; import useDate from '@hooks/useDate'; import { useDeviceType } from 'contexts/DeviceTypeProvider'; -import NoMore from 'views/ErrorPage/components/NoMore'; import BigLoading from 'views/loadings/BigLoding'; import PasswordForm from './components/PasswordForm'; import { containerVar } from './style.css'; +const NoMore = lazy(() => import('views/ErrorPage/components/NoMore')); + const PasswordPage = () => { const { deviceType } = useDeviceType(); const { NoMoreRecruit, isLoading, isMakers } = useDate(); diff --git a/src/views/ResultPage/index.tsx b/src/views/ResultPage/index.tsx index e36211ce..3d5db6db 100644 --- a/src/views/ResultPage/index.tsx +++ b/src/views/ResultPage/index.tsx @@ -1,14 +1,15 @@ -import { useEffect } from 'react'; +import { useEffect, lazy } from 'react'; import useDate from '@hooks/useDate'; import { useTheme } from 'contexts/ThemeProvider'; -import NoMore from 'views/ErrorPage/components/NoMore'; import BigLoading from 'views/loadings/BigLoding'; import useGetMyInfo from 'views/SignedInPage/hooks/useGetMyInfo'; import FinalResult from './components/FinalResult'; import ScreeningResult from './components/ScreeningResult'; +const NoMore = lazy(() => import('views/ErrorPage/components/NoMore')); + const ResultPage = () => { const { handleChangeMode } = useTheme(); const { myInfoData, myInfoIsLoading } = useGetMyInfo(); diff --git a/src/views/ReviewPage/index.tsx b/src/views/ReviewPage/index.tsx index 4a794713..87e4a406 100644 --- a/src/views/ReviewPage/index.tsx +++ b/src/views/ReviewPage/index.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useRef, useState } from 'react'; +import { lazy, useCallback, useEffect, useRef, useState } from 'react'; import { FormProvider, useForm } from 'react-hook-form'; import useDate from '@hooks/useDate'; @@ -15,10 +15,13 @@ import PartSection from 'views/ApplyPage/components/PartSection'; import useGetDraft from 'views/ApplyPage/hooks/useGetDraft'; import useGetQuestions from 'views/ApplyPage/hooks/useGetQuestions'; import { container, formContainerVar } from 'views/ApplyPage/style.css'; -import { PreventReviewDialog } from 'views/dialogs'; -import NoMore from 'views/ErrorPage/components/NoMore'; import BigLoading from 'views/loadings/BigLoding'; +const PreventReviewDialog = lazy(() => + import('views/dialogs').then(({ PreventReviewDialog }) => ({ default: PreventReviewDialog })), +); +const NoMore = lazy(() => import('views/ErrorPage/components/NoMore')); + const ReviewPage = () => { const { deviceType } = useDeviceType(); const preventReviewDialog = useRef(null); diff --git a/src/views/SignInPage/index.tsx b/src/views/SignInPage/index.tsx index 95058526..dae11867 100644 --- a/src/views/SignInPage/index.tsx +++ b/src/views/SignInPage/index.tsx @@ -1,12 +1,15 @@ +import { lazy } from 'react'; + import useDate from '@hooks/useDate'; import { useDeviceType } from 'contexts/DeviceTypeProvider'; -import NoMore from 'views/ErrorPage/components/NoMore'; import BigLoading from 'views/loadings/BigLoding'; import SignInForm from './components/SignInForm'; import SignInInfo from './components/SignInInfo'; import { containerVar } from './style.css'; +const NoMore = lazy(() => import('views/ErrorPage/components/NoMore')); + const SignInPage = () => { const { deviceType } = useDeviceType(); const { isLoading, NoMoreRecruit, isMakers } = useDate(); diff --git a/src/views/SignupPage/components/SignupForm/index.tsx b/src/views/SignupPage/components/SignupForm/index.tsx index 8ee7d6b3..89d9d78e 100644 --- a/src/views/SignupPage/components/SignupForm/index.tsx +++ b/src/views/SignupPage/components/SignupForm/index.tsx @@ -1,5 +1,5 @@ import { track } from '@amplitude/analytics-browser'; -import { useEffect, useRef } from 'react'; +import { lazy, useEffect, useRef } from 'react'; import { type FieldValues, FormProvider, useForm } from 'react-hook-form'; import Button from '@components/Button'; @@ -11,11 +11,14 @@ import { PRIVACY_POLICY } from '@constants/policy'; import { VALIDATION_CHECK } from '@constants/validationCheck'; import useVerificationStatus from '@hooks/useVerificationStatus'; import { useRecruitingInfo } from 'contexts/RecruitingInfoProvider'; -import { ExistingApplicantDialog } from 'views/dialogs'; import useMutateSignUp from 'views/SignupPage/hooks/useMutateSignUp'; import { formWrapper } from './style.css'; +const ExistingApplicantDialog = lazy(() => + import('views/dialogs').then(({ ExistingApplicantDialog }) => ({ default: ExistingApplicantDialog })), +); + const SignupForm = () => { const { recruitingInfo: { season, group }, diff --git a/src/views/SignupPage/index.tsx b/src/views/SignupPage/index.tsx index 18c271de..b7098b2f 100644 --- a/src/views/SignupPage/index.tsx +++ b/src/views/SignupPage/index.tsx @@ -1,12 +1,15 @@ +import { lazy } from 'react'; + import Title from '@components/Title'; import useDate from '@hooks/useDate'; import { useDeviceType } from 'contexts/DeviceTypeProvider'; -import NoMore from 'views/ErrorPage/components/NoMore'; import BigLoading from 'views/loadings/BigLoding'; import SignupForm from './components/SignupForm'; import { containerVar } from './style.css'; +const NoMore = lazy(() => import('views/ErrorPage/components/NoMore')); + const SignupPage = () => { const { deviceType } = useDeviceType(); const { NoMoreRecruit, NoMoreApply, isLoading, isMakers } = useDate(); diff --git a/vite.config.ts b/vite.config.ts index 9b97e8c2..5ceda280 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -12,11 +12,19 @@ export default defineConfig({ vanillaExtractPlugin(), visualizer({ filename: './dist/report.html', - open: true, gzipSize: true, brotliSize: true, }) as PluginOption, ], + build: { + rollupOptions: { + output: { + manualChunks: (id) => { + if (id.includes('firebase')) return 'firebase'; + }, + }, + }, + }, resolve: { alias: [ { find: '@apis', replacement: path.resolve(__dirname, 'src/common/apis') },