Commit 9b1903df authored by Zach Pomerantz's avatar Zach Pomerantz Committed by GitHub

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
parent ba9ff0df
...@@ -4,8 +4,6 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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] ...@@ -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': 'العربية',
......
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 = { ...@@ -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) ...@@ -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 @@ ...@@ -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"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment