fix: 降低数据库读压并优化去重查询
This commit is contained in:
+42
-9
@@ -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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user