큐시즘 공식 홈페이지는 내부 활동과 프로젝트를 외부에 효과적으로 알리는 중요한 창구로, 구성원 모집 및 대외 홍보에 핵심적인 역할을 합니다. 그러나 기존 홈페이지는 클라이언트 사이드 렌더링(CSR) 방식으로 구현되어 있어 몇 가지 중요한 문제점이 있었습니다.
초기 로딩 속도가 느려 사용자 경험에 부정적인 영향을 주었습니다. 콘텐츠가 자바스크립트 로딩 이후에야 렌더링되어, 네트워크 상태가 좋지 않거나 저사양 기기를 사용하는 방문자의 경우 페이지가 표시되기까지 상당한 지연이 발생했습니다. 실제로 Lighthouse 기준 LCP(Largest Contentful Paint) 점수가 약 7초로 측정되어, 웹 성능 측면에서 개선이 시급한 상황이었습니다.
검색엔진 최적화(SEO)가 부족해 정보 노출에 제한이 있었습니다. 모든 콘텐츠가 클라이언트에서 동적으로 생성되다 보니 크롤러가 주요 정보를 제대로 인식하지 못했고, 이는 검색 결과에 큐시즘 활동이나 프로젝트가 노출되지 않는 문제로 이어졌습니다.
그동안 큐시즘 프로젝트 전시는 별도의 페이지에서 분리 관리되고 있어, 사용자가 큐시즘 전체 활동을 한눈에 파악하기 어려운 구조였습니다. 이로 인해 전시 콘텐츠의 접근성과 일관성이 떨어졌고, 내부적으로도 유지보수에 불편함이 존재했습니다.
반응형 작업이 되어 있지 않아 태블릿이나 모바일에서 접속 시 UI가 깨지는 문제가 있었습니다.
이번 리뉴얼에서는 Next.js 기반으로 전체 구조를 마이그레이션하고, 동시에 프로젝트 전시 탭도 새로 구축할 예정입니다.
Next.js를 선택한 이유는 다음과 같습니다:
서버 사이드 렌더링(SSR) 및 정적 생성(ISR)을 통해 초기 렌더 속도와 SEO를 자연스럽게 개선할 수 있어, 성능과 검색 노출 문제를 동시에 해결할 수 있기 때문입니다.
무엇보다 개인적으로 React보다 최적화에 신경 쓸 부분이 적어 개발 생산성을 높일 수 있었고, Next.js 경험이 많아 짧은 시간 안에 안정적인 마이그레이션과 신규 전시 탭 개발을 병행할 수 있다는 점이 결정적인 이유였습니다.
이번 개편을 통해 큐시즘의 활동과 프로젝트를 더 많은 사람에게 빠르고 정확하게 전달하고, 다양한 디바이스 환경에서도 일관된 사용자 경험을 제공할 수 있도록 할 예정입니다.
제가 맡은 부분은 프로젝트를 한눈에 볼 수 있는 프로젝트 페이지와 큐밀리(학회원)들이 남긴 후기를 모아볼 수 있는 후기 페이지였습니다.
🔗 기존 코드 링크
🔗 개선 코드 링크
🔗 프로젝트 페이지 링크
CSR 구조로 코드가 작성되어 있어 초기 로딩 속도가 매우 느렸습니다. 콘텐츠가 자바스크립트 로딩 이후에야 렌더링되어, 네트워크 상태가 좋지 않거나 저사양 기기를 사용하는 방문자의 경우 페이지가 표시되기까지 상당한 지연이 발생했습니다. 실제로 Lighthouse 기준 LCP(Largest Contentful Paint) 점수가 약 7초로 측정되어, 웹 성능 측면에서 개선이 시급한 상황이었습니다.
그리고 해당 링크의 코드를 보면, 페이지 파일임에도 불구하고 컴포넌트 분리가 제대로 되어 있지 않고,
반응형 작업을 시도하다가 마무리되지 않아 주석이 많이 남아 있는 코드임을 확인할 수 있습니다.
이 코드를 어떻게 활용해 개선할 수 있을지 많이 고민했지만,
결국 스타일 코드 외에는 가져올 수 있는 부분이 없었습니다.
기존 스타일 코드를 TailwindCSS로 변환하는 작업은 오래 걸리지 않을 것으로 판단되어 스타일만 참고하였고,
HTML 구조나 컴포넌트 구조는 너무 복잡하게 되어 있어 처음부터 새로 만드는 것이 더 효율적이라고 판단했습니다.
따라서, 피그마 디자인을 참고하며 처음부터 구조를 다시 잡고 캐싱을 이용하여 페이지 마이그레이션 작업을 진행하였습니다.
![]() |
![]() |
프로젝트 페이지에 들어가면, 밋업 프로젝트와 기업 프로젝트를 각각 확인할 수 있도록 탭이 나뉘어 있는 것을 볼 수 있습니다.
저희 큐시즘 웹사이트는 실시간으로 데이터를 불러오는 구조가 아니기 때문에, SSR(Server Side Rendering)이 아닌 ISR(Incremental Static Regeneration) 방식으로 정적 페이지를 제공하는 것을 목표로 했습니다.
SSR은 사용자가 페이지에 접속할 때마다 서버에서 실시간으로 페이지를 생성해주는 방식입니다. 반면 ISR은 한 번 정적으로 페이지를 생성해두고, 일정 주기마다(예: 1주일) 백그라운드에서 새로운 데이터로 페이지를 갱신하는 방식입니다.
큐시즘 홈페이지의 특성을 보면, 가장 많은 접속이 이루어지는 시기는 2월과 7월입니다. 이 시기는 신규 모집 인원을 뽑기 시작하면서 지원자 분들이 대거 큐시즘 사이트에 방문하는 시기입니다.
하지만 저희 사이트는 데이터가 자주 바뀌지 않는 구조이기 때문에, SSR 방식을 사용하면 2월과 7월에 갑자기 많은 사용자가 몰릴 때마다 서버가 실시간으로 페이지를 계속 생성해야합니다. 이로 인해 서버 부하가 급격히 증가할 수 있고, 심한 경우 사이트 접속이 원활하지 않을 수 있다는 문제점이 있습니다.
이런 상황을 고려해, 저희는 ISR 방식을 선택했습니다. ISR을 적용하면 페이지가 미리 정적으로 생성되어 있기 때문에, 많은 사용자가 동시에 접속하더라도 서버에 큰 부담이 가지 않는다. 또한, 데이터가 변경될 필요가 있을 때만 주기적으로(예: 1주일마다) 페이지가 갱신되기 때문에, 최신 정보도 적절히 반영할 수 있습니다.
그렇다면 왜 SSG(Static Site Generation) 방식으로 하지 않고 굳이 ISR을 선택했는가?
사실 저희도 처음에는 SSG 방식으로 구현하려고 했습니다. SSG는 빌드 시점에 모든 페이지를 미리 생성해두는 방식이기 때문에, 데이터가 거의 변하지 않는 사이트에는 매우 적합합니다. 하지만 큐시즘 프로젝트의 경우, 모집 일정이나 프로젝트 정보가 가끔씩 변경될 수 있고, 새로운 프로젝트가 추가될 수도 있습니다. 만약 SSG로만 구현한다면, 이런 변경 사항을 반영하려면 사이트 전체를 다시 빌드하고 배포해야 한다는 번거로움이 있었습니다.
반면 ISR을 사용하면, 데이터가 변경되더라도 설정한 주기(예: 1주일)에 맞춰 자동으로 페이지가 갱신됩니다. 만약 긴급하게 정보를 업데이트해야 할 경우, Next.js의 태그 기능을 활용해 특정 페이지만 빠르게 재생성할 수도 있습니다. 이런 유연함 덕분에, 저희는 SSG 대신 ISR 방식을 선택하게 되었습니다.
실제로 밋업 프로젝트 데이터를 패치하는 코드는 아래와 같이 작성했습니다.
export const getMeetupProjects = async (
cardinal: string,
batch?: string
): Promise<MeetupResponse> => {
try {
const url = `${baseUrl}/api/projects/meetup?batch=${batch}&cardinal=${cardinal}&order=desc`;
const res = await fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
cache: "force-cache",
next: { revalidate: 604800, tags: ["meetupProjects"] }, // 1주일(604800초)마다 재검증
});
if (!res.ok) {
throw new Error(`HTTP error! status: ${res.status}`);
}
const data = await res.json();
return data;
} catch (err) {
console.error("Failed to fetch meetup projects:", err);
throw err;
}
};
async function MeetupProjectPage() {
const meetupProjectList = await getMeetupProjects("");
return (
<>
<section className="w-full max-w-6xl mx-auto py-8 text-center">
<h1 className="text-5xl font-black mb-4 mt-[180px] leading-[130%]">
KUSITMS의 다양한 프로젝트를 <br />
구경해보세요!
</h1>
<p className="font-normal text-[20px]">
<ProjectTotalCount pathname="meetup" />의 프로젝트를 볼 수 있어요.
</p>
<NavButtons />
</section>
<section className="mx-auto w-full max-w-[1180px]">
<div className="flex w-full gap-[90px] mt-[100px] justify-center items-center">
<ImageCard>
<ImageCard.Sticker>
<Image
src="/projects/sticker/MeetupSticker.svg"
alt="스티커"
width={70}
height={100}
priority
style={{ width: 70, height: 100 }}
/>
</ImageCard.Sticker>
<ImageCard.Image src="/projects/tmp/meetup_tmpImg.jpeg" />
</ImageCard>
<EventIntro type="meetup" />
</div>
<ProjectContainer data={meetupProjectList.data} />
</section>
</>
);
}
export default MeetupProjectPage;
우리가 일반적으로 생각할 수 있는 API 캐싱입니다.
// Revalidate at most every hour
fetch('https://...', { next: { revalidate: 3600 } })
Next.js가 확장해놓은 fetch 함수에 next.revalidate 옵션을 넘기면 Data Cache가 동작합니다. 성공적으로 데이터를 가져왔다면 그 응답값을 저장해두었다가 동일한 경로로 fetch 함수를 실행할 때 실제 API 호출은 건너뛰고 저장해놓은 응답값을 반환합니다.
하나의 요청 동안만 유효한 Request Memoization과 다르게 Data Cache는 일정 시간 동안에 웹 서버로 들어오는 모든 요청에 대해 동작합니다. 만약 next.revalidate를 1초로 설정했다면, 1초에 1000명의 사용자가 접속해도 실제 API 요청은 1회 전송됩니다.
이 내용을 활용하여 Next.js의 fetch 옵션에 캐시 유효 기간을 일주일(604800초)로 설정했습니다. 이 설정 덕분에, 페이지는 최초 빌드 시 정적으로 생성되고, 7일마다 백그라운드에서 자동으로 최신 데이터로 갱신됩니다. 덕분에 실시간성이 필요 없는 프로젝트 페이지를 효율적으로 관리할 수 있고, 사용자는 항상 빠른 속도로 페이지를 이용할 수 있었습니다.
이처럼 SSR의 서버 부하 문제와 SSG의 불편함을 모두 피하면서, ISR을 통해 안정적이고 효율적으로 프로젝트 페이지를 운영할 수 있게 되었습니다.
fetch 문에 캐싱 주기(revalidate)만 설정하면 페이지 파일에서 별도로
revalidate
를 따로 지정할 필요 없이 ISR이 자동으로 적용됩니다.
🔗 기존 코드 링크
🔗 개선된 코드 링크
🔗 프로젝트 상세 페이지 링크
위 사진을 보면 알 수 있듯이, 각 프로젝트 요소를 클릭하면 상세 페이지로 이동하는 플로우로 구현되어 있다. URL도 /project/meetup에서 /project/meetup/프로젝트ID와 같이 동적 라우팅이 적용되도록 구성했다.
이렇게 동적 라우팅이 적용된 상세 페이지에서는 각 프로젝트의 이미지를 불러오게 되는데, 만약 이 페이지를 SSR(Server Side Rendering) 방식으로 렌더링하면 이미지가 처음에 천천히, 서서히 나타나는 현상이 발생할 수 있다. 이는 서버에서 페이지를 렌더링할 때 이미지 리소스가 완전히 준비되지 않아, 사용자가 페이지에 진입했을 때 이미지가 점진적으로 로드되기 때문이다.
이 문제를 해결하기 위해서 저는 3가지 방법을 이용하여 해결해보았습니다.
첫 번째로, 해당 상세 페이지를 ISR(Incremental Static Regeneration)로 전환해 정적으로 미리 생성해두었습니다.
이렇게 하면 서버가 페이지와 이미지를 미리 렌더링해두기 때문에, 사용자가 상세 페이지에 접속했을 때 이미지가 지연 없이 빠르게 표시될 수 있습니다.
상세 페이지를 ISR(Incremental Static Regeneration)로 전환하기 위해 Next.js의 generateStaticParams 함수를 사용하여 빌드 시점에 미리 정적 경로를 생성해주고, 이후에는 설정한 주기마다 백그라운드에서 페이지를 재생성되게 설정을 해주었습니다.
import Image from "next/image";
import { getMeetupProjectDetail, getMeetupProjects } from "@/service/projects";
export async function generateStaticParams() {
const meetupProjectList = await getMeetupProjects("");
return meetupProjectList.data.meetup_list.map((project) => ({
projectNumber: project.meetup_id.toString(),
}));
}
async function ProjectDetailPage({ params }) {
const { projectNumber } = await params;
const { data: project } = await getMeetupProjectDetail(projectNumber);
return (
<div>
{/* ...생략... */}
<Image
src={project.poster_url ?? "/footerLogo.svg"}
alt="포스터"
width={580}
height={820}
style={{ width: "580px", height: "820px" }}
priority
unoptimized
/>
{/* ...생략... */}
</div>
);
}
export default ProjectDetailPage;
또한 이미지 로딩 성능 개선을 위해 Next.js의 Image 컴포넌트를 적극 활용했습니다. 내부 정적 이미지의 경우 빌드 시점에 최적화 및 캐싱이 자동으로 적용되며, 외부 이미지의 경우 첫 접속 시 서버에서 최적화 및 캐싱을 수행합니다. 단, 외부 이미지의 경우 배포 시마다 캐시가 초기화될 수 있으므로 주의가 필요합니다.
특히 주요 콘텐츠(예: 프로젝트 포스터 등)에 대해서는 <Image priority />
옵션을 적용해 지연 로딩을 비활성화하고, 초기 렌더링 시 바로 로드되도록 처리했습니다. 이를 통해 LCP 성능을 더욱 개선하고 사용자 경험을 높였습니다.
<Image
src={project.poster_url}
alt="포스터"
width={580}
height={820}
priority // 이 옵션이 핵심!
/>
Next.js의 Link 컴포넌트는 기본적으로 prefetch가 활성화되어 있어, 뷰포트에 들어오거나 마우스 호버 시 해당 페이지의 리소스를 미리 받아옵니다. 이 기능 덕분에 사용자가 링크를 클릭하기 전에 이미 필요한 데이터를 미리 받아와서, 실제로 페이지를 이동할 때 훨씬 빠른 전환이 가능합니다.
하지만 프로젝트 리스트처럼 한 번에 많은 링크가 렌더링되는 경우,모든 링크에 대해 자동으로 prefetch가 일어나면 네트워크 리소스가 불필요하게 낭비될 수 있다고 생각했습니다. 특히 사용자가 실제로 클릭하지 않을 링크까지 모두 미리 받아오게 되면, 브라우저가 불필요한 데이터를 많이 다운로드하게 되고, 이로 인해 오히려 성능이 저하될 수도 있다고 판단하였습니다.
이런 상황을 방지하기 위해,
그래서 prefetch={false}
로 자동 프리페치를 꺼주고, onMouseEnter
이벤트에서 router.prefetch()
를 직접호출해 "정말 사용자가 관심을 보인(마우스를 올린) 링크"에 대해서만 프리페치가 일어나도록 설정했습니다.
이렇게 하면 네트워크 리소스를 효율적으로 사용할 수 있고, 실제로 사용자가 클릭할 가능성이 높은 링크만 미리 데이터를 받아오게 되어 성능과 UX를 모두 챙길 수 있습니다.
import Link from "next/link";
import { useRouter } from "next/navigation";
function MeetupProjectLink({ project }) {
const router = useRouter();
return (
<Link
href={`/projects/meetup/${project.meetup_id}`}
prefetch={false}
onMouseEnter={() => router.prefetch(`/projects/meetup/${project.meetup_id}`)}
>
{/* 카드 내용 */}
</Link>
);
}
큐시즘 웹사이트는 과거에 모든 콘텐츠를 클라이언트에서 동적으로 생성하는 구조였기 때문에, 검색엔진 최적화(SEO)가 부족해 정보 노출에 한계가 있었습니다. 실제로 크롤러가 주요 정보를 제대로 인식하지 못해 큐시즘의 활동이나 프로젝트가 검색 결과에 잘 노출되지 않는 문제가 있었습니다.
이 문제를 해결하기 위해, 최근에는 각 페이지와 상세 페이지 레이아웃에 메타데이터(metadata) 설정을 꼼꼼하게 적용해보았습니다.
예를 들어, 프로젝트 전체 목록 페이지에서는 아래와 같이 metadata 객체를 선언해 title, description, keywords, openGraph, twitter 카드 등 다양한 정보를 명시적으로 지정했다.
// src/app/projects/layout.tsx
export const metadata: Metadata = {
title: "KUSITMS | Projects",
description: "큐시즘에서 진행한 다양한 프로젝트들을 한눈에 확인해보세요.",
keywords: ["큐시즘", "KUSITMS", "프로젝트", "밋업", "기업", "대학생 IT 학회"],
openGraph: { ... },
twitter: { ... },
};
또한, 프로젝트 상세 페이지의 경우에는 각 프로젝트별로 고유한 메타데이터가 동적으로 생성되도록 아래와 같이 구현했다.
이렇게 하면 각 프로젝트마다 검색 노출이 잘 되도록 할 수 있습니다.
// src/app/projects/meetup/[projectNumber]/layout.tsx
export async function generateMetadata({ params }: Props) {
const { projectNumber } = await params;
const { data: project } = await getMeetupProjectDetail(projectNumber);
return {
title: `KUSITMS | ${project.name}`,
description: `${project.one_line_intro}`,
keywords: [project.name, "KUSITMS", "큐시즘", "밋업", "프로젝트"],
openGraph: { ... },
twitter: { ... },
};
}
이런 메타데이터 설정 덕분에 검색엔진이 각 프로젝트의 정보를 정확하게 인식할 수 있게 되었고, 큐시즘 활동과 프로젝트가 검색 결과에 더 잘 노출되는 효과를 기대할 수 있게 됐다.
여기에 더해, 검색엔진이 사이트 전체를 자유롭게 탐색할 수 있도록 robots.txt 파일도 설정했습니다.
아래와 같이 모든 검색엔진이 사이트 전체를 크롤링할 수 있도록 허용하고, sitemap의 위치도 명시했습니다.
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: "*",
allow: "/",
},
sitemap: "https://www.kusitms.com/sitemap.xml",
};
}
또한, 사이트의 전체 구조와 각 페이지의 URL, 갱신 주기, 우선순위 등을 검색엔진에 알려주기 위해 sitemap.xml도 동적으로 생성했습니다.
특히 동적으로 생성되는 프로젝트 상세 페이지까지 모두 sitemap에 포함시켜, 검색엔진이 모든 프로젝트를 빠짐없이 인덱싱할 수 있도록 해주었습니다.
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const meetupProjectList = await getMeetupProjects("");
const dynamicRoutes = meetupProjectList.data.meetup_list.map((project) => ({
url: `https://www.kusitms.com/projects/meetup/${project.meetup_id}`,
lastModified: new Date(),
changeFrequency: "monthly",
priority: 1,
}));
return [
{ url: "https://www.kusitms.com", ... },
{ url: "https://www.kusitms.com/projects/meetup", ... },
...dynamicRoutes,
];
}
이렇게 메타데이터, robots.txt, sitemap.xml을 체계적으로 설정함으로써, 검색엔진이 큐시즘의 모든 활동과 프로젝트 정보를 정확하게 인식하고, 검색 결과에 더 잘 노출될 수 있도록 개선했습니다.
이로 인해 큐시즘의 온라인 가시성과 접근성이 크게 향상되었습니다.
![]() |
![]() |
![]() |
![]() |
이번 마이그레이션의 핵심 목표 중 하나는 느린 초기 로딩 속도로 인한 사용자 경험 저하를 해결하고, 웹 성능 지표를 개선하는 것이었습니다. 이를 위해 Next.js App Router 기반 SSR 구조를 도입하고, 성능 병목 요소들을 전반적으로 분석 및 개선했습니다.
기존 홈페이지는 클라이언트 사이드 렌더링(CSR) 방식이어서, 사용자가 페이지를 요청하면 빈 HTML만 전달되고 브라우저가 자바스크립트를 모두 다운로드·실행한 뒤에야 실제 콘텐츠가 보였다. 이로 인해 저사양 기기나 느린 네트워크 환경에서는 렌더링 지연이 심각했습니다.
Next.js의 App Router 기반 ISR(Incremental Static Regeneration) 기능을 도입해, 주요 페이지와 상세 페이지를 서버에서 미리 정적으로 생성하도록 했다.
특히 상세 페이지의 경우, generateStaticParams를 활용해 각 프로젝트별로 정적 파일을 미리 만들어두고, 이미지도 서버에서 미리 준비되도록 했습니다.
사용자는 페이지에 진입하자마자 콘텐츠와 이미지를 지연 없이 바로 확인할 수 있게 되었고, LCP(Largest Contentful Paint) 지표가 약 7초에서 1초 이내로 크게 단축되었습니다.
대형 썸네일 이미지나 프로젝트 포스터 등 주요 이미지는 Next.js의 Image
태그에 priority 옵션을 적용해, 지연 로드(lazy loading)를 비활성화하고 서버에서 미리 이미지를 준비하도록 했습니다.
또한, 프로젝트 리스트에서 상세 페이지로 이동할 때는 Link 컴포넌트의 prefetch 동작을 커스터마이즈하여, 마우스 호버 시에만 prefetch가 일어나도록 최적화했습니다.
이렇게 함으로써 네트워크 리소스를 효율적으로 사용하면서도, 실제로 사용자가 클릭할 가능성이 높은 링크에 대해서만 빠른 전환 경험을 제공할 수 있었습니다
초기 렌더링에 필요한 이미지만 빠르게 로딩되고, 불필요한 네트워크 사용이 줄어들어 LCP 및 CLS(Cumulative Layout Shift) 지표가 안정화되었다.
Next.js App Router 구조를 적극 활용해, UI의 대부분을 서버 컴포넌트(Server Component)로 구성하고, 클라이언트 컴포넌트는 필요한 부분에만 선언적으로 분리했다.
또한, 각 페이지와 상세 페이지 레이아웃에 title, description, og:image 등 메타데이터를 동적으로 생성해 SEO를 강화했다.
robots.txt와 sitemap.xml도 직접 구현하여, 검색엔진이 사이트 전체와 동적 상세 페이지까지 빠짐없이 인덱싱할 수 있도록 했다.
번들 크기와 자바스크립트 파싱/실행 시간이 줄어들어 TTI(Time to Interactive)와 FCP(First Contentful Paint)가 개선되었고, 검색엔진에서의 정보 노출과 페이지 품질 평가도 크게 향상되었다.
이러한 성능 및 SEO 개선 노력의 결과, Lighthouse 기준 주요 웹 성능 지표는 전반적으로 ‘Good’ 등급을 획득했으며, 특히 LCP는 약 7초에서 1초 내외로 크게 개선되었다.
실제 사용자 경험의 체감 속도가 높아졌을 뿐만 아니라, 검색엔진에서 큐시즘의 활동과 프로젝트가 더 잘 노출되는 효과도 얻을 수 있었다.
항상 Next.js를 이용하여 프로젝트를 진행하며 아쉬운 점이 있었습니다.
아 이거 이렇게 하면 더 좋게 고칠 수 있을 거 같은데...
내가 짠 구조가 과연 좋은 구조일까?..
등등 다양한 생각들을 하면서 프로젝트를 끝냈어서 아쉬운 점이 많이 남았었는데,
이번 큐시즘 홈페이지를 마이그레이션하면서는 정말 후회 없이 진행했던 거 같습니다.
이 글에서는 전시 탭 구축과 반응형 적용에 대해서는 따로 언급하지 않았지만,
전시 탭은 이미 구축을 끝낸 상태이고, 반응형 작업만 남았습니다.
반응형 작업은 7월에 진행할 예정이라, 나중에 이것도 따로 글로 한 번 정리해보려 합니다.
마지막으로 제 깃허브 남기며 글을 끝내보겠습니다. 긴 글 읽어주셔서 감사합니다.
피드백은 언제나 환영이니 많은 관심과 조언 부탁드리겠습니다.
트러플 슈팅 맛있겠네요..