Using a memory cache in development with NextJS does not seem to be effective

When exporting my pages for my simple static blog site, everything runs smoothly and quickly. However, in development mode, the generation of posts is sluggish and I'm looking to implement caching to speed up the process. I have set up a file called post.ts where I define my cache as const posts: Post[] = [].

I anticipate that when running yarn dev, the post.ts file will be loaded once allowing me to populate and reuse my cached post array. Strangely, this TypeScript module seems to be loaded multiple times.

import fs from 'fs'
import path from 'path'
// ...
​
console.log('????? reloading page')
const posts: Post[] = []  // cached posts, hope to generate once
let postsGenerated = false
​
export async function getSortedPostsData(): Promise<Post[]> {
  // Get file names under /posts
  const pendings: Promise<any>[] = []
  if (postsGenerated) {
    console.log('+++++ Using cache ')
    return sortPostsByDate(posts)
  } else {
    console.log('==== Calculating all')
    postsGenerated = true
  }
  let i = 0
  traverseDir('content/blog', (path) => {
    if (path.includes('.md')) { ... })
  }
      
  await Promise.all(pendings)
  return sortPostsByDate(posts)
}

Despite my efforts, sometimes the cache is utilized while other times it isn't. Even on consecutive reloads of the same page, the cache usage is inconsistent. Why is this happening? And what steps can be taken to improve the reliability of the caching system?

https://i.sstatic.net/kSlWY.png

Answer №1

In my opinion, utilizing dynamic routes along with getStaticPaths and getStaticProps could be a suitable solution for this scenario.

getStaticPaths will scan the existing files and generate corresponding routes, while getStaticProps will retrieve the necessary post content as required. Upon exporting, all data will be fetched and processed accordingly.

Check out this link for more information on static HTML export in Next.js

For details on using getStaticPaths for static generation, refer to this documentation

Answer №2

Fast Refresh functionality can be a bit unpredictable, especially when working with `.ts` files during development. One workaround could be using a file as a cache to store parsed data and persist it across reloads instead of relying solely on constants.

const devPostsCache = 'devPostsCache.json';
export async function getSortedPostsData(): Promise<Post[]> {
  // Retrieving file names under /posts
  const pendings: Promise<any>[] = []
  const postsGenerated = fs.existsSync(devPostsCache);
  if (postsGenerated) {
    const posts = JSON.parse(fs.readFileSync(devPostsCache));
    return sortPostsByDate(posts)
  } else {
    console.log('==== Calculating all')
    postsGenerated = true
  }
  let i = 0
  traverseDir('content/blog', (path) => {
    if (path.includes('.md')) { ... })
  }
  
  // Assuming pending promises fetch an array of post objects
  const parsedPosts = await Promise.all(pendings);
  fs.writeFileSync(devPostsCache, JSON.stringify(parsedPosts));
  return sortPostsByDate(posts)
}

Consider deleting the cache file each time you start development using a `predev` script.

  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "predev": "rm devPostsCache.json"
  },

UPDATE

Another approach to minimize code recompilation frequency is adjusting the onDemandEntries configuration settings.

module.exports = {
  onDemandEntries: {
    // Time interval (in ms) serverside pages are kept in buffer
    maxInactiveAge: 360 * 1000,
    // Number of simultaneous pages kept in memory without disposal
    pagesBufferLength: 10,
  },
}

The default values are currently set at `60 * 1000` for maxInactiveAge and 2 for pagesBufferLength.

Although tweaking webpack configurations was attempted, issues persisted as nextjs tends to recompile everything per request.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The type '{ domain: any; domainDispatch: React.Dispatch<any>; }' cannot be assigned to a type 'string'

Within my codebase, I am encountering an issue with a small file structured as follows: import React, { createContext, useContext, useReducer } from 'react' const initState = '' const DomainContext = createContext(initState) export co ...

Exploring Angular's APP_INITIALIZER: Comparing Promises and Observables

I have implemented an Angular v4 application where I need to retrieve settings from the server before the app starts. This is achieved using the APP_INITIALIZER: { provide: APP_INITIALIZER, useFactory: initializeSettings, deps: [SettingsService], ...

"Alert in Javascript executing prematurely prior to initiating the function for sending a get request

private validateURL(url: string) { let isValid = false; this.$http.get(url).then( (data) => { console.log('success'); isValid = true; } ).catch( (reason) => { console. ...

The client has already received headers, cannot set them again

I encountered an issue on sentry.io concerning this piece of code, specifically stating that I am unable to set headers after they have already been sent to the client. This is within a Next.js application. export async function getServerSideProps(ctx ...

In TypeScript, a generic function with an index constraint

Is it possible to define an element that operates in the manner indicated here? function fn<T, U extends keyof T, T[U] extends number>() I am having trouble making the "T[U] extends number" portion function correctly. ...

Is there a way to pass a form error to the parent component as a parameter in React?

I am just starting to learn React. I have created a form and I want to inform the parent component about any input errors that occur. I attempted to use the variable myError as a prop similar to how I used the next method, but unfortunately, it did not wor ...

Error with React, key must be unique. What's the issue?

What is causing the issue with unique keys? To resolve the problem, ensure that each list item has a unique key. For example, if we have x_values = {'male':[1,2,3], 'female':[2,3,4]} the keys should be : 'mean-male', ' ...

Having trouble importing .task files in a Next.js project with TypeScript?

I encountered an issue when trying to import a model.task file into my App.tsx file. After training a hand gesture recognition model in Python, I exported it to a model.task file. Now, I am attempting to import this file into my Next.js + Typescript proje ...

Generating dynamic content

I require assistance with a programming issue. I am working with two separate components: Stage and Executor. Within the Stage component, I am attempting to create new elements based on input parameters, while in the Executor component, I set these paramet ...

When constructing a parameter, providers are unable to resolve another provider

I am currently working on an Ionic v3 app and I have encountered an issue with resolving providers within two other providers. Below is the error message I received: Uncaught Error: Can't resolve all parameters for DialogueMetier:([object Object], [ ...

Each time a page loads, the react useContext feature is causing the web socket connection to reset

I have integrated websockets into various parts of my nextJS application and need to make sure they are accessible everywhere without resetting the socket connection. Whenever the connection is reset, it loses all the rooms it was connected to, causing iss ...

Export data from Angular Material data table to Excel format

I'm currently utilizing the angular material data table to showcase data in a tabular layout. I have a requirement to add a feature that enables the export of tabular data to an Excel sheet. Unfortunately, I haven't been able to locate any resour ...

Having trouble accessing previously submitted form values in Angular

When I try to update the form, I notice that my meetupform.controls.day array is not retaining the previously selected values app.component.html <div *ngIf="meetupForm.controls.recurring.value==='weekly'"> <mat-checkbox (change)="o ...

Enhance Angular Forms: Style Readonly Fields in Grey and Validate Data Retrieval using Typescript

Is there a way to disable a form and make it greyed out, while still being able to access the values? 1/ Disabling controls with this.roleForm.controls['id'].disable() in Typescript does not allow me to retrieve the values of Id, Name, and Descr ...

Asynchronous retrieval of reference value from Firebase Firestore in ReactJS

Encountering a peculiar bug in TypeScript-JavaScript where I have a Model class in TypeScript and a ReactJS Component in JS. The issue arises when dealing with a list of Promo Objects, each containing a "_listCompte" property which holds a list of Compte O ...

How to send Multipart form data with a string payload

Many suggestions in regards to this issue recommend utilizing some form of FormData within nodejs for building a multipart form. However, I am seeking to achieve the same result without relying on the FormData library. Instead, I aim to use only request h ...

Determine the Nautical Miles Between Various Coordinate Points using React

Does anyone have a solution for calculating nautical miles using react? Let's say I have this object: const calculateDistance = [ {point_id: 1, long: longitude , lat: latitude}, {point_id: 2, long: longitude , lat: latitude}, {point_id: 3, ...

Firebase Issue in Next JS Authentication Flow: Unconfirmed Email Causes "auth/email-already-in-use" Error to Trigger

I have encountered a perplexing issue while setting up user registration with Firebase Authentication in my Next.js application. The problem arises when I try to register a new user with an unverified email address. Instead of following the correct flow to ...

The function cannot be invoked. The 'Boolean' type does not have any call signatures. An error has occurred in the computed property of Vue3

Currently, I am working on creating a computed property that checks if an item is in the array. The function I have created returns a boolean value and takes one parameter, which is the item to be checked. isSelected: function (item: MediaGalleryItemTypes) ...

What are the steps for implementing the innerClass style on the searchBox within the appBase?

I'm currently incorporating the searchBox component from appbase io into my upcoming js web application, but I've been facing challenges in customizing the layout of both the search box and the list. Despite following the documentation which sug ...