fix: 降低数据库读压并优化去重查询

This commit is contained in:
2026-03-04 19:38:14 +08:00
parent 4f6035f341
commit 9e884ea478
5 changed files with 331 additions and 95 deletions
+42 -9
View File
@@ -1,11 +1,13 @@
import { prisma } from '@/lib/prisma'
import { getTopTags } from '@/hooks/useProjects'
import { Prisma } from '@prisma/client'
import { unstable_cache } from 'next/cache'
const ONE_DAY_MS = 24 * 60 * 60 * 1000
const DEFAULT_RANKING_LIMIT = 6
const DEFAULT_TIMELINE_LIMIT = 8
const DEFAULT_TOP_TAG_LIMIT = 12
const HOME_PAGE_REVALIDATE_SECONDS = 300
export type HomeProjectSummary = {
id: string
@@ -137,22 +139,30 @@ async function getTopStarsProjects(limit: number): Promise<HomeProjectSummary[]>
return projects.map(mapProjectSummary)
}
export async function getHomePageData(): Promise<HomePageData> {
function getLatestProjectsByWindow(
projects: HomeProjectSummary[],
createdAfter: Date,
limit: number
): HomeProjectSummary[] {
return projects
.filter((project) => new Date(project.createdAt) >= createdAfter)
.slice(0, limit)
}
async function buildHomePageData(): Promise<HomePageData> {
const now = Date.now()
const last24Hours = new Date(now - ONE_DAY_MS)
const last7Days = new Date(now - ONE_DAY_MS * 7)
const last30Days = new Date(now - ONE_DAY_MS * 30)
const latestProjectsLimit = Math.max(DEFAULT_RANKING_LIMIT, DEFAULT_TIMELINE_LIMIT)
const [
totalProjects,
newProjects30d,
newProjects7d,
newProjects24h,
latest24h,
latest7d,
latest30d,
latestProjects,
topStars,
timeline,
topTags,
] = await Promise.all([
safeQuery('countTotalProjects', 0, () => prisma.project.count()),
@@ -186,14 +196,28 @@ export async function getHomePageData(): Promise<HomePageData> {
},
})
),
getLatestProjects(DEFAULT_RANKING_LIMIT, last24Hours),
getLatestProjects(DEFAULT_RANKING_LIMIT, last7Days),
getLatestProjects(DEFAULT_RANKING_LIMIT, last30Days),
getLatestProjects(latestProjectsLimit),
getTopStarsProjects(DEFAULT_RANKING_LIMIT),
getLatestProjects(DEFAULT_TIMELINE_LIMIT),
getTopTags(DEFAULT_TOP_TAG_LIMIT),
])
const latest24h = getLatestProjectsByWindow(
latestProjects,
last24Hours,
DEFAULT_RANKING_LIMIT
)
const latest7d = getLatestProjectsByWindow(
latestProjects,
last7Days,
DEFAULT_RANKING_LIMIT
)
const latest30d = getLatestProjectsByWindow(
latestProjects,
last30Days,
DEFAULT_RANKING_LIMIT
)
const timeline = latestProjects.slice(0, DEFAULT_TIMELINE_LIMIT)
return {
overview: {
totalProjects,
@@ -221,3 +245,12 @@ export async function getHomePageData(): Promise<HomePageData> {
timeline,
}
}
const getCachedHomePageData = unstable_cache(buildHomePageData, ['home-page-data:v1'], {
revalidate: HOME_PAGE_REVALIDATE_SECONDS,
tags: ['home-page-data'],
})
export async function getHomePageData(): Promise<HomePageData> {
return getCachedHomePageData()
}