feat: performance improvements

This commit is contained in:
Linus Flood
2024-11-05 12:53:57 +01:00
parent 249a5f6cb8
commit 7e4bbfb3e6
8 changed files with 290 additions and 300 deletions

View File

@@ -69,7 +69,6 @@ export default async function StepPage({
const hotelData = await getHotelData({
hotelId,
language: lang,
include: [HotelIncludeEnum.RoomCategories],
})
const roomAvailability = await getSelectedRoomAvailability({
hotelId,

View File

@@ -61,7 +61,6 @@ export default async function SelectRatePage({
serverClient().hotel.hotelData.get({
hotelId: searchParams.hotel,
language: params.lang,
include: [HotelIncludeEnum.RoomCategories],
}),
serverClient().hotel.availability.rooms({
hotelId: parseInt(searchParams.hotel, 10),

View File

@@ -31,9 +31,7 @@ export default async function HotelPage() {
const lang = getLang()
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID
const hotelData = await serverClient().hotel.get({
include: ["RoomCategories"],
})
const hotelData = await serverClient().hotel.get()
if (!hotelData) {
return null
}

View File

@@ -1,4 +1,4 @@
import { serverClient } from "@/lib/trpc/server"
import { getCurrentFooter } from "@/lib/trpc/memoizedRequests"
import Image from "@/components/Image"
import { getLang } from "@/i18n/serverContext"
@@ -8,9 +8,7 @@ import Navigation from "./Navigation"
import styles from "./footer.module.css"
export default async function Footer() {
const footerData = await serverClient().contentstack.base.currentFooter({
lang: getLang(),
})
const footerData = await getCurrentFooter(getLang())
if (!footerData) {
return null
}

View File

@@ -61,18 +61,15 @@ export const getHotelData = cache(async function getMemoizedHotelData({
hotelId,
language,
isCardOnlyPayment,
include,
}: {
hotelId: string
language: string
isCardOnlyPayment?: boolean
include?: HotelIncludeEnum[]
}) {
return serverClient().hotel.hotelData.get({
hotelId,
language,
isCardOnlyPayment,
include,
})
})
@@ -120,6 +117,12 @@ export const getCurrentHeader = cache(async function getMemoizedCurrentHeader(
return serverClient().contentstack.base.currentHeader({ lang })
})
export const getCurrentFooter = cache(async function getMemoizedCurrentFooter(
lang: Lang
) {
return serverClient().contentstack.base.currentFooter({ lang })
})
export const getMyPagesNavigation = cache(
async function getMemoizedMyPagesNavigation() {
return serverClient().contentstack.myPages.navigation.get()

View File

@@ -1,4 +1,5 @@
import { metrics } from "@opentelemetry/api"
import { cache } from "react"
import {
MembershipLevel,
@@ -42,7 +43,7 @@ const getByLevelLoyaltyLevelFailCounter = meter.createCounter(
"trpc.contentstack.loyaltyLevel.byLevel-fail"
)
export async function getAllLoyaltyLevels(ctx: Context) {
export const getAllLoyaltyLevels = cache(async (ctx: Context) => {
getAllLoyaltyLevelCounter.add(1)
// Ideally we should fetch all available tiers from API, but since they
@@ -95,9 +96,10 @@ export async function getAllLoyaltyLevels(ctx: Context) {
getAllLoyaltyLevelSuccessCounter.add(1)
return validatedLoyaltyLevels.data
}
})
export async function getLoyaltyLevel(ctx: Context, level_id: MembershipLevel) {
export const getLoyaltyLevel = cache(
async (ctx: Context, level_id: MembershipLevel) => {
getByLevelLoyaltyLevelCounter.add(1, {
query: JSON.stringify({ lang: ctx.lang, level_id }),
})
@@ -146,7 +148,8 @@ export async function getLoyaltyLevel(ctx: Context, level_id: MembershipLevel) {
getByLevelLoyaltyLevelSuccessCounter.add(1)
return validatedLoyaltyLevels.data[0]
}
}
)
export const loyaltyLevelQueryRouter = router({
byLevel: contentstackBaseProcedure

View File

@@ -1,11 +1,5 @@
import { z } from "zod"
export const getHotelInputSchema = z.object({
include: z
.array(z.enum(["RoomCategories", "NearbyHotels", "Restaurants", "City"]))
.optional(),
})
export const getHotelsAvailabilityInputSchema = z.object({
cityId: z.string(),
roomStayStartDate: z.string(),
@@ -54,18 +48,17 @@ export const getRatesInputSchema = z.object({
hotelId: z.string(),
})
export enum HotelIncludeEnum {
export const HotelIncludeEnum = z.enum([
"RoomCategories",
"NearbyHotels",
"Restaurants",
"City",
}
])
export const getHotelDataInputSchema = z.object({
hotelId: z.string(),
language: z.string(),
isCardOnlyPayment: z.boolean().optional(),
include: z.array(z.nativeEnum(HotelIncludeEnum)).optional(),
})
export type HotelDataInput = z.input<typeof getHotelDataInputSchema>

View File

@@ -1,4 +1,5 @@
import { metrics } from "@opentelemetry/api"
import { cache } from "react"
import { Lang } from "@/constants/languages"
import * as api from "@/lib/api"
@@ -34,7 +35,6 @@ import {
import {
getBreakfastPackageInputSchema,
getHotelDataInputSchema,
getHotelInputSchema,
getHotelsAvailabilityInputSchema,
getRatesInputSchema,
getRoomsAvailabilityInputSchema,
@@ -165,25 +165,20 @@ async function getContentstackData(lang: Lang, uid?: string | null) {
return hotelPageData.data.hotel_page
}
export async function getHotelData(
input: HotelDataInput,
serviceToken: string
) {
const { hotelId, language, include, isCardOnlyPayment } = input
export const getHotelData = cache(
async (input: HotelDataInput, serviceToken: string) => {
const { hotelId, language, isCardOnlyPayment } = input
const params: Record<string, string> = {
hotelId,
language,
}
if (include) {
params.include = include.join(",")
}
params.include = HotelIncludeEnum.options.join(",")
getHotelCounter.add(1, {
hotelId,
language,
include,
})
console.info(
"api.hotels.hotelData start",
@@ -196,6 +191,12 @@ export async function getHotelData(
headers: {
Authorization: `Bearer ${serviceToken}`,
},
// needs to clear default option as only
// cache or next.revalidate is permitted
cache: undefined,
next: {
revalidate: 60 * 30, // 30 minutes
},
},
params
)
@@ -205,7 +206,6 @@ export async function getHotelData(
getHotelFailCounter.add(1, {
hotelId,
language,
include,
error_type: "http_error",
error: JSON.stringify({
status: apiResponse.status,
@@ -234,7 +234,6 @@ export async function getHotelData(
getHotelFailCounter.add(1, {
hotelId,
language,
include,
error_type: "validation_error",
error: JSON.stringify(validateHotelData.error),
})
@@ -252,7 +251,6 @@ export async function getHotelData(
getHotelSuccessCounter.add(1, {
hotelId,
language,
include,
})
console.info(
"api.hotels.hotelData success",
@@ -267,14 +265,12 @@ export async function getHotelData(
}
return validateHotelData.data
}
}
)
export const hotelQueryRouter = router({
get: contentStackUidWithServiceProcedure
.input(getHotelInputSchema)
.query(async ({ ctx, input }) => {
get: contentStackUidWithServiceProcedure.query(async ({ ctx }) => {
const { lang, uid } = ctx
const { include } = input
const contentstackData = await getContentstackData(lang, uid)
const hotelId = contentstackData?.hotel_page_id
@@ -289,11 +285,9 @@ export const hotelQueryRouter = router({
language: apiLang,
}
if (include) {
params.include = include.join(",")
}
params.include = HotelIncludeEnum.options.join(",")
getHotelCounter.add(1, { hotelId, lang, include })
getHotelCounter.add(1, { hotelId, lang })
console.info(
"api.hotels.hotel start",
JSON.stringify({
@@ -306,6 +300,12 @@ export const hotelQueryRouter = router({
headers: {
Authorization: `Bearer ${ctx.serviceToken}`,
},
// needs to clear default option as only
// cache or next.revalidate is permitted
cache: undefined,
next: {
revalidate: 60 * 30, // 30 minutes
},
},
params
)
@@ -315,7 +315,6 @@ export const hotelQueryRouter = router({
getHotelFailCounter.add(1, {
hotelId,
lang,
include,
error_type: "http_error",
error: JSON.stringify({
status: apiResponse.status,
@@ -343,7 +342,6 @@ export const hotelQueryRouter = router({
getHotelFailCounter.add(1, {
hotelId,
lang,
include,
error_type: "validation_error",
error: JSON.stringify(validatedHotelData.error),
})
@@ -387,7 +385,7 @@ export const hotelQueryRouter = router({
},
]
getHotelSuccessCounter.add(1, { hotelId, lang, include })
getHotelSuccessCounter.add(1, { hotelId, lang })
console.info(
"api.hotels.hotel success",
JSON.stringify({
@@ -773,7 +771,6 @@ export const hotelQueryRouter = router({
{
hotelId,
language: ctx.lang,
include: [HotelIncludeEnum.RoomCategories],
},
ctx.serviceToken
)