Skip to content

[HOLD for payment 2024-09-23] Performance Improvement: Update formatjs libraries and upstream/patch date-fns-tz #47988

Description

@hurali97

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

Screenshot 2024-08-26 at 12 47 42 PM

snapshot from profile

Screenshot 2024-08-26 at 12 41 31 PM

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:

Screenshot 2024-08-26 at 1 03 06 PM

snapshot from profile

Screenshot 2024-08-26 at 12 42 15 PM


To summarise;

  • Bump formatjs libraries to the latest
  • Patch or Upstream date-fns-tz with the changes described above

Metadata

Metadata

Labels

AutoAssignerNewDotQualityUsed to assign quality issues to engineersAwaiting PaymentAuto-added when associated PR is deployed to productionBugSomething is broken. Auto assigns a BugZero manager.DailyKSv2

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions