Skip to content

Commit d573dca

Browse files
perf(i18n): lazy load translations
1 parent 4d5b67d commit d573dca

File tree

5 files changed

+47
-47
lines changed

5 files changed

+47
-47
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,5 @@ playwright/.cache/
7272
coverage/
7373

7474
dump.rdb
75+
76+
compiled-locales

client/app/lib/components/wrappers/I18nProvider.tsx

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ReactNode, useEffect } from 'react';
1+
import { ReactNode, useEffect, useState } from 'react';
22
import { IntlProvider } from 'react-intl';
33

44
import {
@@ -8,7 +8,7 @@ import {
88
import { useI18nConfig } from 'lib/hooks/session';
99
import moment from 'lib/moment';
1010

11-
import translations from '../../../../build/locales/locales.json';
11+
import LoadingIndicator from '../core/LoadingIndicator';
1212

1313
interface I18nProviderProps {
1414
children: ReactNode;
@@ -17,26 +17,59 @@ interface I18nProviderProps {
1717
const getLocaleWithoutRegionCode = (locale: string): string =>
1818
locale.toLowerCase().split(/[_-]+/)[0];
1919

20-
const getMessages = (locale: string): Record<string, string> | undefined => {
21-
const localeWithoutRegionCode = getLocaleWithoutRegionCode(locale);
22-
23-
return localeWithoutRegionCode !== DEFAULT_LOCALE
24-
? translations[localeWithoutRegionCode] || translations[locale]
25-
: undefined;
26-
};
27-
2820
const I18nProvider = (props: I18nProviderProps): JSX.Element => {
2921
const { locale, timeZone } = useI18nConfig();
22+
const [messages, setMessages] = useState<Record<string, string>>();
3023

3124
useEffect(() => {
3225
moment.tz.setDefault(timeZone?.trim() || DEFAULT_TIME_ZONE);
3326
}, [timeZone]);
3427

28+
const localeWithoutRegionCode = getLocaleWithoutRegionCode(locale);
29+
30+
useEffect(() => {
31+
setMessages(undefined);
32+
33+
let ignore = false;
34+
35+
(async (): Promise<void> => {
36+
let loadedMessages: Record<string, string>;
37+
38+
try {
39+
loadedMessages = await import(
40+
`../../../../compiled-locales/${localeWithoutRegionCode}.json`
41+
);
42+
} catch (error) {
43+
if (
44+
!(
45+
error instanceof Error &&
46+
error.message.includes('Cannot find module')
47+
)
48+
)
49+
throw error;
50+
51+
loadedMessages = await import(
52+
`../../../../compiled-locales/${DEFAULT_LOCALE}.json`
53+
);
54+
}
55+
56+
if (ignore) return;
57+
58+
setMessages(loadedMessages);
59+
})();
60+
61+
return () => {
62+
ignore = true;
63+
};
64+
}, [localeWithoutRegionCode]);
65+
66+
if (!messages) return <LoadingIndicator />;
67+
3568
return (
3669
<IntlProvider
3770
defaultLocale={DEFAULT_LOCALE}
3871
locale={locale}
39-
messages={getMessages(locale)}
72+
messages={messages}
4073
textComponent="span"
4174
>
4275
{props.children}

client/package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"build:production": "export NODE_ENV=production && yarn run build:translations && webpack --node-env=production --config webpack.prod.js",
1414
"build:development": "yarn run build:translations && webpack serve --config webpack.dev.js",
1515
"build:profile": "yarn run build:translations && webpack serve --config webpack.profile.js --progress=profile",
16-
"build:translations": "babel-node scripts/aggregate-translations.js",
16+
"build:translations": "formatjs compile-folder --ast locales compiled-locales",
1717
"extract-translations": "formatjs extract \"app/**/*.{js,jsx,ts,tsx}\" --ignore='**/*.d.ts' --out-file ./locales/en.json",
1818
"lint-src": "eslint . --ext .js --ext .jsx --ext .ts --ext .tsx --cache --ignore-pattern '**/__test__/**' --ignore-pattern 'coverage/**'",
1919
"lint-tests": "eslint . --ext .test.js --ext .test.jsx --ext .test.ts --ext .test.tsx --cache",
@@ -173,14 +173,12 @@
173173
"favicons": "^7.1.4",
174174
"favicons-webpack-plugin": "^6.0.1",
175175
"fork-ts-checker-webpack-plugin": "^9.0.2",
176-
"glob": "^10.3.7",
177176
"html-webpack-plugin": "^5.6.0",
178177
"image-minimizer-webpack-plugin": "^4.1.3",
179178
"jest": "^29.7.0",
180179
"jest-canvas-mock": "^2.5.2",
181180
"jest-environment-jsdom": "^29.7.0",
182181
"jest-localstorage-mock": "^2.4.26",
183-
"mkdirp": "^3.0.1",
184182
"moment-timezone-data-webpack-plugin": "^1.5.1",
185183
"postcss": "^8.4.38",
186184
"postcss-loader": "^8.1.1",

client/scripts/aggregate-translations.js

Lines changed: 0 additions & 28 deletions
This file was deleted.

client/yarn.lock

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8220,11 +8220,6 @@ mkdirp@^1.0.3:
82208220
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
82218221
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
82228222

8223-
mkdirp@^3.0.1:
8224-
version "3.0.1"
8225-
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50"
8226-
integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==
8227-
82288223
moment-timezone-data-webpack-plugin@^1.5.1:
82298224
version "1.5.1"
82308225
resolved "https://registry.yarnpkg.com/moment-timezone-data-webpack-plugin/-/moment-timezone-data-webpack-plugin-1.5.1.tgz#9d35dfd3768db55058e1e809d77a2b64bd6d03a4"

0 commit comments

Comments
 (0)