Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SP-694 메인페이지, 모집공고 모아보기 페이지 성능 개선 - Code Splitting, Loading Spinner 구현 #371

Merged
merged 4 commits into from
Aug 30, 2024

Conversation

SungHyun627
Copy link
Collaborator

💡 다음 이슈를 해결했어요.

  • Loading 과정에서 보여줄 LoadingSpinner 컴포넌트 구현
  • 라우터 레벨에서 코드 스플리팅 적용

💡 이슈를 처리하면서 추가된 코드가 있어요.

🛠 Loading 과정에서 보여줄 LoadingSpinner 컴포넌트 구현

Suspense의 Fallback으로 적용되는 LoadingSpinner 컴포넌트와 스토리를 구현하였습니다.

import { LoadingImage } from '@/Assets';
import styled from 'styled-components';
export const LoadingSpinner = () => {
return (
<LoadingSpinnerBox>
<SpinnerImg src={LoadingImage} alt="loading spinner" />
</LoadingSpinnerBox>
);
};
const LoadingSpinnerBox = styled.div`
position: absolute;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
`;
const SpinnerImg = styled.img`
opacity: 0.7;
animation: rotateImage 1.2s linear infinite;
transform-origin: 50% 50%;
@keyframes rotateImage {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(20deg);
}
50% {
transform: rotate(0deg);
}
75% {
transform: rotate(-20deg);
}
100% {
transform: rotate(0deg);
}
}
`;

✔︎ Loading Spinner

🛠 라우터 레벨에서 코드 스플리팅 적용

라우터 레벨에서 코드 스플리팅을 적용하였습니다.

✔︎ �Dynamic Import

const MainPage = lazy(() => import('@/Pages/Main'));
const RecruitmentsPage = lazy(() => import('@/Pages/Recruitments'));
const LoginPage = lazy(() => import('@/Pages/Login'));
const SignUpPage = lazy(() => import('@/Pages/SignUp'));
const RecruitmentDetailPage = lazy(() => import('@/Pages/RecruitmentDetail'));
const StudyDetailPage = lazy(() => import('@/Pages/StudyDetail'));
const ApplicantsPage = lazy(() => import('@/Pages/Applicants'));
const CreateStudyPage = lazy(() => import('@/Pages/Studies/CreateStudy'));
const ModifyStudyPage = lazy(() => import('@/Pages/Studies/EditStudy'));
const CreateRecruitmentPage = lazy(() => import('@/Pages/CreateRecruitment'));
const LoginFailPage = lazy(() => import('@/Pages/LoginFail'));
const SignUpFailPage = lazy(() => import('@/Pages/SignUpFail'));
const MyPageHome = lazy(() => import('@/Pages/MyPageHome/index'));
const NotificationsSettings = lazy(() => import('@/Pages/NotificationsSettings'));
const ReviewPage = lazy(() => import('@/Pages/Review'));
const Notifications = lazy(() => import('@/Pages/Notifications'));
const MyPageReviews = lazy(() => import('@/Pages/MyPageReviews'));
const EditRecruitmentPage = lazy(() => import('@/Pages/EditRecruitment'));
const SavedPage = lazy(() => import('@/Pages/Saved'));

✔︎ 라우트별 Suspense 적용

export const RouterPath = createBrowserRouter([
{
element: (
<>
<Header />
<Suspense fallback={<LoadingSpinner />}>
<Outlet />
<Footer />
</Suspense>
</>
),
errorElement: <ErrorBoundary />,
children: [
{
path: ROUTES.MAIN,
element: <MainPage />,
},
{
path: ROUTES.AUTH.LOGIN,
element: <LoginPage />,
},
{
path: ROUTES.AUTH.LOGINFAIL,
element: <LoginFailPage />,
},
{
// 마이페이지
path: ROUTES.MYPAGE.HOME,
// 마이페이지 공통 사이드바
element: (
<MyPageLayout>
<Outlet />
</MyPageLayout>
),
children: [
{
// 회원 정보
index: true,
element: <MyPageHome />,
},
{
// 스터디원이 남긴 나의 리뷰
path: ROUTES.MYPAGE.REVIEWS,
element: (
<ProfileLayout>
<MyPageReviews />
</ProfileLayout>
),
},
{
// 임시 저장된 글
path: ROUTES.MYPAGE.SAVED,
element: <SavedPage />,
},
{
path: ROUTES.MYPAGE.SETTINGS,
// 설정 페이지 공통 레이아웃
element: (
<SettingLayout>
<Outlet />
</SettingLayout>
),
children: [
{
// 알림 권한 설정
path: ROUTES.MYPAGE.NOTIFICATIONS_SETTINGS,
element: <NotificationsSettings />,
},
],
},
{
// 루도가 알려요
path: ROUTES.MYPAGE.NOTIFICATIONS,
element: <Notifications />,
},
],
},
{
path: ROUTES.STUDY.DETAIL,
element: <StudyDetailPage />,
},
{
path: ROUTES.RECRUITMENT.RECRUITMENTS,
element: <RecruitmentsPage />,
},
{
path: ROUTES.RECRUITMENT.DETAIL,
element: <RecruitmentDetailPage />,
},
{
path: ROUTES.AUTH.SIGNUP,
element: <SignUpPage />,
},
{
path: ROUTES.AUTH.SIGNUPFAIL,
element: <SignUpFailPage />,
},
],
},
{
// 스터디원 평가 페이지
path: ROUTES.STUDY.REVIEW,
element: (
<Suspense>
<ReviewPage />
</Suspense>
),
},
{
// 스터디 생성 페이지
path: ROUTES.STUDY.CREATE,
element: (
<Suspense>
<CreateStudyPage />
</Suspense>
),
},
{
// 스터디 수정 페이지
path: ROUTES.STUDY.MODIFY,
element: (
<Suspense>
<ModifyStudyPage />
</Suspense>
),
},
{
// 스터디 지원자 페이지
path: ROUTES.STUDY.APPLICANTS,
element: (
<Suspense>
<ApplicantsPage />
</Suspense>
),
},
{
// 모집공고 생성 페이지
path: ROUTES.RECRUITMENT.CREATE,
element: (
<Suspense>
<CreateRecruitmentPage />
</Suspense>
),
},
// 모집공고 수정 페이지
{
path: ROUTES.RECRUITMENT.EDIT,
element: (
<Suspense>
<EditRecruitmentPage />
</Suspense>
),
},
]);

✅ 셀프 체크리스트

  • 브랜치 전략에 맞는 브랜치에 PR을 올리고 있습니다. (master/main이 아닙니다.)
  • 커밋 메세지를 컨벤션에 맞추었습니다.
  • 변경 후 코드는 컴파일러/브라우저 warning/error 가 발생시키지 않습니다.
  • 변경 후 코드는 기존의 테스트를 통과합니다.
  • 테스트 추가가 필요한지 검토해보았고, 필요한 경우 테스트를 추가했습니다.
  • docs 수정이 필요한지 검토해보았고, 필요한 경우 docs를 수정했습니다.

@SungHyun627 SungHyun627 changed the title SP-694 메인페이지, 모집공고 모아보기 페이지 성능 개선 SP-694 메인페이지, 모집공고 모아보기 페이지 성능 개선 - Code Splitting, Loading Spinner 구현 Aug 30, 2024
@SungHyun627 SungHyun627 merged commit 782b97e into dev Aug 30, 2024
4 checks passed
Copy link

💡 LightHouse Reports

🟢 90 ~ 100    🟠 50 ~ 89    🔴 0 ~ 49

🖥 Desktop

📄 메인
Category Score
🟠 Performance 59
🟢 Accessibility 95
🟢 Best practices 100
🟢 SEO 92
🔴 First Contentful Paint 2.2 s
🔴 Largest Contentful Paint 5.1 s
🔴 Speed Index 11.4 s
🟢 Total Blocking Time 40 ms
🟢 Cumulative Layout Shift 0.017
📄 로그인
Category Score
🟠 Performance 64
🟢 Accessibility 95
🟢 Best practices 100
🟢 SEO 92
🔴 First Contentful Paint 2.1 s
🔴 Largest Contentful Paint 5.0 s
🔴 Speed Index 2.4 s
🟢 Total Blocking Time 20 ms
🟢 Cumulative Layout Shift 0.004
📄 모집공고 모아보기
Category Score
🟠 Performance 58
🟢 Accessibility 91
🟢 Best practices 100
🟢 SEO 92
🔴 First Contentful Paint 2.3 s
🔴 Largest Contentful Paint 5.1 s
🔴 Speed Index 10.1 s
🟢 Total Blocking Time 100 ms
🟢 Cumulative Layout Shift 0.021
📄 모집공고 상세
Category Score
🟠 Performance 63
🟠 Accessibility 87
🟢 Best practices 96
🟠 SEO 83
🔴 First Contentful Paint 2.1 s
🔴 Largest Contentful Paint 4.9 s
🔴 Speed Index 2.5 s
🟢 Total Blocking Time 90 ms
🟢 Cumulative Layout Shift 0.012

📱 Mobile

📄 메인
Category Score
🔴 Performance 37
🟢 Accessibility 95
🟢 Best practices 93
🟢 SEO 92
🔴 First Contentful Paint 12.5 s
🔴 Largest Contentful Paint 30.2 s
🔴 Speed Index 27.5 s
🔴 Total Blocking Time 720 ms
🟢 Cumulative Layout Shift 0
📄 로그인
Category Score
🔴 Performance 45
🟢 Accessibility 95
🟢 Best practices 100
🟢 SEO 92
🔴 First Contentful Paint 12.5 s
🔴 Largest Contentful Paint 30.0 s
🔴 Speed Index 12.5 s
🟠 Total Blocking Time 440 ms
🟢 Cumulative Layout Shift 0
📄 모집공고 모아보기
Category Score
🔴 Performance 34
🟢 Accessibility 91
🟢 Best practices 93
🟢 SEO 92
🔴 First Contentful Paint 12.5 s
🔴 Largest Contentful Paint 30.0 s
🔴 Speed Index 24.7 s
🔴 Total Blocking Time 950 ms
🟢 Cumulative Layout Shift 0
📄 모집공고 상세
Category Score
🔴 Performance 38
🟠 Accessibility 87
🟢 Best practices 93
🟠 SEO 83
🔴 First Contentful Paint 12.5 s
🔴 Largest Contentful Paint 30.0 s
🔴 Speed Index 12.5 s
🔴 Total Blocking Time 730 ms
🟢 Cumulative Layout Shift 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant