perf: aggregate homepage data and trim frontend loading
This commit is contained in:
@@ -279,10 +279,26 @@ const i18nPayload = JSON.stringify({ locale, messages });
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
|
||||
media="print"
|
||||
onload="this.media='all'"
|
||||
/>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
|
||||
</noscript>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap"
|
||||
rel="stylesheet"
|
||||
media="print"
|
||||
onload="this.media='all'"
|
||||
>
|
||||
<noscript>
|
||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
</noscript>
|
||||
</head>
|
||||
<body class="min-h-screen bg-[var(--bg)] text-[var(--text)] font-sans antialiased">
|
||||
<div class="relative min-h-screen flex flex-col">
|
||||
|
||||
@@ -132,6 +132,14 @@ export interface ApiSiteSettings {
|
||||
paragraph_comments_enabled: boolean;
|
||||
}
|
||||
|
||||
export interface ApiHomePagePayload {
|
||||
site_settings: ApiSiteSettings;
|
||||
posts: ApiPost[];
|
||||
tags: ApiTag[];
|
||||
friend_links: ApiFriendLink[];
|
||||
categories: ApiCategory[];
|
||||
}
|
||||
|
||||
export interface AiSource {
|
||||
slug: string;
|
||||
href: string;
|
||||
@@ -398,8 +406,22 @@ class ApiClient {
|
||||
}
|
||||
|
||||
async getPostBySlug(slug: string): Promise<UiPost | null> {
|
||||
const posts = await this.getPosts();
|
||||
return posts.find(post => post.slug === slug) || null;
|
||||
const response = await fetch(`${this.baseUrl}/posts/slug/${encodeURIComponent(slug)}`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (response.status === 404) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text().catch(() => '');
|
||||
throw new Error(errorText || `API error: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
return normalizePost((await response.json()) as ApiPost);
|
||||
}
|
||||
|
||||
async getComments(
|
||||
@@ -487,6 +509,24 @@ class ApiClient {
|
||||
return normalizeSiteSettings(settings);
|
||||
}
|
||||
|
||||
async getHomePageData(): Promise<{
|
||||
siteSettings: SiteSettings;
|
||||
posts: UiPost[];
|
||||
tags: UiTag[];
|
||||
friendLinks: AppFriendLink[];
|
||||
categories: UiCategory[];
|
||||
}> {
|
||||
const payload = await this.fetch<ApiHomePagePayload>('/site_settings/home');
|
||||
|
||||
return {
|
||||
siteSettings: normalizeSiteSettings(payload.site_settings),
|
||||
posts: payload.posts.map(normalizePost),
|
||||
tags: payload.tags.map(normalizeTag),
|
||||
friendLinks: payload.friend_links.map(normalizeFriendLink),
|
||||
categories: payload.categories.map(normalizeCategory),
|
||||
};
|
||||
}
|
||||
|
||||
async getCategories(): Promise<UiCategory[]> {
|
||||
const categories = await this.fetch<ApiCategory[]>('/categories');
|
||||
return categories.map(normalizeCategory);
|
||||
|
||||
@@ -37,19 +37,13 @@ let apiError: string | null = null;
|
||||
const { locale, t } = getI18n(Astro);
|
||||
|
||||
try {
|
||||
const [settings, posts, rawTags, rawFriendLinks, nextCategories] = await Promise.all([
|
||||
api.getSiteSettings(),
|
||||
api.getPosts(),
|
||||
api.getTags(),
|
||||
api.getFriendLinks(),
|
||||
api.getCategories(),
|
||||
]);
|
||||
const homeData = await api.getHomePageData();
|
||||
|
||||
siteSettings = settings;
|
||||
allPosts = posts;
|
||||
tags = rawTags.map(tag => tag.name);
|
||||
friendLinks = rawFriendLinks.filter(friend => friend.status === 'approved');
|
||||
categories = nextCategories;
|
||||
siteSettings = homeData.siteSettings;
|
||||
allPosts = homeData.posts;
|
||||
tags = homeData.tags.map(tag => tag.name);
|
||||
friendLinks = homeData.friendLinks.filter(friend => friend.status === 'approved');
|
||||
categories = homeData.categories;
|
||||
|
||||
const filteredPosts = allPosts.filter(post => {
|
||||
const normalizedCategory = post.category?.trim().toLowerCase() || '';
|
||||
|
||||
Reference in New Issue
Block a user