Problem
While we were analysing the latest traces from Jason, we realised that there's substantial amount of time spent in formatjs and date-fns-tz. We also double-checked this with our heavy accounts (~15k reports) and we got the same results. Following is how things look like on baseline:
Baseline

snapshot from profile

Solution:
While analysing the traces, we curated a list of places that can be improved in formatjs and date-fns-tz. Two noticeable items are BestFitMatcher from formatjs and getDateTimeFormat from date-fns-tz. Now, since these are third party libraries, we can bump them to the latest versions and see if they are already fixing performance related issues. We compared the code for BestFitMatcher from the currently installed version formatjs/intl-locale@3.3.0 with formatjs/intl-locale@4.0.0 and there was a significant refactor of this file.
So it only made sense to bump formatjs libraries to the latest to get the performance improvements out of the box. For date-fns-tz there was no significant updates to getDateTimeFormat function, so to apply the improvements we have two options:
- Patch
date-fns-tz
- Upstream
date-fns-tz by creating a PR to it's repository
However, we don't know how long it would take for option 2 as it depends on the reviewer of that repo. We can maybe move forward by mixing both options and removing the patch, once our PR is merged and available on NPM.
The improvement for getDateTImeFormat is pretty simple. We have Intl.DateTimeFormat being re-initialised every time getDateTimeFormat is invoked. Since testDateFormatted is a static variable, we can move it outside of the function.
var dtfCache = {};
// Moved this out from `getDateTimeFormat`
var testDateFormatted = new Intl.DateTimeFormat('en-US', {
hour12: false,
timeZone: 'America/New_York',
year: 'numeric',
month: 'numeric',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
}).format(new Date('2014-06-25T04:00:00.123Z'));
var hourCycleSupported = testDateFormatted === '06/25/2014, 00:00:00' || testDateFormatted === '06/25/2014 00:00:00';
function getDateTimeFormat(timeZone) {
...someImplementation
return dtfCache[timeZone];
}
Below is how things look like after formatjs version bumps and date-fns-tz patch:

snapshot from profile

To summarise;
- Bump
formatjs libraries to the latest
- Patch or Upstream
date-fns-tz with the changes described above
Problem
While we were analysing the latest traces from Jason, we realised that there's substantial amount of time spent in
formatjsanddate-fns-tz. We also double-checked this with our heavy accounts (~15k reports) and we got the same results. Following is how things look like on baseline:snapshot from profile
Solution:
While analysing the traces, we curated a list of places that can be improved in
formatjsanddate-fns-tz. Two noticeable items areBestFitMatcherfromformatjsandgetDateTimeFormatfromdate-fns-tz. Now, since these are third party libraries, we can bump them to the latest versions and see if they are already fixing performance related issues. We compared the code forBestFitMatcherfrom the currently installed versionformatjs/intl-locale@3.3.0withformatjs/intl-locale@4.0.0and there was a significant refactor of this file.So it only made sense to bump
formatjslibraries to the latest to get the performance improvements out of the box. Fordate-fns-tzthere was no significant updates togetDateTimeFormatfunction, so to apply the improvements we have two options:date-fns-tzdate-fns-tzby creating a PR to it's repositoryHowever, we don't know how long it would take for option 2 as it depends on the reviewer of that repo. We can maybe move forward by mixing both options and removing the patch, once our PR is merged and available on NPM.
The improvement for
getDateTImeFormatis pretty simple. We haveIntl.DateTimeFormatbeing re-initialised every timegetDateTimeFormatis invoked. SincetestDateFormattedis a static variable, we can move it outside of the function.Below is how things look like after
formatjsversion bumps anddate-fns-tzpatch:snapshot from profile
To summarise;
formatjslibraries to the latestdate-fns-tzwith the changes described above