Improving SSR Performance
Caching API response in server-side call
If you're using SSR via withTravelokaPage or exporting a getServerSideProps function, you can use cacheOptions options in callAPI function to cache your API response. The cache is stored in memory and valid for all users visiting the page within the same container.
import {
TravelokaPageComponent,
withTravelokaPage,
callAPI,
} from '@traveloka/core';
const Page: TravelokaPageComponent = props => {
return (
<div />
)
};
Page.getInitialProps = async ctx => {
const searchQuery = ctx.query.search as string;
// call API if there's no cache
const response = await callAPI(ctx, {
domain: 'accomContent',
path: '/v1/hotel/autocomplete',
method: 'post',
payload: {
data: {
query: searchQuery,
},
},
cacheOptions: {
key: searchQuery,
// in seconds
maxAge: 1500,
}
});
// store in cache if API returns 2xx
if (res.success) {
const results = res.result.data.geoAreaContent.rows
return {
searchQuery,
results,
}
}
return {
searchQuery,
results: [],
}
}
export default withTravelokaPage(Page);
One way to debug whether your server-side cache is working or not is by using Server-Timing. You'll see that page-data timing takes less time.
Switching the page to SSG
Most of the time, you don't need SSG. You can switch your page to SSG using staticProps helper function. With SSG you don't need to cache your server-side API call, even if it happens on revalidation because the server will cache the HTML response instead. By default, staticProps function instruct next.js to revalidate every 10 minutes (including errors and redirects).
import {
staticProps,
callAPI,
} from '@traveloka/core';
export const getStaticProps = staticProps({
path: '/some/path',
resources: [],
async getStaticProps(ctx) {
const searchQuery = ctx.query.search as string;
// call API if there's no cache
const response = await callAPI(ctx, {
domain: 'accomContent',
path: '/v1/hotel/autocomplete',
method: 'post',
payload: {
data: {
query: searchQuery,
},
},
cacheOptions: {
key: searchQuery,
// in seconds
maxAge: 1500,
}
});
// store in cache if API returns 2xx
if (res.success) {
const results = res.result.data.geoAreaContent.rows
return {
props: {
searchQuery,
results,
}
}
}
return {
props: {
searchQuery,
results: [],
}
}
})
If you want to specify different revalidation time, you can pass revalidate options, or return revalidate field inside getStaticProps method.
export const getStaticProps = staticProps({
// set default revalidation for any getStaticProps response
revalidate: 100,
async getStaticProps(ctx) {
if (something) {
return {
// use 100 revalidate by default
props: {}
}
}
return {
props: {},
// set different revalidate value (defaults to 100)
revalidate: 50
}
}