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

[Feat] 페이지 코드 스플릿팅 #213

Merged
merged 2 commits into from
Nov 17, 2024

Conversation

Ivoryeee
Copy link
Collaborator

@Ivoryeee Ivoryeee commented Oct 23, 2024

🔥 Related Issues

✅ 작업 리스트

  • 페이지 코드 스플릿팅

🔧 작업 내용

Login 페이지에서 사용되는 lottie 번들이 Home 페이지에서도 불러와져 큰 용량을 차지하고 있었습니다. 로그인 페이지를 하나의 번들로 분리하고, Login 페이지에서만 lottie가 사용되도록 코드 스플릿팅을 진행했습니다. Lazy, Suspend 사용으로 동적으로 컴포넌트를 불러와 번들의 크기를 줄이고, 초기 렌더링에서 사용되지 않는 컴포넌트의 로딩을 지연시킴으로써 페이지 성능을 최적화 하였습니다.

Router.tsx

const LoginPage = lazy(() => import('@/pages/LoginPage'));

LoginPage에서 동적 import를 활용해 모듈을 비동기적으로 로드할 수 있도록 lazy를 추가합니다.

const router: Router = createBrowserRouter([
	{
		//public 라우트들
		path: '/',
		element: <Outlet />,
		children: [
			{
				path: ROUTES_CONFIG.login.path,
				element: (
					<Suspense fallback={<div>Loading...</div>}>
						<LoginPage />
					</Suspense>
				),
			},
			/.../
		],
	},

동적 import를 통해LoginPage가 로드되며, 그 동안 Suspense`의 fallback prop에 지정된 UI 요소가 화면에 표시됩니다.

LoginPage/index.tsx

	const handleMouseEnter = () => {
		import('@/pages/HomePage/HomePage').catch((error) => {
			console.error('홈페이지를 받아오는데 오류가 발생했습니다.', error);
		});
	};

LoginPage에서 로그인 버튼에 mouseover 될 때, HomePage 요소가 preload 되도록 handleMouseEnter를 추가했습니다.

	return (
				<ButtonSVG
					onMouseEnter={handleMouseEnter}
					onClick={handleClick}
					className={`ml-[12rem] transition-opacity duration-300 ${isAnimationComplete ? 'opacity-100' : 'opacity-0'}`}
				>
					<GoogleLoginIcon />
				</ButtonSVG>

ButtonSVGonMouseEnter={handleMouseEnter} 속성을 추가해 두었습니다.

구체적인 성능 개선 수치는 아래에 정리해 두었습니다!
https://www.notion.so/1282109060f4800483abfa3d015be1cc?pvs=4

🧐 새로 알게된 점

  • Lazy, 'Suspense` 사용에 대한 개념적 이해를 얻었습니다.
  • 네트워크 탭, 퍼포먼스 탭, lighthouse 사용을 통해 성능을 개선시키는 경험을 하였습니다.

🤔 궁금한 점

  • 로그인 페이지에 Lazy를 적용하고 나니 Lottie Animation이 ButtonSVG보다 늦게 불러와 지는 걸 발견했습니다. 네트워크 속도를 3G로 변경해 보았을 때, 콘텐츠 다운로드 속도는 개선되었으나 queue 시작 시점이 3-4초 가량 늦어지는 문제가 있습니다.

수정 전

image

수정 후

image

  • 첫 페이지를 불러올 때 로그인 페이지가 불러와지기 전까지 Suspense 사용으로 Loading 이라는 문구가 나타나도록 설정해 두었습니다. 모립의 첫 화면인데, Lottie-animation이 나타나기 전에 짧은 순간이라도 Loading이 나타나도록 하는 구현이 맞을지 고민이 되었습니다.

📸 스크린샷 / GIF / Link

@Ivoryeee Ivoryeee added the ✨ Feature 기능 개발 label Oct 23, 2024
@Ivoryeee Ivoryeee self-assigned this Oct 23, 2024
@Ivoryeee Ivoryeee linked an issue Oct 23, 2024 that may be closed by this pull request
1 task
Copy link
Member

@suwonthugger suwonthugger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

열심히 찾아보고 비교하며 진행해주셔서 감사드립니다~ 저도 많이 배웠어요. 코드 스플릿팅을 하고 끝!이 아니라 그 후의 고민까지 정말 야무지네요..

  • 먼저 로티 번들 네트워크 요청이 queued 된 시점이 4초가량 늦어졌긴 했지만, 이 부분은 해당 번들이 네트워크 요청 대기열에 들어간 순서가 단순히 조금 뒤로 밀린 부분이라 상관없다고 생각했어요.
    브라우저는 자원을 모두 받아온 후에 동작하기 때문에, 전체적인 퍼포먼스가 올라간 상태에서 로티 하나의 네트워크 요청 순서가 조금 뒤로 밀려났다고 해서 큰 영향은 없을 것 같아요!
    물론 제 의견이니 다른 의견있으시면 편하게 말씀해주셔도 됩니다!

  • 로딩은 저번에 서현이가 하나 UI 만들어 놓은게 있는데, 일단은 지금 로딩 적용한거 유지하고 나중에 로딩 컴포넌트를 하나 만들어서 사용합시다 굿굿!

아래 제안드린 사항만 확인 부탁드립니다!

Comment on lines +29 to +33
const handleMouseEnter = () => {
import('@/pages/HomePage/HomePage').catch((error) => {
console.error('홈페이지를 받아오는데 오류가 발생했습니다.', error);
});
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pre loading 적용까지 굿굿~~

Comment on lines 1 to 17
import type { Router } from '@remix-run/router';

import { Suspense, lazy } from 'react';
import { Outlet, createBrowserRouter } from 'react-router-dom';

import HomePage from '@/pages/HomePage/HomePage';
import LoginPage from '@/pages/LoginPage';
import NotFoundPage from '@/pages/NotFoundPage/NotFoundPage';
import TimerPage from '@/pages/TimerPage/TimerPage';

import RedirectPage from '../pages/RedirectPage';
import { ROUTES_CONFIG } from './routesConfig';

const LoginPage = lazy(() => import('@/pages/LoginPage'));

const ProtectedRoute = () => {
//Todo: 개발이 진행되면 실제 토큰 상태를 받아서 login page로 이동 시킴
// const accessToken = getAccessTotken();
Copy link
Member

@suwonthugger suwonthugger Nov 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3: 각 페이지별로 확연하게 쓰이는 컴포넌트들이 다르기도 하고 크기가 크다보니, Not found를 제외한, 페이지(Login, Home, Timer) 모두 페이지별 코드 스플릿팅을 해주는건 어떠신가요? 제 생각에는 성능이 더 올라갈 것 같아요!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋은 의견 감사합니다! Home, Timer에서는 특히 해당 페이지에서만 사용되는 컴포넌트나 라이브러리들이 많다 보니 코드 스플릿팅을 통해 성능이 크게 향상될 것 같아요! 요 부분 추가해 두겠습니다!

@pull-request-size pull-request-size bot added size/M and removed size/S labels Nov 12, 2024
Copy link
Member

@suwonthugger suwonthugger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@suwonthugger suwonthugger merged commit 1f75d4b into develop Nov 17, 2024
1 check passed
@suwonthugger suwonthugger deleted the feat/#204/page-code-splitting branch November 17, 2024 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

[ Feat ] 페이지 별 코드 스플리팅
2 participants