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
This commit is contained in:
Zach Pomerantz 2021-09-21 12:20:53 -07:00 committed by GitHub
parent ba9ff0dfa5
commit 9b1903df77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 8 additions and 24 deletions

2
.gitignore vendored

@ -4,8 +4,6 @@
/src/types/v3 /src/types/v3
/src/abis/types /src/abis/types
/src/locales/**/*.js /src/locales/**/*.js
/src/locales/**/*.ts
/src/locales/**/*.json
/src/locales/**/en-US.po /src/locales/**/en-US.po
/src/state/data/generated.ts /src/state/data/generated.ts

@ -12,7 +12,6 @@
"@graphql-codegen/typescript-operations": "^1.18.2", "@graphql-codegen/typescript-operations": "^1.18.2",
"@graphql-codegen/typescript-rtk-query": "^1.1.1", "@graphql-codegen/typescript-rtk-query": "^1.1.1",
"@lingui/cli": "^3.9.0", "@lingui/cli": "^3.9.0",
"@lingui/loader": "^3.9.0",
"@lingui/macro": "^3.9.0", "@lingui/macro": "^3.9.0",
"@lingui/react": "^3.9.0", "@lingui/react": "^3.9.0",
"@popperjs/core": "^2.4.4", "@popperjs/core": "^2.4.4",
@ -131,15 +130,16 @@
"compile-contract-types": "yarn compile-external-abi-types && yarn compile-v3-contract-types", "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-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'", "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: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'", "integration-test": "start-server-and-test 'serve build -l 3000' http://localhost:3000 'cypress run --record'",
"graphql:generate": "graphql-codegen --config codegen.yml", "graphql:generate": "graphql-codegen --config codegen.yml",
"postinstall": "yarn compile-contract-types", "postinstall": "yarn compile-contract-types",
"start": "yarn compile-contract-types && react-scripts start", "start": "yarn compile-contract-types && react-scripts start",
"test": "react-scripts test --env=./custom-test-env.js", "test": "react-scripts test --env=./custom-test-env.js",
"prei18n:extract": "touch src/locales/en-US.po", "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": { "eslintConfig": {
"extends": "react-app", "extends": "react-app",

@ -36,6 +36,8 @@ export type SupportedLocale = typeof SUPPORTED_LOCALES[number]
export const DEFAULT_LOCALE: SupportedLocale = 'en-US' export const DEFAULT_LOCALE: SupportedLocale = 'en-US'
export { messages as DEFAULT_MESSAGES } from '../locales/en-US'
export const LOCALE_LABEL: { [locale in SupportedLocale]: string } = { export const LOCALE_LABEL: { [locale in SupportedLocale]: string } = {
'af-ZA': 'Afrikaans', 'af-ZA': 'Afrikaans',
'ar-SA': 'العربية', 'ar-SA': 'العربية',

@ -1,9 +1,9 @@
import { useEffect, useState } from 'react' import { useEffect } from 'react'
import { i18n } from '@lingui/core' import { i18n } from '@lingui/core'
import { I18nProvider } from '@lingui/react' import { I18nProvider } from '@lingui/react'
import { ReactNode } from 'react' import { ReactNode } from 'react'
import { initialLocale, useActiveLocale } from 'hooks/useActiveLocale' import { initialLocale, useActiveLocale } from 'hooks/useActiveLocale'
import { SupportedLocale } from 'constants/locales' import { DEFAULT_LOCALE, DEFAULT_MESSAGES, SupportedLocale } from 'constants/locales'
import { import {
af, af,
ar, ar,
@ -77,8 +77,8 @@ const plurals: LocalePlural = {
} }
async function dynamicActivate(locale: SupportedLocale) { async function dynamicActivate(locale: SupportedLocale) {
const { messages } = await import(`@lingui/loader!./locales/${locale}.po`)
i18n.loadLocaleData(locale, { plurals: () => plurals[locale] }) i18n.loadLocaleData(locale, { plurals: () => plurals[locale] })
const { messages } = locale === DEFAULT_LOCALE ? { messages: DEFAULT_MESSAGES } : await import(`locales/${locale}`)
i18n.load(locale, messages) i18n.load(locale, messages)
i18n.activate(locale) i18n.activate(locale)
} }
@ -88,23 +88,18 @@ dynamicActivate(initialLocale)
export function LanguageProvider({ children }: { children: ReactNode }) { export function LanguageProvider({ children }: { children: ReactNode }) {
const locale = useActiveLocale() const locale = useActiveLocale()
const [, setUserLocale] = useUserLocaleManager() const [, setUserLocale] = useUserLocaleManager()
const [loaded, setLoaded] = useState(false)
useEffect(() => { useEffect(() => {
dynamicActivate(locale) dynamicActivate(locale)
.then(() => { .then(() => {
document.documentElement.setAttribute('lang', locale) document.documentElement.setAttribute('lang', locale)
setUserLocale(locale) // stores the selected locale to persist across sessions setUserLocale(locale) // stores the selected locale to persist across sessions
setLoaded(true)
}) })
.catch((error) => { .catch((error) => {
console.error('Failed to activate locale', locale, error) console.error('Failed to activate locale', locale, error)
}) })
}, [locale, setUserLocale]) }, [locale, setUserLocale])
// prevent the app from rendering with placeholder text before the locale is loaded
if (!loaded) return null
return ( return (
<I18nProvider forceRenderOnLocaleChange={false} i18n={i18n}> <I18nProvider forceRenderOnLocaleChange={false} i18n={i18n}>
{children} {children}

@ -2884,17 +2884,6 @@
make-plural "^6.2.2" make-plural "^6.2.2"
messageformat-parser "^4.1.3" 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": "@lingui/macro@^3.9.0":
version "3.9.0" version "3.9.0"
resolved "https://registry.npmjs.org/@lingui/macro/-/macro-3.9.0.tgz" resolved "https://registry.npmjs.org/@lingui/macro/-/macro-3.9.0.tgz"