Search code examples
javascriptnode.jsservice

Slow performance toLocaleString() Node.js update from 12.18.3 to 18.13.0


We have recently updated node.js from version 12.18.3 to version 18.13.0. We run node.js on windows.

We experience a problem with the built-in function toLocaleString() and the problem is that it takes about 10x the time that it used to take earlier. The problem only occurs when we start our API as a service. If it's started in the command prompt and we shoot requests against it, the function's performance is as fast as it where earlier.

We have a function called strDateArr(fd, td) where we can send in a fromdate and todate and the function returns an array with string formatted dates. Example,

let dates = strDateArr("2013-01-31", "2022-12-31")

returns,

["2013-01-31", ..., "2022-12-31"]

The usage of toLocaleString() in our function looks like this.

let relDateStr = relDate.toLocaleString("sv-SE", {
  month: "2-digit",
  year: "numeric",
  day: "2-digit",
});

This might be a cache problem and I really appreciate any help. Thanks in advance.


Solution

  • You should use Intl.DateTimeFormat with its format() method when you want to format large numbers of dates. It usually is faster:

    let formatter = new Intl.DateTimeFormat('sv-SE', {
      month: "2-digit",
      year: "numeric",
      day: "2-digit"
    });
    
    let relDateStr = formatter.format(relDate);
    

    You can run the snippet below for a quick and dirty benchmark:

    let dates = [];
    let options = {
      month: "2-digit",
      year: "numeric",
      day: "2-digit"
    };
    
    for (let i = 0; i < 20 * 365; i++)
      dates.push(new Date(Date.now() - i * 24 * 60 * 60 * 1000));
    
    let t0 = performance.now();
    
    dates.map(date => date.toLocaleString("sv-SE", options));
    
    let t1 = performance.now();
    let formatter = new Intl.DateTimeFormat('sv-SE', options);
    
    dates.map(date => formatter.format(date));
    
    const t2 = performance.now();
    console.log(`toLocaleString() took ${t1 - t0} milliseconds.`);
    console.log(`Intl.DateTimeFormat() took ${t2 - t1} milliseconds.`);