Skip to content
This repository has been archived by the owner on Oct 1, 2024. It is now read-only.

Commit

Permalink
Use @shopify/dates formatDate function and memoize Intl.NumberFormat
Browse files Browse the repository at this point in the history
  • Loading branch information
Neele Barthel committed Feb 24, 2020
1 parent 3f218f3 commit fdd4d85
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 34 deletions.
8 changes: 7 additions & 1 deletion packages/react-i18n/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).

---

<!-- ## [Unreleased] -->
## [Unreleased]

### Fixed

- Fixed memory leaks when server-side rendering for `Intl.DateTimeFormat.format()` and `Intl.NumberFormat.format()` ([#1287](https://github.com/Shopify/quilt/pull/1287))

---

### Fixed

Expand Down
27 changes: 2 additions & 25 deletions packages/react-i18n/src/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
formatDate,
isLessThanOneHourAgo,
isLessThanOneMinuteAgo,
isLessThanOneWeekAgo,
Expand All @@ -7,7 +8,6 @@ import {
isYesterday,
TimeUnit,
} from '@shopify/dates';
import {memoize as memoizeFn} from '@shopify/function-enhancers';
import {memoize} from '@shopify/decorators';
import {languageFromLocale, regionFromLocale} from '@shopify/i18n';

Expand Down Expand Up @@ -61,12 +61,6 @@ const DECIMAL_NOT_SUPPORTED = 'N/A';
const PERIOD = '.';
const DECIMAL_VALUE_FOR_CURRENCIES_WITHOUT_DECIMALS = '00';

const memoizedDateTimeFormatter = memoizeFn(
dateTimeFormatter,
(locale: string, options: Intl.DateTimeFormatOptions = {}) =>
`${locale}${JSON.stringify(options)}`,
);

export class I18n {
readonly locale: string;
readonly pseudolocalize: boolean | string;
Expand Down Expand Up @@ -296,13 +290,6 @@ export class I18n {
const {locale, defaultTimezone} = this;
const {timeZone = defaultTimezone} = options;

// Etc/GMT+12 is not supported in most browsers and there is no equivalent fallback
if (timeZone === 'Etc/GMT+12') {
const adjustedDate = new Date(date.valueOf() - 12 * 60 * 60 * 1000);

return this.formatDate(adjustedDate, {...options, timeZone: 'UTC'});
}

const {style = undefined, ...formatOptions} = options || {};

if (style) {
Expand All @@ -311,10 +298,7 @@ export class I18n {
: this.formatDate(date, {...formatOptions, ...dateStyle[style]});
}

return memoizedDateTimeFormatter(locale, {
timeZone,
...formatOptions,
}).format(date);
return formatDate(date, locale, {...formatOptions, timeZone});
}

ordinal(amount: number) {
Expand Down Expand Up @@ -566,10 +550,3 @@ function isTranslateOptions(
function defaultOnError(error: I18nError) {
throw error;
}

function dateTimeFormatter(
locale: string,
options: Intl.DateTimeFormatOptions = {},
) {
return new Intl.DateTimeFormat(locale, options);
}
21 changes: 13 additions & 8 deletions packages/react-i18n/src/utilities/translate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@ const MISSING_TRANSLATION = Symbol('Missing translation');
const PLURALIZATION_KEY_NAME = 'count';
const SEPARATOR = '.';

const numberFormats = new Map();
export const memoizedNumberFormatter = function(locale, options = {}) {
const key = numberFormatCacheKey(locale, options);
if (numberFormats.has(key)) {
return numberFormats.get(key);
}
const i = new Intl.NumberFormat(locale, options);
numberFormats.set(key, i);
return i;
};

export const PSEUDOTRANSLATE_OPTIONS: PseudotranslateOptions = {
startDelimiter: '{',
endDelimiter: '}',
Expand All @@ -30,19 +41,13 @@ export interface TranslateOptions<Replacements = {}> {
pseudotranslate?: boolean | string;
}

function numberFormatter(
function numberFormatCacheKey(
locale: string,
options: Intl.NumberFormatOptions = {},
) {
return new Intl.NumberFormat(locale, options);
return `${locale}${JSON.stringify(options)}`;
}

export const memoizedNumberFormatter = memoizeFn(
numberFormatter,
(locale: string, options: Intl.NumberFormatOptions = {}) =>
`${locale}${JSON.stringify(options)}`,
);

function pluralRules(locale: string, options: Intl.PluralRulesOptions = {}) {
return new Intl.PluralRules(locale, options);
}
Expand Down

0 comments on commit fdd4d85

Please sign in to comment.