question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Per-locale bundles

See original GitHub issue

Discussion for RFC 003: https://lingui.js.org/rfc/003_per_locale_bundles.html

Introduction from RFC

Per-locale bundles are another build time optimization to reduce size of internationalized JavaScript applications.

Consider this example - we have an internationalized app which loads translation from external file:

// src/Notifications.js
import * as React from "react"
import { setupI18n } from "@lingui/core"
import { I18nProvider } from "@lingui/react"
import { Trans, Plural, date } from "@lingui/macro"

const i18n = setupI18n()
i18n.load("cs", import("./locale/cs/messages.json"))
i18n.activate("cs")

const Notifications = ({ now, count }) => (
   <I18nProvider i18n={i18n}>
      <h1><Trans>Notifications</Trans></h1>

      <p><Trans>Today is {date(now)}</Trans></p>

      <p>
         <Plural
            value={count}
            one={<>You have <strong>#</strong> unread notification</>}
            other={<>You have <strong>#</strong> unread notifications</>}
         />
      </p>
   </I18nProvider>
)

If we generate the production bundle in Engish locale, it will roughly look like this - <Trans> components are removed and formatting components (<Plural> and date()) are replaced with runtime versions:

// build/Notifications.en.js
import * as React from "react"
import { Plural, date } from "@lingui/react"

const Notifications = ({ now, count }) => (
   <div>
      <h1>Notifications</h1>

      <p>Today is {date(now)}</p>

      <p>
         <Plural
            value={count}
            one={<>You have <strong>#</strong> unread notification</>}
            other={<>You have <strong>#</strong> unread notifications</>}
         />
      </p>
   </div>
)

So far the code looks very similar to the original one except the loading of message catalogs is removed completely.

Let’s take a look on other than source locale, for example Czech. The message catalog might look similar to this:

msgid "Notifications"
msgstr "Upozornění"

msgid "Today is {now, date}"
msgstr "Dnes je {now, date}"

msgid ""
"{count, plural, "
"one {You have <0>#</0> unread notification} "
"other {You have <0>#</0> unread notification}}"
msgstr ""
"{count, plural, "
"one {Máte <0>#</0> nepřečtenou zprávu} "
"few {Máte <0>#</0> nepřečtené zprávy} "
"other {Máte <0>#</0> nepřečtených zpráv}}"

If we generate the production bundle for Czech locale, it will look roughly like this - translations are applied at build time. Also, <Plural> has all locale specific plural rules:

// build/Notifications.cs.js
import * as React from "react"
import { Plural, date } from "@lingui/react"

const Notifications = ({ now, count }) => (
   <div>
      <h1>Upozornění</h1>

      <p>Dnes je {date(now)}</p>

      <p>
         <Plural
            value={count}
            one={<>Máte <strong>#</strong> nepřečtenou zprávu</>}
            few={<>Máte <strong>#</strong> nepřečtené zprávy</>}
            other={<>Máte <strong>#</strong> nepřečtené zprávy</>}
         />
      </p>
   </div>
)

Per-locale bundles has zero footprint of internatinalization library - the code looks exactly the same have it would look like when no internationalization was used at all. The remaining runtime layer are utilities for formatting like plurals, dates and number formatting. There’s also no extra request to fetch locale files and no runtime parsing.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:13
  • Comments:47 (42 by maintainers)

github_iconTop GitHub Comments

5reactions
tricoder42commented, May 21, 2019

Care to elaborate? I load a single language bundle on initial app load. If the user changes language, I will load another. Nothing extra is ever getting loaded.

per-locale bundle

function Component() {
   return <span>Ahoj <strong>světe</strong></span>
}

locale agnostic bundle

function Trans({ id, component }) {
   // extra code here
}

const messages = {
   "Hello <0>world</0>": "Ahoj <0>světe</0>"
}

function Component() {
   return <span><Trans id="Hello <0>world</0>" components={{0: <strong />}} /></span>
}

There’re two parts of extra data:

  • constant overhead - localization library itself, ~3-5kb in case of LinguiJS
  • linear overhead - every message is roughly tripled. Once in source code, once as message key in catalog and once more as a translation. That may vary in length, but it has roughly the same length as message key. It could be optimized by minifying the IDs (#139), but there’s still gonna be extra code compared to locale-specific build.

Now the question is what is worse.

2reactions
ScriptedAlchemycommented, Jul 24, 2020

Just a heads up, Module Federation will likely enable per-locale bundling capabilities. Youd have to use the lower-level API, but I think it should be able to do this

Read more comments on GitHub >

github_iconTop Results From Across the Web

Zero-footprint internationalization (i18n) - per-locale bundles : r/reactjs
Hey everyone, last autumn I spoke at React Conf about possible build time optimization for internationalized apps using per-locale bundles. I finally…
Read more >
JMSI18nRoutingBundle Documentation - Version: master
This bundle allows you to create i18n routes. ... supports different hosts per locale; allows you to add i18n at any time during...
Read more >
Creating, Adding and Referencing External Resource Bundles ...
External Resource Bundles are custom resource bundles that provide localized ... They contain locale specific properties files (one per locale) where each ...
Read more >
DefaultResourceBundle (Atlassian JIRA 7.1.5 API)
This class caches the ResourceBundle per locale, because the lookup is expensive and causes thread contention. Default ResourceBundles must live in the core ......
Read more >
Different facelets (for use in templates) in JSF 2 per locale
Currently I'm working on some web application that uses JSF 2, with PrimeFaces as component bundle, which uses resource bundles for i18n in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found