Skip to content

Commit

Permalink
use weak map and refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
zbigg committed Sep 12, 2024
1 parent 31ab222 commit 95e68a8
Showing 1 changed file with 29 additions and 26 deletions.
55 changes: 29 additions & 26 deletions packages/react-ui/src/hooks/useImperativeIntl.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,40 @@ import {
} from '../localization/localeUtils';

const cache = createIntlCache();
const intlInstanceCache = new WeakMap();

let lastIntlConfig;
let cachedC4rIntl;
const createIntlInstance = (intlConfig) => {
const locale = intlConfig?.locale || DEFAULT_LOCALE;
const messagesLocale = findMatchingMessagesLocale(locale, messages);
const intMessages = {
...(messages[messagesLocale] || {}),
...(intlConfig?.messages || {})
};

const getGloballyCachedIntl = (intlConfig) => {
if (!cachedC4rIntl || lastIntlConfig !== intlConfig) {
// This is very simple cache exploits fact that Intl instance is actually same for most of time
// so we can reuse those maps across several instances of same components
// note, useMemo can't do that globally and flattenMessages over _app_ and c4r is quite costly and would
// be paid for every c4r component mounted.
const locale = intlConfig?.locale || DEFAULT_LOCALE;
const messagesLocale = findMatchingMessagesLocale(locale, messages);
const intMessages = {
...(messages[messagesLocale] || {}),
...(intlConfig?.messages || {})
};
const combinedMessages = flattenMessages(intMessages);
return createIntl(
{
locale,
messages: combinedMessages
},
cache
);
};

const combinedMessages = flattenMessages(intMessages);
cachedC4rIntl = createIntl(
{
locale,
messages: combinedMessages
},
cache
);
lastIntlConfig = intlConfig;
const getGloballyCachedIntl = (intlConfig) => {
// This is very simple cache exploits fact that Intl instance is actually same for most of time
// so we can reuse those maps across several instances of same components
// note, useMemo can't cache accross many that globally and flattenMessages over _app_ and c4r messages is quite costly
// and would be paid for every c4r component mounted.
let cachedInstance = intlInstanceCache.get(intlConfig);
if (cachedInstance) {
return cachedInstance;
}
return cachedC4rIntl;
const newInstance = createIntlInstance(intlConfig);
intlInstanceCache.set(intlConfig, newInstance);
return newInstance;
};

export default function useImperativeIntl(intlConfig) {
// second level cache, in components is just to avoid re-creating the Intl instance if user is rendering many languages in one app
return useMemo(() => getGloballyCachedIntl(intlConfig), [intlConfig]);
return getGloballyCachedIntl(intlConfig);
}

0 comments on commit 95e68a8

Please sign in to comment.