From 42baf3fe3cdf70c4bce18829706de82dc6e53fd9 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Sat, 16 May 2026 02:14:36 +0200 Subject: [PATCH] =?UTF-8?q?perf(frontend):=20stream=20sidebar=20via=20Susp?= =?UTF-8?q?ense=20=E2=80=94=20feed=20renders=20immediately;=20sidebar=20lo?= =?UTF-8?q?ads=20async?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- thoughts-frontend/app/page.tsx | 49 +++++++------------ .../app/users/[username]/page.tsx | 19 ++----- 2 files changed, 24 insertions(+), 44 deletions(-) diff --git a/thoughts-frontend/app/page.tsx b/thoughts-frontend/app/page.tsx index ebac652..a4dc23a 100644 --- a/thoughts-frontend/app/page.tsx +++ b/thoughts-frontend/app/page.tsx @@ -1,12 +1,6 @@ import type { Metadata } from "next"; import { cookies } from "next/headers"; -import { - getFeed, - getFriends, - getMe, - getTopFriends, - Me, -} from "@/lib/api"; +import { getFeed, getMe, Me } from "@/lib/api"; import { ThoughtForm } from "@/components/thought-form"; import { EmptyState } from "@/components/empty-state"; import { Button } from "@/components/ui/button"; @@ -16,9 +10,10 @@ import { ThoughtThread } from "@/components/thought-thread"; import { buildThoughtThreads } from "@/lib/utils"; import { TopFriends } from "@/components/top-friends"; import { UsersCount } from "@/components/users-count"; - import { PaginationNav } from "@/components/pagination-nav"; import { redirect } from "next/navigation"; +import { Suspense } from "react"; +import { ProfileSkeleton, TagsSkeleton, CountSkeleton } from "@/components/loading-skeleton"; export const metadata: Metadata = { title: "Home", @@ -61,18 +56,26 @@ async function FeedPage({ const { items: allThoughts, totalPages } = feedData!; const thoughtThreads = buildThoughtThreads(allThoughts); - const friends = (await getFriends(token)).users.map((user) => user.username); - const topFriendsData = me - ? await getTopFriends(me.username, token).catch(() => ({ topFriends: [] })) - : { topFriends: [] }; - const shouldDisplayTopFriends = topFriendsData.topFriends.length > 0; + const sidebar = ( + <> + }> + + + }> + + + }> + + + + ); return (
@@ -84,14 +87,7 @@ async function FeedPage({
- - {shouldDisplayTopFriends && ( - - )} - {!shouldDisplayTopFriends && token && friends.length > 0 && ( - - )} - + {sidebar}
@@ -115,14 +111,7 @@ async function FeedPage({
diff --git a/thoughts-frontend/app/users/[username]/page.tsx b/thoughts-frontend/app/users/[username]/page.tsx index bbb4ef1..8e8c30c 100644 --- a/thoughts-frontend/app/users/[username]/page.tsx +++ b/thoughts-frontend/app/users/[username]/page.tsx @@ -5,7 +5,6 @@ import { getMe, getRemoteFollowers, getRemoteFollowing, - getTopFriends, getUserProfile, getUserThoughts, Me, @@ -52,6 +51,8 @@ import { notFound } from "next/navigation"; import { cookies } from "next/headers"; import { FollowButton } from "@/components/follow-button"; import { TopFriends } from "@/components/top-friends"; +import { Suspense } from "react"; +import { ProfileSkeleton } from "@/components/loading-skeleton"; import { buildThoughtThreads } from "@/lib/utils"; import { ThoughtThread } from "@/components/thought-thread"; import { Button } from "@/components/ui/button"; @@ -127,15 +128,6 @@ export default async function ProfilePage({ params }: ProfilePageProps) { const fediverseHandle = user.local && apiDomain ? `@${user.username}@${apiDomain}` : null; - // Show who the profile owner follows (uses the already-fetched followingResult). - const friends = - followingResult.status === "fulfilled" - ? followingResult.value.items.map((u) => u.username) - : []; - - const topFriendsData = await getTopFriends(username, token).catch(() => ({ topFriends: [] })); - const shouldDisplayTopFriends = topFriendsData.topFriends.length > 0; - return (
{user.customCss && ( @@ -252,10 +244,9 @@ export default async function ProfilePage({ params }: ProfilePageProps) {
- {shouldDisplayTopFriends && ( - - )} - {token && } + }> + +