From 9b1903df775d0d2bb9690d68ede43ce26db75cf2 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 21 Sep 2021 12:20:53 -0700 Subject: [PATCH] perf(i18n): bundle default locale with main chunk (#2405) * fix(i18n): do not defer render on locale Do not defer render on locale load. This delays the initial render of the page, effectively delaying to LCP. Lingui allows the page to render with no text while a locale is loading. A fallback locale is only used when loading a locale fails - not while it is pending. * perf(i18n): include default language in initial bundle --- .gitignore | 2 -- package.json | 6 +++--- src/constants/locales.ts | 2 ++ src/i18n.tsx | 11 +++-------- yarn.lock | 11 ----------- 5 files changed, 8 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index d3b5282732..3457d13b38 100644 --- a/.gitignore +++ b/.gitignore @@ -4,8 +4,6 @@ /src/types/v3 /src/abis/types /src/locales/**/*.js -/src/locales/**/*.ts -/src/locales/**/*.json /src/locales/**/en-US.po /src/state/data/generated.ts diff --git a/package.json b/package.json index 679c661f16..82e5fc48bf 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ "@graphql-codegen/typescript-operations": "^1.18.2", "@graphql-codegen/typescript-rtk-query": "^1.1.1", "@lingui/cli": "^3.9.0", - "@lingui/loader": "^3.9.0", "@lingui/macro": "^3.9.0", "@lingui/react": "^3.9.0", "@popperjs/core": "^2.4.4", @@ -131,15 +130,16 @@ "compile-contract-types": "yarn compile-external-abi-types && yarn compile-v3-contract-types", "compile-external-abi-types": "typechain --target ethers-v5 --out-dir src/abis/types './src/abis/**/*.json'", "compile-v3-contract-types": "typechain --target ethers-v5 --out-dir src/types/v3 './node_modules/@uniswap/?(v3-core|v3-periphery)/artifacts/contracts/**/*.json'", - "build": "yarn compile-contract-types && yarn graphql:generate && yarn i18n:extract && react-scripts build", + "build": "yarn compile-contract-types && yarn graphql:generate && yarn i18n:extract && yarn i18n:compile && react-scripts build", "i18n:extract": "lingui extract --locale en-US", + "i18n:compile": "lingui compile", "integration-test": "start-server-and-test 'serve build -l 3000' http://localhost:3000 'cypress run --record'", "graphql:generate": "graphql-codegen --config codegen.yml", "postinstall": "yarn compile-contract-types", "start": "yarn compile-contract-types && react-scripts start", "test": "react-scripts test --env=./custom-test-env.js", "prei18n:extract": "touch src/locales/en-US.po", - "prestart": "yarn graphql:generate && yarn prei18n:extract" + "prestart": "yarn graphql:generate && yarn prei18n:extract && yarn i18n:compile" }, "eslintConfig": { "extends": "react-app", diff --git a/src/constants/locales.ts b/src/constants/locales.ts index cad84e4275..da695f5887 100644 --- a/src/constants/locales.ts +++ b/src/constants/locales.ts @@ -36,6 +36,8 @@ export type SupportedLocale = typeof SUPPORTED_LOCALES[number] export const DEFAULT_LOCALE: SupportedLocale = 'en-US' +export { messages as DEFAULT_MESSAGES } from '../locales/en-US' + export const LOCALE_LABEL: { [locale in SupportedLocale]: string } = { 'af-ZA': 'Afrikaans', 'ar-SA': 'العربية', diff --git a/src/i18n.tsx b/src/i18n.tsx index cdb7c3a8ea..8356752b14 100644 --- a/src/i18n.tsx +++ b/src/i18n.tsx @@ -1,9 +1,9 @@ -import { useEffect, useState } from 'react' +import { useEffect } from 'react' import { i18n } from '@lingui/core' import { I18nProvider } from '@lingui/react' import { ReactNode } from 'react' import { initialLocale, useActiveLocale } from 'hooks/useActiveLocale' -import { SupportedLocale } from 'constants/locales' +import { DEFAULT_LOCALE, DEFAULT_MESSAGES, SupportedLocale } from 'constants/locales' import { af, ar, @@ -77,8 +77,8 @@ const plurals: LocalePlural = { } async function dynamicActivate(locale: SupportedLocale) { - const { messages } = await import(`@lingui/loader!./locales/${locale}.po`) i18n.loadLocaleData(locale, { plurals: () => plurals[locale] }) + const { messages } = locale === DEFAULT_LOCALE ? { messages: DEFAULT_MESSAGES } : await import(`locales/${locale}`) i18n.load(locale, messages) i18n.activate(locale) } @@ -88,23 +88,18 @@ dynamicActivate(initialLocale) export function LanguageProvider({ children }: { children: ReactNode }) { const locale = useActiveLocale() const [, setUserLocale] = useUserLocaleManager() - const [loaded, setLoaded] = useState(false) useEffect(() => { dynamicActivate(locale) .then(() => { document.documentElement.setAttribute('lang', locale) setUserLocale(locale) // stores the selected locale to persist across sessions - setLoaded(true) }) .catch((error) => { console.error('Failed to activate locale', locale, error) }) }, [locale, setUserLocale]) - // prevent the app from rendering with placeholder text before the locale is loaded - if (!loaded) return null - return ( {children} diff --git a/yarn.lock b/yarn.lock index 8af7d29941..cc621472d6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2884,17 +2884,6 @@ make-plural "^6.2.2" messageformat-parser "^4.1.3" -"@lingui/loader@^3.9.0": - version "3.9.0" - resolved "https://registry.npmjs.org/@lingui/loader/-/loader-3.9.0.tgz" - integrity sha512-IczFzbIE4Y4++QcXLUorIduhlJpezsx9f5A+g2UGa9/NJykVuG8YUb0xZuxsMm05wWXLHYXvg1FZWu+uUi7hUg== - dependencies: - "@babel/runtime" "^7.11.2" - "@lingui/cli" "^3.9.0" - "@lingui/conf" "^3.9.0" - loader-utils "^2.0.0" - ramda "^0.27.1" - "@lingui/macro@^3.9.0": version "3.9.0" resolved "https://registry.npmjs.org/@lingui/macro/-/macro-3.9.0.tgz"