An Idiosyncratic Blog

⏱ Add delay to a request in ExpressJS

Published on
2 minutes read

I was working on a Next.js app with a custom server, which had an issue around the loading state for a dynamically imported component.

For the uninitiated, a dynamically imported component is split into its own file (or a chunk) and loaded on-demand. This helps in reducing the initial load time of the app, by not loading all the components at the start.

In Next.js, it looks like this:

const component = dynamic(() => import('@/component/SearchEngine'), {
  loading: Loader,
})

Problem was, my internet was too fast to simulate the issue locally. Never heard of fast internet being a problem, right? The Loader was only shown for a very short time, and then disappeared. I needed the loader to show for a longer time, to replicate the issue.

I used the throttling options in dev tools, but that was throttling the entire page and all the requests. It was not a pleasant experience to debug.

So I implemented a middleware that delays the response to a particular request only. This is a very simple middleware, but it works for my use case.

const REQUEST_DELAY = 2000
const RESPONSE_DELAY = 5000
const delayResponse = (req, res, next) => {
  if (THROTTLE_PATHS(req.url)) {
    // Delay request by 2 seconds
    setTimeout(next, REQUEST_DELAY)

    // Delay response completion by 5 seconds
    const endOriginal = res.end
    res.end = (...args) => {
      setTimeout(() => {
        endOriginal.apply(res, args)
      }, RESPONSE_DELAY)
    }
  } else {
    next()
  }
}

I have two setTimeout calls in the middleware. The first one is to delay processing the request by 2 seconds. The second one is to delay the response completion by 5 seconds. THROTTLE_PATHS is a method that has list of URL paths that needs a delayed response.

THROTTLE_PATHS is a very fancy implementation for my use-case. You can get away with a simple if statement.

Adding the middleware is as simple as: app.use(delayResponse).

And that's it! I was able to see the Loader for a longer time, and debugging was a lot easier.