From 898268fd5d44ecff095f4499ef15eb5fa4b8a89a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20Zag=C3=B3rski?= Date: Thu, 12 Sep 2024 11:19:26 +0200 Subject: [PATCH] use weak map and refactor --- .../react-ui/src/hooks/useImperativeIntl.js | 55 ++++++++++--------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/packages/react-ui/src/hooks/useImperativeIntl.js b/packages/react-ui/src/hooks/useImperativeIntl.js index ecec5a493..73bf686af 100644 --- a/packages/react-ui/src/hooks/useImperativeIntl.js +++ b/packages/react-ui/src/hooks/useImperativeIntl.js @@ -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); }