From 804f6f69ae85445804bf5eafe092d96ca6755080 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Sat, 6 Jun 2026 15:06:19 +0330 Subject: [PATCH] update optimize --- public/sw.js | 4 -- .../[name]/(Main)/about/hooks/useAboutData.ts | 6 +-- src/app/[name]/(Main)/hooks/useMenuData.ts | 6 ++- src/app/[name]/(Main)/page.tsx | 14 +++++-- src/app/[name]/lib/prefetchMenuPage.ts | 26 +++++++++++++ src/app/[name]/lib/serverMenuFetch.ts | 39 +++++++++++++++++++ src/app/[name]/manifest.webmanifest/route.ts | 10 +---- src/lib/query/getQueryClient.ts | 18 +++++++++ 8 files changed, 103 insertions(+), 20 deletions(-) create mode 100644 src/app/[name]/lib/prefetchMenuPage.ts create mode 100644 src/app/[name]/lib/serverMenuFetch.ts create mode 100644 src/lib/query/getQueryClient.ts diff --git a/public/sw.js b/public/sw.js index 8574449..3ca07ab 100644 --- a/public/sw.js +++ b/public/sw.js @@ -5,7 +5,3 @@ self.addEventListener('install', (event) => { self.addEventListener('activate', (event) => { event.waitUntil(self.clients.claim()); }); - -self.addEventListener('fetch', (event) => { - event.respondWith(fetch(event.request)); -}); diff --git a/src/app/[name]/(Main)/about/hooks/useAboutData.ts b/src/app/[name]/(Main)/about/hooks/useAboutData.ts index dbc577d..6dfd592 100644 --- a/src/app/[name]/(Main)/about/hooks/useAboutData.ts +++ b/src/app/[name]/(Main)/about/hooks/useAboutData.ts @@ -5,7 +5,7 @@ import { useParams } from "next/navigation"; export const useGetAbout = () => { const { name } = useParams<{ name: string }>(); return useQuery({ - queryKey: ["about"], + queryKey: ["about", name], queryFn: () => api.getAbout(name), enabled: !!name, retry: false, @@ -17,7 +17,7 @@ export const useGetAbout = () => { export const useGetReviews = () => { const { name } = useParams<{ name: string }>(); return useQuery({ - queryKey: ["reviews"], + queryKey: ["reviews", name], queryFn: () => api.getReviews(name), enabled: !!name, retry: false, @@ -27,7 +27,7 @@ export const useGetReviews = () => { export const useGetSchedules = () => { const { name } = useParams<{ name: string }>(); return useQuery({ - queryKey: ["schedules"], + queryKey: ["schedules", name], queryFn: () => api.getSchedules(name), enabled: !!name, retry: false, diff --git a/src/app/[name]/(Main)/hooks/useMenuData.ts b/src/app/[name]/(Main)/hooks/useMenuData.ts index 874ccae..dec230e 100644 --- a/src/app/[name]/(Main)/hooks/useMenuData.ts +++ b/src/app/[name]/(Main)/hooks/useMenuData.ts @@ -6,7 +6,7 @@ import { hasAuthToken } from "@/lib/api/func"; export const useGetFoods = () => { const { name } = useParams<{ name: string }>(); return useQuery({ - queryKey: ["menu"], + queryKey: ["menu", name], queryFn: () => api.getFoods(name), enabled: !!name, staleTime: 5 * 60_000, @@ -17,9 +17,11 @@ export const useGetFoods = () => { export const useGetCategories = () => { const { name } = useParams<{ name: string }>(); return useQuery({ - queryKey: ["categories"], + queryKey: ["categories", name], queryFn: () => api.getCategories(name), enabled: !!name, + staleTime: 5 * 60_000, + refetchOnMount: false, }); }; diff --git a/src/app/[name]/(Main)/page.tsx b/src/app/[name]/(Main)/page.tsx index dd4de83..82fc0bf 100644 --- a/src/app/[name]/(Main)/page.tsx +++ b/src/app/[name]/(Main)/page.tsx @@ -1,10 +1,12 @@ import type { Metadata, Viewport } from "next"; +import { dehydrate, HydrationBoundary } from "@tanstack/react-query"; import { notFound } from "next/navigation"; -import { getRestaurant } from "@/app/[name]/lib/getRestaurant"; import { buildRestaurantMetadata, buildRestaurantViewport, } from "@/app/[name]/lib/restaurantMetadata"; +import { prefetchMenuPageData } from "@/app/[name]/lib/prefetchMenuPage"; +import { getQueryClient } from "@/lib/query/getQueryClient"; import MenuIndex from "./components/MenuIndex"; type PageParams = { name: string }; @@ -33,14 +35,20 @@ export default async function Page({ params: Promise; }) { const { name } = await params; + const queryClient = getQueryClient(); try { - await getRestaurant(name); + await prefetchMenuPageData(queryClient, name); } catch (error) { if (error instanceof Error && error.message === "RESTAURANT_NOT_FOUND") { notFound(); } + throw error; } - return ; + return ( + + + + ); } diff --git a/src/app/[name]/lib/prefetchMenuPage.ts b/src/app/[name]/lib/prefetchMenuPage.ts new file mode 100644 index 0000000..48eb405 --- /dev/null +++ b/src/app/[name]/lib/prefetchMenuPage.ts @@ -0,0 +1,26 @@ +import type { QueryClient } from "@tanstack/react-query"; +import { + fetchAboutResponse, + fetchCategoriesResponse, + fetchFoodsResponse, +} from "./serverMenuFetch"; + +export async function prefetchMenuPageData( + queryClient: QueryClient, + name: string, +) { + await Promise.all([ + queryClient.prefetchQuery({ + queryKey: ["about", name], + queryFn: () => fetchAboutResponse(name), + }), + queryClient.prefetchQuery({ + queryKey: ["menu", name], + queryFn: () => fetchFoodsResponse(name), + }), + queryClient.prefetchQuery({ + queryKey: ["categories", name], + queryFn: () => fetchCategoriesResponse(name), + }), + ]); +} diff --git a/src/app/[name]/lib/serverMenuFetch.ts b/src/app/[name]/lib/serverMenuFetch.ts new file mode 100644 index 0000000..942c2d1 --- /dev/null +++ b/src/app/[name]/lib/serverMenuFetch.ts @@ -0,0 +1,39 @@ +import axios from "axios"; +import { API_BASE_URL } from "@/config/const"; +import type { AboutResponse } from "../(Main)/about/types/Types"; +import type { CategoriesResponse, FoodsResponse } from "../(Main)/types/Types"; +import { getRestaurant, RESTAURANT_FETCH_TIMEOUT_MS } from "./getRestaurant"; + +function createServerAxios(slug: string) { + return axios.create({ + baseURL: API_BASE_URL, + headers: { + "Content-Type": "application/json", + "X-SLUG": slug, + }, + timeout: RESTAURANT_FETCH_TIMEOUT_MS, + }); +} + +export async function fetchAboutResponse(slug: string): Promise { + const restaurant = await getRestaurant(slug); + return { success: true, data: restaurant }; +} + +export async function fetchFoodsResponse(slug: string): Promise { + const client = createServerAxios(slug); + const { data } = await client.get( + `/public/foods/restaurant/${slug}`, + ); + return data; +} + +export async function fetchCategoriesResponse( + slug: string, +): Promise { + const client = createServerAxios(slug); + const { data } = await client.get( + `/public/categories/restaurant/${slug}`, + ); + return data; +} diff --git a/src/app/[name]/manifest.webmanifest/route.ts b/src/app/[name]/manifest.webmanifest/route.ts index 9e06752..0919684 100644 --- a/src/app/[name]/manifest.webmanifest/route.ts +++ b/src/app/[name]/manifest.webmanifest/route.ts @@ -47,10 +47,7 @@ export async function GET( return NextResponse.json(manifest, { headers: { "Content-Type": "application/manifest+json", - "Cache-Control": - "no-store, no-cache, must-revalidate, proxy-revalidate", - Pragma: "no-cache", - Expires: "0", + "Cache-Control": "public, max-age=300, stale-while-revalidate=600", }, }); } catch (error) { @@ -79,10 +76,7 @@ export async function GET( return NextResponse.json(manifest, { headers: { "Content-Type": "application/manifest+json", - "Cache-Control": - "no-store, no-cache, must-revalidate, proxy-revalidate", - Pragma: "no-cache", - Expires: "0", + "Cache-Control": "public, max-age=300, stale-while-revalidate=600", }, }); } diff --git a/src/lib/query/getQueryClient.ts b/src/lib/query/getQueryClient.ts new file mode 100644 index 0000000..63a1812 --- /dev/null +++ b/src/lib/query/getQueryClient.ts @@ -0,0 +1,18 @@ +import { QueryClient } from "@tanstack/react-query"; +import { cache } from "react"; + +export const getQueryClient = cache( + () => + new QueryClient({ + defaultOptions: { + queries: { + retry: false, + retryOnMount: false, + staleTime: 5 * 60_000, + }, + mutations: { + retry: false, + }, + }, + }), +);