Skip to content

Commit

Permalink
[웹페이지성능개선] 번들 사이즈 확인 및 HTML 응답 시간 개선 (#72)
Browse files Browse the repository at this point in the history
* refactor : svg 2 png 변경

* style : svg 파일 정리 및 이미지 생성 아이콘 변경

* style : 이미지 생성 png 변경

* feat : svg 파일 용량 개선

* chore : 이미지 태그 로딩 추가

* feat : 이미지 preload

* feat : head에 preload 이미지 추가

* feat : head에 추가된 preload 제거 및 webp 변경

* feat : route 기반 코드 스플리팅

* chore : 이미지 레이지 로딩 제거

* chore : 이미지 크기 조정
  • Loading branch information
imeureka authored Sep 15, 2024
1 parent 5b16da6 commit cd54b30
Show file tree
Hide file tree
Showing 31 changed files with 4,991 additions and 330 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"msw": "^2.2.3",
"rollup-plugin-visualizer": "^5.12.0",
"typescript": "^5.2.2",
"vite": "^5.1.6",
"vite-plugin-svgr": "^4.2.0"
Expand Down
Binary file added src/assets/Icon/event_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icon/guide_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icon/guide_icon.webp
Binary file not shown.
Binary file added src/assets/Icon/menu_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icon/mystore_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icon/recreate_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icon/sodong_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icon/sodong_icon.webp
Binary file not shown.
Binary file added src/assets/Icon/store_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icon/store_icon.webp
Binary file not shown.
Binary file added src/assets/Icon/text_recreate_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 0 additions & 29 deletions src/assets/svg/IconEventEmoji.tsx

This file was deleted.

29 changes: 0 additions & 29 deletions src/assets/svg/IconMenuEmoji.tsx

This file was deleted.

24 changes: 0 additions & 24 deletions src/assets/svg/Image.tsx

This file was deleted.

24 changes: 0 additions & 24 deletions src/assets/svg/ImgGuide.tsx

This file was deleted.

29 changes: 0 additions & 29 deletions src/assets/svg/ImgMyStore.tsx

This file was deleted.

24 changes: 0 additions & 24 deletions src/assets/svg/ImgSodong.tsx

This file was deleted.

48 changes: 0 additions & 48 deletions src/assets/svg/MyStoreIc.tsx

This file was deleted.

24 changes: 0 additions & 24 deletions src/assets/svg/Store.tsx

This file was deleted.

24 changes: 0 additions & 24 deletions src/assets/svg/Text.tsx

This file was deleted.

11 changes: 0 additions & 11 deletions src/assets/svg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ export { default as GuideIc } from './GuideIc';
export { default as HistoryIc } from './HistoryIc';
export { default as Instagram } from './Instagram';
export { default as KoGptIc } from './KoGptIc';
export { default as MyStoreIc } from './MyStoreIc';
export { default as PostNewIc } from './PostNewIc';
export { default as Ai } from './Ai';
export { default as Carrot } from './Carrot';
Expand All @@ -15,16 +14,13 @@ export { default as FooterImg } from './Footer';
export { default as Hat } from './Hat';
export { default as IcArrow } from './IcArrow';
export { default as IcRetry } from './IcRetry';
export { default as Image } from './Image';
export { default as Kakao } from './Kakao';
export { default as Kakaomap } from './Kakaomap';
export { default as Kogpt } from './Kogpt';
export { default as MyStore } from './MyStore';
export { default as Myposting } from './Myposting';
export { default as ProfileImg } from './ProfileImg';
export { default as Search } from './Search';
export { default as Store } from './Store';
export { default as Text } from './Text';
export { default as Tip } from './Tip';
export { default as Xmark } from './Xmark';
export { default as TipBtn } from './Tip';
Expand All @@ -33,15 +29,8 @@ export { default as IcEmptyThumbnailFinal } from './IcEmptyThumbnailFinal';
export { default as Footer } from './Footer';
export { default as IconLock } from './IconLock';

export { default as ImgSodong } from './ImgSodong';
export { default as ImgGuide } from './ImgGuide';
export { default as ImgMyStore } from './ImgMyStore';

export { default as IcFeed01 } from './IcFeed01';
export { default as IcHome01 } from './IcHome01';
export { default as IcPosting01 } from './IcPosting01';
export { default as IcPosting02 } from './IcPosting02';
export { default as IconArrow } from './IconArrow';

export { default as IconEventEmoji } from './IconEventEmoji';
export { default as IconMenuEmoji } from './IconMenuEmoji';
11 changes: 8 additions & 3 deletions src/components/Post/PostBottomSheet.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { BottomSheet } from 'react-spring-bottom-sheet';
import { Image, Text } from '../../assets/svg';
import styled from 'styled-components';
import recreateIcon from '../../assets/Icon/recreate_icon.png';
import recreateTextIcon from '../../assets/Icon/text_recreate_icon.png';

interface PostBottomSheetProps {
open: boolean;
Expand Down Expand Up @@ -31,13 +32,13 @@ export default function PostBottomSheet({
<BottomSheetSelectContainer>
{type == 'Both' && (
<BottomSheetSelect onClick={() => onSelect('Image')}>
<Image style={{ width: '110px' }} />
<img src={recreateIcon} />
<p>이미지 생성하기</p> <div>{imgCnt}/3</div>
</BottomSheetSelect>
)}

<BottomSheetSelect onClick={() => onSelect('Text')}>
<Text style={{ width: '110px' }} />
<img src={recreateTextIcon} />
<p>글 생성하기</p> <div>{txtCnt}/3</div>
</BottomSheetSelect>
</BottomSheetSelectContainer>
Expand Down Expand Up @@ -92,4 +93,8 @@ const BottomSheetSelect = styled.div`
> div {
${({ theme }) => theme.fonts.ex_01};
}
> img {
width: 110px;
}
`;
13 changes: 5 additions & 8 deletions src/components/PostNew/SelectType/SelectTypeOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { GenderOptionProps } from '../../../types/PostNew';
import { useOnboardingContext } from '../../../context/PostNew/PostNewContext';
import NextButton from '../PostFooter/NextButton';
import { NameInputProps } from '../SelectSns/SelectSns';
import { IconEventEmoji, IconMenuEmoji } from '../../../assets/svg';
import IconEvent from '../../../assets/Icon/event_icon.png';
import IconMenu from '../../../assets/Icon/menu_icon.png';

export default function SelectType(props: NameInputProps) {
const { onNext } = props;
Expand All @@ -26,12 +27,12 @@ export default function SelectType(props: NameInputProps) {
}

const typeOptions = [
{ label: '메뉴 홍보', labelSub: 'ex. 신메뉴 홍보', value: '메뉴', image: IconMenuEmoji },
{ label: '메뉴 홍보', labelSub: 'ex. 신메뉴 홍보', value: '메뉴', image: IconMenu },
{
label: '이벤트 홍보',
labelSub: 'ex. 첫 오픈 할인 이벤트',
value: '이벤트',
image: IconEventEmoji,
image: IconEvent,
},
];

Expand All @@ -44,7 +45,7 @@ export default function SelectType(props: NameInputProps) {
selected={selectedType === option.value}
onClick={() => handleMenuSelect(option.value)}
>
<option.image className='nav-icon' />
<img src={option.image} alt={option.label} />
<LabelContainer>
{option.label}
<p>{option.labelSub}</p>
Expand Down Expand Up @@ -94,8 +95,4 @@ const TypeOption = styled.div<GenderOptionProps>`
${({ theme }) => theme.fonts.heading_02};
${({ theme, selected }) =>
selected ? `border: 1px solid ${theme.colors.main}; color: ${theme.colors.main}; ` : ''}
.nav-icon {
width: 3.75rem;
}
`;
8 changes: 6 additions & 2 deletions src/components/StoreNew/StoreResultNone.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import styled from 'styled-components';
import { Store } from '../../assets/svg';
import storeIcon from '../../assets/Icon/mystore_icon.png';

interface StoreResultNoneProps {
title: string;
Expand All @@ -15,7 +15,7 @@ export default function StoreResultNone({
}: StoreResultNoneProps) {
return (
<StoreResultNoneContainer height={height} $isClickable={onClick !== undefined}>
<Store style={{ width: '40%' }} />
<img src={storeIcon} />
<h3>{title}</h3>
<p onClick={onClick}>{description}</p>
</StoreResultNoneContainer>
Expand All @@ -40,6 +40,10 @@ const StoreResultNoneContainer = styled.div<{ height?: string; $isClickable?: bo
${({ theme }) => theme.fonts.ex_01};
margin: 0.31rem 0;
> img {
width: 40%;
}
// Click 가능한 경우,
cursor: ${({ $isClickable }) => ($isClickable ? 'pointer' : 'none')};
text-decoration: ${({ $isClickable }) => ($isClickable ? 'underline' : 'none')};
Expand Down
48 changes: 22 additions & 26 deletions src/components/common/Card/CommonCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,30 @@ interface PostCardProps {

export default function PostNewCard({ type }: PostCardProps) {
const navigate = useNavigate();
const {
title,
subTitle,
buttonText,
navigateTo,
backgroundColor,
Icon,
iconWidth,
iconBottom,
iconLeft,
} = CARD_CONFIG[type];
const { title, subTitle, buttonText, navigateTo, backgroundColor, Icon, iconBottom, iconLeft } =
CARD_CONFIG[type];

const handlePostCreate = () => {
navigate(navigateTo);
};

return (
<CardContainer backgroundColor={backgroundColor} onClick={handlePostCreate}>
<TitleContainer>
<PostTitle type={type}>{title}</PostTitle>
<PostSubTitle type={type}>{subTitle}</PostSubTitle>
<Button type={type}>{buttonText}</Button>
</TitleContainer>
<>
<CardContainer backgroundColor={backgroundColor} onClick={handlePostCreate}>
<TitleContainer>
<PostTitle type={type}>{title}</PostTitle>
<PostSubTitle type={type}>{subTitle}</PostSubTitle>
<Button type={type}>{buttonText}</Button>
</TitleContainer>

<IconContainer bottom={iconBottom} left={iconLeft}>
<Icon width={iconWidth} />
</IconContainer>
</CardContainer>
<IconContainer bottom={iconBottom} left={iconLeft}>
<picture>
<source srcSet={`${Icon}`} type='image/webp' />
<img src={Icon} alt='Card Icon' width='110' height='110' loading='lazy' />
</picture>
</IconContainer>
</CardContainer>
</>
);
}

Expand All @@ -50,11 +46,6 @@ const CardContainer = styled.section<{ backgroundColor: string }>`
margin-bottom: 1rem;
border-radius: 10px;
background-color: ${({ backgroundColor, theme }) => theme.colors[backgroundColor]};
img {
width: 172px;
height: 168px;
}
`;

const PostTitle = styled.p<{ type: keyof typeof CARD_CONFIG }>`
Expand All @@ -79,6 +70,11 @@ const IconContainer = styled.div<{ bottom: string; left: string }>`
position: relative;
bottom: ${({ bottom }) => bottom};
left: ${({ left }) => left};
> img {
width: 210px;
height: 210px;
}
`;

const Button = styled.button<{ type: keyof typeof CARD_CONFIG }>`
Expand Down
10 changes: 6 additions & 4 deletions src/core/Post.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ImgSodong, ImgGuide, ImgMyStore } from '../assets/svg/index';
import TrendImg from '../assets/Image/trend3.png';
import TrendImg2 from '../assets/Image/trend4.png';
import ImgSodong from '../assets/Icon/sodong_icon.webp';
import ImgGuide from '../assets/Icon/guide_icon.webp';
import ImgMyStore from '../assets/Icon/store_icon.webp';

export const POSTING_CHANNEL = Object.freeze({
INSTAGRAM: `인스타그램`,
Expand Down Expand Up @@ -28,8 +30,8 @@ export const CARD_CONFIG = {
backgroundColor: 'main',
Icon: ImgSodong,
iconWidth: '13rem',
iconBottom: '5.5rem',
iconLeft: '8rem',
iconBottom: '2.75rem',
iconLeft: '12rem',
},
guideline: {
title: '이용가이드',
Expand All @@ -50,7 +52,7 @@ export const CARD_CONFIG = {
backgroundColor: 'yellow',
Icon: ImgMyStore,
iconWidth: '7rem',
iconBottom: '2.2rem',
iconBottom: '2.75rem',
iconLeft: '12rem',
},
};
Expand Down
77 changes: 57 additions & 20 deletions src/router/Router.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { createBrowserRouter } from 'react-router-dom';
import Layout from '../layouts/Layout';
import Home from '../pages/Home/HomePage';
import PostResultPage from '../pages/PostResult/PostResultPage';
import HeaderLayout from '../layouts/HeaderLayout';
import NotFound from '../components/Error/NotFound';
import Login from '../pages/Login/Login';
import StoreNewPage from '../pages/StoreNew/StoreNewPage';
import { OnboardingProvider } from '../context/PostNew/PostNewContext';
import PostDetailPage from '../pages/PostDetail/PostDetailPage';
import GuidePage from '../pages/Guide/GuidePage';
import PostNewPage from '../pages/PostNew/PostNewPage';
import BottomLayout from '../layouts/BottomLayout';
import PostHistoryPage from '../pages/PostHistory/PostHistoryPage';
import FeedPage from '../pages/Feed/FeedPage';
import HeaderLayout from '../layouts/HeaderLayout';
import React, { Suspense } from 'react';

// 1. 라우트 기반 코드 스플리팅
// 컴포넌트를 비동기적으로 import 시킨다.
const Home = React.lazy(() => import('../pages/Home/HomePage'));
const Login = React.lazy(() => import('../pages/Login/Login'));
const PostResultPage = React.lazy(() => import('../pages/PostResult/PostResultPage'));
const PostNewPage = React.lazy(() => import('../pages/PostNew/PostNewPage'));
const StoreNewPage = React.lazy(() => import('../pages/StoreNew/StoreNewPage'));
const GuidePage = React.lazy(() => import('../pages/Guide/GuidePage'));
const PostDetailPage = React.lazy(() => import('../pages/PostDetail/PostDetailPage'));
const PostHistoryPage = React.lazy(() => import('../pages/PostHistory/PostHistoryPage'));
const FeedPage = React.lazy(() => import('../pages/Feed/FeedPage'));

const router = createBrowserRouter([
{
Expand All @@ -22,18 +26,27 @@ const router = createBrowserRouter([
children: [
{
path: '/',
element: <Login />,
element: (
<Suspense fallback={<div>Loading...</div>}>
<Login />
</Suspense>
),
},

{
path: '/post-result/:id',
element: <PostResultPage />,
element: (
<Suspense fallback={<div>Loading...</div>}>
<PostResultPage />
</Suspense>
),
},
{
path: '/post',
element: (
<OnboardingProvider>
<PostNewPage />
<Suspense fallback={<div>Loading...</div>}>
<PostNewPage />
</Suspense>
</OnboardingProvider>
),
},
Expand All @@ -42,15 +55,27 @@ const router = createBrowserRouter([
children: [
{
path: '/home',
element: <Home />,
element: (
<Suspense fallback={<div>Loading...</div>}>
<Home />
</Suspense>
),
},
{
path: '/post-history',
element: <PostHistoryPage />,
element: (
<Suspense fallback={<div>Loading...</div>}>
<PostHistoryPage />
</Suspense>
),
},
{
path: '/feed',
element: <FeedPage />,
element: (
<Suspense fallback={<div>Loading...</div>}>
<FeedPage />
</Suspense>
),
},
],
},
Expand All @@ -59,15 +84,27 @@ const router = createBrowserRouter([
children: [
{
path: '/guide',
element: <GuidePage />,
element: (
<Suspense fallback={<div>Loading...</div>}>
<GuidePage />
</Suspense>
),
},
{
path: '/post-detail/:id',
element: <PostDetailPage />,
element: (
<Suspense fallback={<div>Loading...</div>}>
<PostDetailPage />
</Suspense>
),
},
{
path: '/store-new',
element: <StoreNewPage />,
element: (
<Suspense fallback={<div>Loading...</div>}>
<StoreNewPage />
</Suspense>
),
},
],
},
Expand Down
Loading

0 comments on commit cd54b30

Please sign in to comment.