@@ -6,6 +6,7 @@ import { CALENDAR_ID, ISO_YEAR, ISO_MONTH, ISO_DAY, CreateSlots, GetSlot, HasSlo
66
77const ArrayIncludes = Array . prototype . includes ;
88const ArrayPrototypePush = Array . prototype . push ;
9+ const IntlDateTimeFormat = globalThis . Intl . DateTimeFormat ;
910const MathAbs = Math . abs ;
1011const MathFloor = Math . floor ;
1112const ObjectAssign = Object . assign ;
@@ -430,19 +431,31 @@ function simpleDateDiff(one, two) {
430431 */
431432const nonIsoHelperBase = {
432433 // The properties and methods below here should be the same for all lunar/lunisolar calendars.
434+ getFormatter ( ) {
435+ // `new Intl.DateTimeFormat()` is amazingly slow and chews up RAM. Per
436+ // https://bugs.chromium.org/p/v8/issues/detail?id=6528#c4, we cache one
437+ // DateTimeFormat instance per calendar. Caching is lazy so we only pay for
438+ // calendars that are used. Note that the nonIsoHelperBase object is spread
439+ // into each each calendar's implementation before any cache is created, so
440+ // each calendar gets its own separate cached formatter.
441+ if ( typeof this . formatter === 'undefined' ) {
442+ this . formatter = new IntlDateTimeFormat ( `en-US-u-ca-${ this . id } ` , {
443+ day : 'numeric' ,
444+ month : 'numeric' ,
445+ year : 'numeric' ,
446+ era : this . eraLength ,
447+ timeZone : 'UTC'
448+ } ) ;
449+ }
450+ return this . formatter ;
451+ } ,
433452 isoToCalendarDate ( isoDate , cache ) {
434453 let { year : isoYear , month : isoMonth , day : isoDay } = isoDate ;
435454 const key = JSON . stringify ( { func : 'isoToCalendarDate' , isoYear, isoMonth, isoDay, id : this . id } ) ;
436455 const cached = cache . get ( key ) ;
437456 if ( cached ) return cached ;
438457
439- const dateTimeFormat = new Intl . DateTimeFormat ( `en-US-u-ca-${ this . id } ` , {
440- day : 'numeric' ,
441- month : 'numeric' ,
442- year : 'numeric' ,
443- era : this . eraLength ,
444- timeZone : 'UTC'
445- } ) ;
458+ const dateTimeFormat = this . getFormatter ( ) ;
446459 let parts , isoString ;
447460 try {
448461 isoString = toUtcIsoDateString ( { isoYear, isoMonth, isoDay } ) ;
@@ -1604,14 +1617,7 @@ const helperChinese = ObjectAssign({}, nonIsoHelperBase, {
16041617 const key = JSON . stringify ( { func : 'getMonthList' , calendarYear, id : this . id } ) ;
16051618 const cached = cache . get ( key ) ;
16061619 if ( cached ) return cached ;
1607- const dateTimeFormat = new Intl . DateTimeFormat ( `en-US-u-ca-${ this . id } ` , {
1608- day : 'numeric' ,
1609- month : 'numeric' ,
1610- year : 'numeric' ,
1611- era : 'short' ,
1612- timeZone : 'UTC'
1613- } ) ;
1614-
1620+ const dateTimeFormat = this . getFormatter ( ) ;
16151621 const getCalendarDate = ( isoYear , daysPastFeb1 ) => {
16161622 const isoStringFeb1 = toUtcIsoDateString ( { isoYear, isoMonth : 2 , isoDay : 1 } ) ;
16171623 const legacyDate = new Date ( isoStringFeb1 ) ;
0 commit comments