Skip to content

Commit

Permalink
refactor: 번들링 사이즈 관련 성능 개선 (#258)
Browse files Browse the repository at this point in the history
* chore: 번들링 도구 세팅

* feat: LinkButton, Button 분리

* feat: 랜딩 페이지 이미지 최적화

* feat: 로딩, 에러 이미지 최적화

* feat: 모달 사이드 바 최적화

* refactor: svg를 Image src로 넣기

* feat: 랜딩 페이지 이미지 최적화

* feat: 자유 게시판 이미지 최적화

* refactor: lodash-es로 변경

* refactor: 테마에 따라 색상 변경 불필요한 svgr Image로 변경

* chore: 번들링 도구 세팅

* feat: LinkButton, Button 분리

* feat: 랜딩 페이지 이미지 최적화

* feat: 로딩, 에러 이미지 최적화

* feat: 모달 사이드 바 최적화

* refactor: svg를 Image src로 넣기

* feat: 랜딩 페이지 이미지 최적화

* feat: 자유 게시판 이미지 최적화

* refactor: lodash-es로 변경

* refactor: 테마에 따라 색상 변경 불필요한 svgr Image로 변경

* fix: 콘솔 에러 처리

* fix: 정적 이미지 middleware 처리

* fix: 테마 관련 자유게시판 이미지 수정

* fix: 빌드 오류 해결

---------

Co-authored-by: hyunow <[email protected]>
Co-authored-by: seo02wow <[email protected]>
  • Loading branch information
3 people authored Aug 26, 2024
1 parent 3da8c10 commit 365097e
Show file tree
Hide file tree
Showing 53 changed files with 546 additions and 386 deletions.
21 changes: 17 additions & 4 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,32 @@
"rules": {
"react/jsx-no-useless-fragment": "off",
"multiline-comment-style": "off",
"quotes": ["error", "double"],
"quotes": [
"error",
"double"
],
"linebreak-style": 0,
"react/react-in-jsx-scope": "off",
"react/jsx-filename-extension": [
1,
{ "extensions": [".js", ".jsx", ".ts", ".tsx"] }
{
"extensions": [
".js",
".jsx",
".ts",
".tsx"
]
}
],
"react/jsx-props-no-spreading": "off",
"react/require-default-props": "off",
"jsx-a11y/label-has-associated-control": [
2,
{
"some": ["nesting", "id"]
"some": [
"nesting",
"id"
]
}
],
"import/extensions": [
Expand All @@ -38,4 +51,4 @@
"parserOptions": {
"project": "./tsconfig.json"
}
}
}
17 changes: 13 additions & 4 deletions app/(auth)/_components/easy-login-button.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
"use client";

import { GOOGLE_OAUTH_URL, KAKAO_OAUTH_URL } from "@/constants/oauth";
import Google from "@/public/icons/google.svg";
import KakaoTalk from "@/public/icons/kakao-talk.svg";
import Image from "next/image";
import Link from "next/link";
import { useEffect, useState } from "react";

Expand Down Expand Up @@ -34,9 +33,19 @@ export default function EasyLoginButton({ domain }: EasyLoginButtonProps) {
className={`flex size-[42px] items-center justify-center rounded-full ${isKaKaoTalk ? "bg-[#F5E14B]" : "bg-[#F9FAFB]"}`}
>
{isKaKaoTalk ? (
<KakaoTalk width={26} height={24} />
<Image
src="/icons/kakao-talk.svg"
alt="카카오톡 간편 로그인"
width={26}
height={26}
/>
) : (
<Google width={26} height={24} />
<Image
src="/icons/google.svg"
alt="구글 간편 로그인"
width={26}
height={26}
/>
)}
</Link>
);
Expand Down
10 changes: 8 additions & 2 deletions app/(auth)/oauth/_components/auth-redirect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { oauthLogin } from "@/lib/apis/auth";
import { myFetch } from "@/lib/apis/myFetch";
import { GetGoogleTokenResponse } from "@/lib/apis/type";
import { showToast } from "@/lib/show-toast";
import Spinner from "@/public/icons/tube-spinner.svg";
import { useMutation } from "@tanstack/react-query";
import { setCookie } from "cookies-next";
import { useRouter } from "next-nprogress-bar";
import Image from "next/image";
import { useSearchParams } from "next/navigation";
import { useEffect, useState } from "react";

Expand Down Expand Up @@ -84,7 +84,13 @@ export default function AuthRedirect({ provider }: AuthRedirectProps) {
{provider === "KAKAO" ? "카카오" : "구글"} 계정으로 로그인하고 있어요.
</h1>
<div className="flex justify-center">
<Spinner width={120} height={120} className="mt-[30px]" />
<Image
src="/icons/tube-spinner.svg"
alt="로딩 중"
width={120}
height={120}
className="mt-[30px]"
/>
</div>
</>
);
Expand Down
7 changes: 3 additions & 4 deletions app/(free-board)/_components/card.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
"use client";

import useClickOutside from "@/hooks/use-click-outside";
import Comment from "@/public/icons/comment.svg";
import ProfileIcon from "@/public/icons/default-profile.svg";
import DefaultProfile from "@/public/icons/default-profile.svg";
import { KebabHover } from "@/public/icons/kebab-hover";
import { KebabLarge } from "@/public/icons/kebab-large";
import LikeButtonColored from "@/public/icons/like-button-colored";
Expand Down Expand Up @@ -103,7 +102,7 @@ export function Profile({
className="rounded-full"
/>
) : (
<ProfileIcon width={32} height={32} className="rounded-full" />
<DefaultProfile width={32} height={32} className="rounded-full" />
)}
<span className="leading-3 md:leading-[14px]">{name}</span>
</section>
Expand Down Expand Up @@ -175,7 +174,7 @@ export function CommentIcon({
<section
className={`flex items-center gap-0.5 text-sm font-normal leading-4 text-text-disabled ${className}`}
>
<Comment width={size} height={size} />
<Image src="/icons/comment.svg" alt="댓글" width={size} height={size} />
<span className="flex h-4 items-center">
{commentCount > 9999 ? "9999+" : commentCount}
</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import Button from "@/components/button/button";
import { useCustomOverlay } from "@/hooks/use-custom-overlay";
import ArrowReturn from "@/public/icons/arrow-return";
import MediaIcon from "@/public/icons/media-icon.svg";
import Image from "next/image";
import { useState } from "react";
import { useDropzone } from "react-dropzone";
Expand Down Expand Up @@ -79,7 +78,12 @@ export default function FileDragDown({
<input {...getInputProps()} />
{preview === null ? (
<section className="relative inset-0 flex h-full w-full flex-col items-center justify-center rounded-xl border-2 border-dashed border-background-tertiary bg-white py-4 md:aspect-square">
<MediaIcon />
<Image
src="/icons/media-icon.svg"
alt="media-icon"
height="77"
width="96"
/>
<p className="text-xl font-bold text-black">
사진과 동영상을 여기에 놓으세요
</p>
Expand Down
13 changes: 1 addition & 12 deletions app/(free-board)/_components/handle-article-modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useCallback, useState } from "react";

import ArticleForm from "./article-form";
import FileDragDown from "./file-drag-down";
import { ArticleType } from "./types";

interface HandleArticleModalProps {
close: () => void;
Expand All @@ -14,18 +15,6 @@ interface HandleArticleModalProps {
onSubmit: (formData: ArticleType) => void;
}

export interface FormType {
title: string;
content: string;
image: File | string;
}

export interface ArticleType {
title: string;
content: string;
image: string;
}

export default function HandleArticleModal({
close,
onSubmit,
Expand Down
11 changes: 0 additions & 11 deletions app/(free-board)/_components/handle-article-modal/type.d.ts

This file was deleted.

4 changes: 2 additions & 2 deletions app/(free-board)/_components/modal-cancel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Modal from "@/components/modal/modal";
import Alert from "@/public/icons/alert.svg";
import Image from "next/image";
import { useCallback } from "react";

interface ModalCancelProps {
Expand All @@ -22,7 +22,7 @@ export default function ModalCancel({
return (
<Modal close={close} closeOnFocusOut>
<header className="flex justify-center pb-4 pt-6">
<Alert width={24} height={24} />
<Image src="/icons/alert.svg" alt="경고창" width={24} height={24} />
</header>
<div className="mx-12 text-center md:mx-9">
<Modal.Title className="mb-4 text-slate-50 md:text-text-primary">
Expand Down
4 changes: 2 additions & 2 deletions app/(free-board)/_components/modal-delete.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Modal from "@/components/modal/modal";
import Alert from "@/public/icons/alert.svg";
import Image from "next/image";

export default function ModalDelete({
close,
Expand All @@ -15,7 +15,7 @@ export default function ModalDelete({
return (
<Modal close={close} closeOnFocusOut>
<header className="flex justify-center pb-4 pt-6">
<Alert width={24} height={24} />
<Image src="/icons/alert.svg" alt="경고창" width={24} height={24} />
</header>
<div className="mx-12 text-center md:mx-9">
<Modal.Title className="mb-4 text-slate-50 md:text-text-primary">
Expand Down
3 changes: 2 additions & 1 deletion app/(free-board)/_components/upload-article-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { useCustomOverlay } from "@/hooks/use-custom-overlay";
import { SubmitHandler } from "react-hook-form";

import { useUploadArticleMutation } from "../_query/mutation";
import ArticleModal, { ArticleType } from "./handle-article-modal";
import ArticleModal from "./handle-article-modal";
import { ArticleType } from "./handle-article-modal/types";

export default function UploadArticleButton() {
const uploadPostMutation = useUploadArticleMutation();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import {
LikeCountSection,
Profile,
} from "@/app/(free-board)/_components/card";
import HandleArticleModal, {
ArticleType,
} from "@/app/(free-board)/_components/handle-article-modal";
import HandleArticleModal from "@/app/(free-board)/_components/handle-article-modal";
import { ArticleType } from "@/app/(free-board)/_components/handle-article-modal/types";
import ModalDelete from "@/app/(free-board)/_components/modal-delete";
import {
useDeleteArticleMutation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default function LikeSection({ articleId }: LikeSectionProps) {
const { likeCount, isLiked } = data;
const handleClick = () => {
if (isFetching || isPending) {
/* eslint-disable-next-line */
alert(
"공감/비공감 후 일정시간 동안 추가적인 공감/비공감을 제한하고 있습니다.",
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function ArticlesList({ searchParams }: ArticlesListProps) {

return (
<>
<section className="mt-6 flex flex-col gap-6 md:mt-8 xl:flex-row xl:flex-wrap">
<section className="mt-6 flex flex-col gap-6 md:mt-8 xl:grid xl:grid-cols-2 xl:grid-rows-5">
{articles && articles.length > 0 ? (
articles.map((article) => (
<ArticleCard key={article.id} article={article} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { Dropdown } from "@/components/dropdown/dropdown";
import { useProgress } from "@/hooks/use-progress";
import ToggleClose from "@/public/icons/toggle.svg";
import Image from "next/image";
import Link from "next/link";

const options: { display: "최신순" | "인기순"; value: "recent" | "like" }[] = [
Expand Down Expand Up @@ -37,10 +37,12 @@ export default function ArticleOrderbyDropdown({
>
<section className="text-xs md:text-sm">
<Dropdown.Button className="h-10 !w-[94px] justify-between rounded-xl border border-black border-opacity-10 bg-background-tertiary px-[14px] dark:border dark:border-white dark:border-opacity-10 md:h-11 md:!w-[120px]">
<ToggleClose
<Image
src="/icons/toggle.svg"
alt="토글"
width="24"
height="24"
className="h-6 w-6 group-hover:animate-pulse"
className="group-hover:animate-pulse"
/>
</Dropdown.Button>
<Dropdown.Body className="!z-10 mt-1 flex w-[94px] flex-col rounded-xl border border-black border-opacity-10 bg-background-tertiary dark:border dark:border-white dark:border-opacity-10 md:w-[120px]">
Expand Down
11 changes: 9 additions & 2 deletions app/(free-board)/boards/_components/article-ranking-chart.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getArticles } from "@/lib/apis/article";
import Fire from "@/public/icons/fire.svg";
import { convertDiffDateFromNow } from "@/utils/convert-date";
import shortenString from "@/utils/shorten-string";
import Image from "next/image";
import Link from "next/link";

export default async function ArticleRankingChart() {
Expand All @@ -24,7 +24,14 @@ export default async function ArticleRankingChart() {
className="flex gap-1 truncate hover:underline"
>
{`${shortenString(article.title, 16)}`}
{i <= 2 && <Fire className="h-4 w-4" />}
{i <= 2 && (
<Image
src="/icons/fire.svg"
alt="Fire"
width={16}
height={16}
/>
)}
</Link>
</span>
<div className="flex-shrink-0 text-sm font-normal text-text-disabled">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LinkButton } from "@/components/button/button";
import LinkButton from "@/components/button/link-button";

interface ArticleResetButtonProps {
btnSize: "large" | "x-small";
Expand Down
64 changes: 42 additions & 22 deletions app/(free-board)/boards/_components/article-search-bar.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
"use client";

import { BasicInput } from "@/components/input-field/basic-input";
import SearchIcon from "@/public/icons/search.svg";
import { AnimatePresence, motion, useInView } from "framer-motion";
import {
AnimatePresence,
LazyMotion,
domAnimation,
m,
useInView,
} from "framer-motion";
import { useRouter } from "next-nprogress-bar";
import Image from "next/image";
import { useRef } from "react";
import { SubmitHandler, useForm } from "react-hook-form";

Expand Down Expand Up @@ -41,30 +47,44 @@ export default function ArticleSearchBar() {
placeholder="검색어를 입력해주세요"
className="h-12 border border-black border-opacity-10 pl-[48px] text-sm font-normal text-text-default md:h-14 md:pl-[52px] md:text-base"
/>
<SearchIcon className="absolute left-4 top-3 h-6 w-6 md:top-4" />
<Image
src="/icons/search.svg"
alt="돋보기"
width={24}
height={24}
className="absolute left-4 top-3 md:top-4"
/>
</form>
<AnimatePresence>
{!isInView && (
<motion.section
transition={{ type: "tween", duration: 0.3 }}
initial={{ opacity: 0, y: -100 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -100 }}
className="fixed left-0 right-0 top-[58px] z-30 bg-background-secondary px-4 pb-2 pt-1 shadow-xl"
>
<form
className="relative mx-auto w-full max-w-[1200px] rounded-xl px-4 md:px-0"
onSubmit={handleSubmit(onSubmit)}
<LazyMotion features={domAnimation}>
<m.section
transition={{ type: "tween", duration: 0.3 }}
initial={{ opacity: 0, y: -100 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -100 }}
className="fixed left-0 right-0 top-[58px] z-30 bg-background-secondary px-4 pb-2 pt-1 shadow-xl"
>
<BasicInput
register={register}
id="keyword"
placeholder="검색어를 입력해주세요"
className="h-12 bg-background-tertiary pl-[48px] text-sm font-normal text-text-default md:h-14 md:pl-[52px] md:text-base"
/>
<SearchIcon className="absolute left-8 top-3 h-6 w-6 md:left-4 md:top-4" />
</form>
</motion.section>
<form
className="relative mx-auto w-full max-w-[1200px] rounded-xl px-4 md:px-0"
onSubmit={handleSubmit(onSubmit)}
>
<BasicInput
register={register}
id="keyword"
placeholder="검색어를 입력해주세요"
className="h-12 bg-background-tertiary pl-[48px] text-sm font-normal text-text-default md:h-14 md:pl-[52px] md:text-base"
/>
<Image
src="/icons/search.svg"
alt="돋보기"
width={24}
height={24}
className="absolute left-8 top-3 md:left-4 md:top-4"
/>
</form>
</m.section>
</LazyMotion>
)}
</AnimatePresence>
</>
Expand Down
Loading

1 comment on commit 365097e

@codefug
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Deploy preview for kkom-kkom ready!

✅ Preview
https://kkom-kkom-4dwouqngw-codefugs-projects.vercel.app

Built with commit 365097e.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.