Skip to content

Commit 993aa1a

Browse files
authored
Merge pull request #226 from manNomi/refactor/home-page
Refactor/home page
2 parents 271e2e5 + 928cb74 commit 993aa1a

7 files changed

Lines changed: 184 additions & 235 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import Image from "next/image";
2+
import Link from "next/link";
3+
4+
import { ListUniversity } from "@/types/university";
5+
6+
type PopularUniversityCardProps = {
7+
university: ListUniversity;
8+
priority?: boolean;
9+
loading?: "eager" | "lazy";
10+
fetchPriority?: "high" | "low";
11+
};
12+
13+
const PopularUniversityCard = ({
14+
university,
15+
priority = false,
16+
loading = "lazy",
17+
fetchPriority = "low",
18+
}: PopularUniversityCardProps) => {
19+
return (
20+
<Link key={university.id} href={`/university/${university.id}`}>
21+
<div className="relative w-[153px]">
22+
<div className="relative h-[120px] w-[153px] overflow-hidden rounded-lg bg-gray-200">
23+
<Image
24+
className="h-[120px] rounded-lg object-cover"
25+
src={
26+
university.backgroundImageUrl
27+
? `${process.env.NEXT_PUBLIC_IMAGE_URL}/${university.backgroundImageUrl}`
28+
: "/images/default-university.jpg"
29+
}
30+
width={153}
31+
height={120}
32+
alt={`${university.koreanName || "대학교"} 배경 이미지`}
33+
priority={priority}
34+
loading={loading}
35+
fetchPriority={fetchPriority}
36+
sizes="153px"
37+
placeholder={!priority ? "blur" : undefined}
38+
blurDataURL={
39+
!priority
40+
? "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAIAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAv/xAAhEAACAQMDBQAAAAAAAAAAAAABAgMABAUGIWGRkrHB0f/EABUBAQEAAAAAAAAAAAAAAAAAAAMF/8QAGhEAAgIDAAAAAAAAAAAAAAAAAAECEgMRkf/aAAwDAQACEQMRAD8AltJagyeH0AthI5xdrLcNM91BF5pX2HaH9bcfaSXWGaRmknyJckliyjqTzSlT54b6bk+h0R//2Q=="
41+
: undefined
42+
}
43+
unoptimized={false}
44+
/>
45+
</div>
46+
<div className="absolute bottom-[9px] left-[10px] z-10 text-sm font-semibold leading-[160%] tracking-[0.15px] text-white">
47+
{university.koreanName}
48+
</div>
49+
</div>
50+
</Link>
51+
);
52+
};
53+
54+
export default PopularUniversityCard;
Lines changed: 32 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
1-
import Image from "next/image";
2-
import Link from "next/link";
1+
import dynamic from "next/dynamic";
32
import { Suspense } from "react";
43

4+
import PopularUniversityCard from "./_ui/PopularUniversityCard";
5+
56
import { ListUniversity } from "@/types/university";
67

8+
// PopularUniversityCard를 동적 임포트
9+
const PopularUniversityCardDynamic = dynamic(() => import("./_ui/PopularUniversityCard"), {
10+
ssr: false,
11+
loading: () => (
12+
<div className="relative w-[153px]">
13+
<div className="h-[120px] w-[153px] animate-pulse rounded-lg bg-gray-200" />
14+
</div>
15+
),
16+
});
17+
718
type PopularUniversitySectionProps = {
819
universities: ListUniversity[];
920
};
@@ -17,78 +28,31 @@ const PopularUniversitySection = ({ universities }: PopularUniversitySectionProp
1728
<div className="flex gap-2">
1829
{/* 첫 3장은 즉시 전송 – LCP 후보 */}
1930
{aboveFold.map((university, index) => (
20-
<Link key={university.id} href={`/university/${university.id}`}>
21-
<div className="relative w-[153px]">
22-
<div className="relative h-[120px] w-[153px] overflow-hidden rounded-lg bg-gray-200">
23-
<Image
24-
className="h-[120px] rounded-lg object-cover"
25-
src={
26-
university.backgroundImageUrl
27-
? `${process.env.NEXT_PUBLIC_IMAGE_URL}/${university.backgroundImageUrl}`
28-
: "/images/default-university.jpg"
29-
}
30-
width={153}
31-
height={120}
32-
alt={`${university.koreanName || "대학교"} 배경 이미지`}
33-
priority={index === 0}
34-
loading={index === 0 ? "eager" : "lazy"}
35-
fetchPriority={index === 0 ? "high" : "low"}
36-
sizes="153px"
37-
unoptimized={false}
38-
/>
39-
</div>
40-
<div className="absolute bottom-[9px] left-[10px] z-10 text-sm font-semibold leading-[160%] tracking-[0.15px] text-white">
41-
{university.koreanName}
42-
</div>
43-
</div>
44-
</Link>
31+
<PopularUniversityCard
32+
priority={index === 0} // 첫 번째만 priority
33+
loading="eager" // 즉시 로딩
34+
fetchPriority="high" // 높은 우선순위
35+
key={university.id}
36+
university={university}
37+
/>
4538
))}
4639

47-
{/* 나머지는 뒤늦게 HTML 스트림으로 전송 */}
48-
{belowFold.length > 0 && (
49-
<Suspense fallback={null}>
50-
<PopularUniversitiesBelowFold universities={belowFold} />
40+
{/* 나머지는 동적 렌더링으로 위임 */}
41+
{belowFold.map((university) => (
42+
<Suspense
43+
key={university.id}
44+
fallback={
45+
<div className="relative w-[153px]">
46+
<div className="h-[120px] w-[153px] animate-pulse rounded-lg bg-gray-200" />
47+
</div>
48+
}
49+
>
50+
<PopularUniversityCardDynamic university={university} priority={false} loading="lazy" fetchPriority="low" />
5151
</Suspense>
52-
)}
52+
))}
5353
</div>
5454
</div>
5555
);
5656
};
5757

58-
const PopularUniversitiesBelowFold = ({ universities }: { universities: ListUniversity[] }) => {
59-
return (
60-
<>
61-
{universities.map((university) => (
62-
<Link key={university.id} href={`/university/${university.id}`}>
63-
<div className="relative w-[153px]">
64-
<div className="relative h-[120px] w-[153px] overflow-hidden rounded-lg bg-gray-200">
65-
<Image
66-
className="h-[120px] rounded-lg object-cover"
67-
src={
68-
university.backgroundImageUrl
69-
? `${process.env.NEXT_PUBLIC_IMAGE_URL}/${university.backgroundImageUrl}`
70-
: "/images/default-university.jpg"
71-
}
72-
width={153}
73-
height={120}
74-
alt={`${university.koreanName || "대학교"} 배경 이미지`}
75-
priority={false}
76-
loading="lazy"
77-
fetchPriority="low"
78-
sizes="153px"
79-
placeholder="blur"
80-
blurDataURL="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAIAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAv/xAAhEAACAQMDBQAAAAAAAAAAAAABAgMABAUGIWGRkrHB0f/EABUBAQEAAAAAAAAAAAAAAAAAAAMF/8QAGhEAAgIDAAAAAAAAAAAAAAAAAAECEgMRkf/aAAwDAQACEQMRAD8AltJagyeH0AthI5xdrLcNM91BF5pX2HaH9bcfaSXWGaRmknyJckliyjqTzSlT54b6bk+h0R//2Q=="
81-
unoptimized={false}
82-
/>
83-
</div>
84-
<div className="absolute bottom-[9px] left-[10px] z-10 text-sm font-semibold leading-[160%] tracking-[0.15px] text-white">
85-
{university.koreanName}
86-
</div>
87-
</div>
88-
</Link>
89-
))}
90-
</>
91-
);
92-
};
93-
9458
export default PopularUniversitySection;

src/app/(home)/head.tsx

Lines changed: 0 additions & 48 deletions
This file was deleted.

src/app/(home)/index.tsx

Lines changed: 0 additions & 88 deletions
This file was deleted.

src/app/(home)/layout.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import TopLogoBar from "@/components/ui/TopLogoBar";
2+
3+
interface HomeLayoutProps {
4+
children: React.ReactNode;
5+
}
6+
7+
const HomeLayout = ({ children }: HomeLayoutProps) => {
8+
return (
9+
<>
10+
<TopLogoBar />
11+
{children}
12+
</>
13+
);
14+
};
15+
16+
export default HomeLayout;

0 commit comments

Comments
 (0)