mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-01-09 15:17:59 -05:00
fix(frontend): marketplace page load and caching (#10934)
## Changes 🏗️ ### **Server-Side:** - ✅ **ISR Cache**: Page cached for 60 seconds, served instantly - ✅ **Prefetch**: All API calls made on server, not client - ✅ **Static Generation**: HTML pre-rendered with data - ✅ **Streaming**: Loading states show immediately ### **Client-Side:** - ✅ **No API Calls**: Data hydrated from server cache - ✅ **Fast Hydration**: React Query uses prefetched data - ✅ **Smart Caching**: 60s stale time prevents unnecessary requests - ✅ **Progressive Loading**: Suspense boundaries for better UX ### **🔄 Caching Strategy:** 1. **Server**: ISR cache (60s) → API calls → Static HTML 2. **CDN**: Cached HTML served instantly 3. **Client**: Hydrated data from server → No additional API calls 4. **Background**: ISR regenerates stale pages automatically ### **🎯 Result:** - **First Visit**: Instant HTML + hydrated data (no client API calls) - **Subsequent Visits**: Instant cached page - **Background Updates**: Automatic revalidation every 60s - **Optimal Performance**: Server-side rendering + client-side caching ## Checklist 📋 ### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] Run the app locally - [x] Marketplace page loads are faster ### For configuration changes: None
This commit is contained in:
@@ -5,8 +5,15 @@ import {
|
||||
import { StoreAgentsResponse } from "@/app/api/__generated__/models/storeAgentsResponse";
|
||||
import { CreatorsResponse } from "@/app/api/__generated__/models/creatorsResponse";
|
||||
|
||||
const queryConfig = {
|
||||
staleTime: 60 * 1000, // 60 seconds - match server cache
|
||||
gcTime: 5 * 60 * 1000, // 5 minutes
|
||||
refetchOnWindowFocus: false, // Avoid unnecessary refetches
|
||||
refetchOnMount: false, // Use cached data from server
|
||||
};
|
||||
|
||||
export const useMainMarketplacePage = () => {
|
||||
// Below queries are already fetched on server and hydrated properly in cache, hence these requests are fast
|
||||
// Data is prefetched on server and hydrated, these queries will use cached data
|
||||
const {
|
||||
data: featuredAgents,
|
||||
isLoading: isFeaturedAgentsLoading,
|
||||
@@ -15,6 +22,7 @@ export const useMainMarketplacePage = () => {
|
||||
{ featured: true },
|
||||
{
|
||||
query: {
|
||||
...queryConfig,
|
||||
select: (x) => {
|
||||
return x.data as StoreAgentsResponse;
|
||||
},
|
||||
@@ -33,6 +41,7 @@ export const useMainMarketplacePage = () => {
|
||||
},
|
||||
{
|
||||
query: {
|
||||
...queryConfig,
|
||||
select: (x) => {
|
||||
return x.data as StoreAgentsResponse;
|
||||
},
|
||||
@@ -48,6 +57,7 @@ export const useMainMarketplacePage = () => {
|
||||
{ featured: true, sorted_by: "num_agents" },
|
||||
{
|
||||
query: {
|
||||
...queryConfig,
|
||||
select: (x) => {
|
||||
return x.data as CreatorsResponse;
|
||||
},
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { MainMarketplacePageLoading } from "./components/MainMarketplacePageLoading";
|
||||
|
||||
export default function Loading() {
|
||||
return <MainMarketplacePageLoading />;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Metadata } from "next";
|
||||
import { Suspense } from "react";
|
||||
import {
|
||||
prefetchGetV2ListStoreAgentsQuery,
|
||||
prefetchGetV2ListStoreCreatorsQuery,
|
||||
@@ -6,8 +7,7 @@ import {
|
||||
import { getQueryClient } from "@/lib/react-query/queryClient";
|
||||
import { dehydrate, HydrationBoundary } from "@tanstack/react-query";
|
||||
import { MainMarkeplacePage } from "./components/MainMarketplacePage/MainMarketplacePage";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
import { MainMarketplacePageLoading } from "./components/MainMarketplacePageLoading";
|
||||
|
||||
// FIX: Correct metadata
|
||||
export const metadata: Metadata = {
|
||||
@@ -56,22 +56,45 @@ export const metadata: Metadata = {
|
||||
export default async function MarketplacePage(): Promise<React.ReactElement> {
|
||||
const queryClient = getQueryClient();
|
||||
|
||||
// Prefetch all data on server with proper caching
|
||||
await Promise.all([
|
||||
prefetchGetV2ListStoreAgentsQuery(queryClient, {
|
||||
featured: true,
|
||||
}),
|
||||
prefetchGetV2ListStoreAgentsQuery(queryClient, {
|
||||
sorted_by: "runs",
|
||||
}),
|
||||
prefetchGetV2ListStoreCreatorsQuery(queryClient, {
|
||||
featured: true,
|
||||
sorted_by: "num_agents",
|
||||
}),
|
||||
prefetchGetV2ListStoreAgentsQuery(
|
||||
queryClient,
|
||||
{ featured: true },
|
||||
{
|
||||
query: {
|
||||
staleTime: 60 * 1000, // 60 seconds
|
||||
gcTime: 5 * 60 * 1000, // 5 minutes (formerly cacheTime)
|
||||
},
|
||||
},
|
||||
),
|
||||
prefetchGetV2ListStoreAgentsQuery(
|
||||
queryClient,
|
||||
{ sorted_by: "runs", page_size: 1000 },
|
||||
{
|
||||
query: {
|
||||
staleTime: 60 * 1000, // 60 seconds
|
||||
gcTime: 5 * 60 * 1000, // 5 minutes
|
||||
},
|
||||
},
|
||||
),
|
||||
prefetchGetV2ListStoreCreatorsQuery(
|
||||
queryClient,
|
||||
{ featured: true, sorted_by: "num_agents" },
|
||||
{
|
||||
query: {
|
||||
staleTime: 60 * 1000, // 60 seconds
|
||||
gcTime: 5 * 60 * 1000, // 5 minutes
|
||||
},
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
return (
|
||||
<HydrationBoundary state={dehydrate(queryClient)}>
|
||||
<MainMarkeplacePage />
|
||||
<Suspense fallback={<MainMarketplacePageLoading />}>
|
||||
<MainMarkeplacePage />
|
||||
</Suspense>
|
||||
</HydrationBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user