Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: use Intl.getCanonicalLocale #2244

Conversation

VIKTORVAV99
Copy link
Contributor

Since this code was created 9 years ago there has been standardisation around this and it's now part of the Intl object.

Replacing this should have no impact on support as it has had full browser support for several years now: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/getCanonicalLocales

This reduces the size by 519 bytes (49 096 bytes -> 48 577 bytes) and should be faster as it has a native implementation.

Checklist

  • only relevant code is changed (make a diff before you submit the PR)
  • run tests npm run test
  • tests are included
  • commit message and code follows the Developer's Certification of Origin

@coveralls
Copy link

Coverage Status

coverage: 96.174% (-0.03%) from 96.199%
when pulling 80cda93 on VIKTORVAV99:replace_custom_language_formatting_code_with_Intl.getCanoncialLocales
into 60e3779 on i18next:master.

@adrai
Copy link
Member

adrai commented Oct 13, 2024

as long as there is V3 support that does not use the Intl api => https://github.com/i18next/i18next/blob/master/src/PluralResolver.js#L99 we can't merge this...
but we can consider this like (#2184) for the next major version

@VIKTORVAV99
Copy link
Contributor Author

as long as there is V3 support that does not use the Intl api => https://github.com/i18next/i18next/blob/master/src/PluralResolver.js#L99 we can't merge this... but we can consider this like (#2184) for the next major version

Intl.getCanonicalLocale is a lot older than plural rules so even then it should be supported IMO. But yeah probably best to put it in a new major version. Might I also suggest removing the lowerCaseLanguage option when that is done? (this one: this.options.lowerCaseLng I don't think it's adding any value).

adrai added a commit that referenced this pull request Oct 13, 2024
@adrai
Copy link
Member

adrai commented Oct 13, 2024

Just released v23.16.0 that will use Intl.getCanonicalLocale if available...

@adrai
Copy link
Member

adrai commented Oct 13, 2024

regarding the lowerCaseLng... this was a user request long time ago... and part of i18next since v1.2.3... isn't it @jamuhl ?

@VIKTORVAV99
Copy link
Contributor Author

Just released v23.16.0 that will use Intl.getCanonicalLocale if available...

Just as a FYI, it would be really nice if you used PRs so other people like myself can watch for new PRs. Commits to master does not have this capability.

@VIKTORVAV99
Copy link
Contributor Author

I would for example have loved to provide some feedback as the typeof !== 'undefined' checks are not needed in this case as a simple truthy check would suffice. typeof functions and comparisons are slower than a simple true check.

@adrai
Copy link
Member

adrai commented Oct 13, 2024

Just as a FYI, it would be really nice if you used PRs so other people like myself can watch for new PRs. Commits to master does not have this capability.

you're right... next time..

I would for example have loved to provide some feedback as the typeof !== 'undefined' checks are not needed in this case as a simple truthy check would suffice. typeof functions and comparisons are slower than a simple true check.

Unfortunately, in some environments those truthy checks did not work... we experienced this also here: https://github.com/i18next/i18next/blob/master/src/i18next.js#L94

All these different environments and setups etc... are the reason why we want to keep the code compatibility as wide as possible... and not always use the newest syntax features etc...

@VIKTORVAV99
Copy link
Contributor Author

Just as a FYI, it would be really nice if you used PRs so other people like myself can watch for new PRs. Commits to master does not have this capability.

you're right... next time..

I would for example have loved to provide some feedback as the typeof !== 'undefined' checks are not needed in this case as a simple truthy check would suffice. typeof functions and comparisons are slower than a simple true check.

Unfortunately, in some environments those truthy checks did not work... we experienced this also here: https://github.com/i18next/i18next/blob/master/src/i18next.js#L94

All these different environments and setups etc... are the reason why we want to keep the code compatibility as wide as possible... and not always use the newest syntax features etc...

I'm really curious to hear about which environments have defined internal objects that resolve truthy if they don't exist. If those exist they are not actually JavaScript compliant and I don't think anyone should go out of their way to support them.

And while I agree that the newest syntax should not always be used I'd say it's fair game to use any feature that is supported by all supported browsers and engines. If end users want to support older stuff than that I'd say it's up to them to enable that either by using older versions of the package or polyfiling/transpiling the code.

It should not be up to you as a maintainer to support 10 year old browsers.

But that's just my take on it.

@jamuhl
Copy link
Member

jamuhl commented Oct 13, 2024

not all companies are fast movers - most are not, most big companies are not...locking them out just because of the latest greatest can be done - but should be done wisely (there is nothing worse than getting major versions every few months - breaking your codebase)...

@adrai
Copy link
Member

adrai commented Oct 13, 2024

It should not be up to you as a maintainer to support 10 year old browsers.

i18next is not only used in browsers... but also react-native, hexo, server side, meteor... etc...

@adrai
Copy link
Member

adrai commented Oct 13, 2024

btw: most users will just downgrade to still continue to work with i18next... and if they find some bugs or missing functionality etc... we are then forced to address that also on older i18next versions... more work for everyone, just because of new syntax etc...

@VIKTORVAV99
Copy link
Contributor Author

VIKTORVAV99 commented Oct 13, 2024

not all companies are fast movers - most are not, most big companies are not...locking them out just because of the latest greatest can be done - but should be done wisely (there is nothing worse than getting major versions every few months - breaking your codebase)...

That's the great part about pinning dependencies. Everything would work exactly as it does now for them. I don't see a problem here.

If they only use the latest all the time that's on them.

i18next is not only used in browsers... but also react-native, hexo, server side, meteor... etc...

Intl is supported in react-native, node, deno and other JS runtimes as well and have been for a long time.

It reached baseline support in September 2017.

btw: i18next/react-i18next#1797 to still continue to work with i18next... and if they find some bugs or missing functionality etc... we are then forced to address that also on older i18next versions... more work for everyone, just because of new syntax etc...

Which is my point, if they need to downgrade, from a major version they shouldn't have updated in the first place. Major versions indicate breaking changes and therefore extra care should be taken to ensure it works. Or to pin the dependency to the last supported version.

Newer applications and users should not have to suffer from bloated code or performance hits just because unsupported environments don't support a built in object or newer syntax.

For example i18next is 48.9 kb minified while Lingui is 7 kb, that is a lot of extra stuff for two libraries that aim to do the same thing.

@adrai
Copy link
Member

adrai commented Oct 13, 2024

Newer applications and users should not have to suffer from bloated code or performance hits just because unsupported environments don't support a built in object or newer syntax.

If bloated code or performance really hits in real world scenarios, I'm full ok with removing stuff for the newer (more modern) environments... but if it only brings a marginal improvement, then it's better not to cut off the user base straight away...

For example i18next is 48.9 kb minified while Lingui is 7 kb, that is a lot of extra stuff for two libraries that aim to do the same thing.

i18next has a completely different approach compared to Lingui... and btw: what are 50kb vs 7kb when your application loads mbs of data...?

But in general, I'm with you...
I already told you... for the next major, we will remove/change some stuff here...

@VIKTORVAV99
Copy link
Contributor Author

VIKTORVAV99 commented Oct 13, 2024

i18next has a completely different approach compared to Lingui... and btw: what are 50kb vs 7kb when your application loads mbs of data...

Because we built a SPA that bundles all the languages and core libraries and only connect to our backend to get production data, not translations. But it's also an indicator that there is a lot more operations that are going on than there needs to be, which I'm more concerned about.

More importantly our app bundles are split up and i18next is included in the core bundle as it's used everywhere in our application. The core bundle is currently 286.85 kB so removing 43 kb from that (excluding any extra reductions from the react package) would mean lowering our index bundle by 15%. Since that bundle is blocking all other code from executing that is a pretty significant change.

@jamuhl
Copy link
Member

jamuhl commented Oct 13, 2024

Sure smaller is better in general...but does your SPA really suffer from those 14kB i18next adds (if loaded gzipped)? Or could the time be invested better somewhere else?

I mean our app has a core module size of 900kB which gets cached after first load - and even if not - takes like 70ms to load. But we might be lucky our app is not used in environments having bad internet.

@VIKTORVAV99
Copy link
Contributor Author

Sure smaller is better in general...but does your SPA really suffer from those 14kB i18next adds (if loaded gzipped)? Or could the time be invested better somewhere else?

I mean our app has a core module size of 900kB which gets cached after first load - and even if not - takes like 70ms to load. But we might be lucky our app is not used in environments having bad internet.

Our app is very much used in mobile envs and there is for sure other optimisations that can be done (and are being done) but these are outside the index bundle. So while they are important and still are being done they don't have the same impact on first load as the core packages like i18next.

@jamuhl
Copy link
Member

jamuhl commented Oct 14, 2024

my last 50cents...looks like such changes have a wider impact as estimated...i18next/react-i18next#1797 (comment) comes to mind

if such changes break installments - I would consider not publishing this as just "patch" versions - but possible breaking major

alexandresoro pushed a commit to alexandresoro/ouca that referenced this pull request Oct 14, 2024
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [i18next](https://www.i18next.com) ([source](https://github.com/i18next/i18next)) | dependencies | minor | [`23.15.2` -> `23.16.0`](https://renovatebot.com/diffs/npm/i18next/23.15.2/23.16.0) |

---

### Release Notes

<details>
<summary>i18next/i18next (i18next)</summary>

### [`v23.16.0`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#23160)

[Compare Source](i18next/i18next@v23.15.2...v23.16.0)

-   use `Intl.getCanonicalLocales` function if available to format language code, like suggested in [2244](i18next/i18next#2244)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC4xMjAuMCIsInVwZGF0ZWRJblZlciI6IjM4LjEyMC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Reviewed-on: https://git.tristess.app/alexandresoro/ouca/pulls/221
Reviewed-by: Alexandre Soro <code@soro.dev>
Co-authored-by: renovate <renovate@git.tristess.app>
Co-committed-by: renovate <renovate@git.tristess.app>
@VIKTORVAV99 VIKTORVAV99 deleted the replace_custom_language_formatting_code_with_Intl.getCanoncialLocales branch October 28, 2024 17:06
alexandresoro pushed a commit to alexandresoro/ouca that referenced this pull request Dec 23, 2024
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [i18next](https://www.i18next.com) ([source](https://github.com/i18next/i18next)) | dependencies | major | [`23.16.8` -> `24.2.0`](https://renovatebot.com/diffs/npm/i18next/23.16.8/24.2.0) |

---

### Release Notes

<details>
<summary>i18next/i18next (i18next)</summary>

### [`v24.2.0`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2420)

[Compare Source](i18next/i18next@v24.1.2...v24.2.0)

-   feat(typescript): Add strictKeyChecks option to enforce checking key existence when defaultValue is used [2274](i18next/i18next#2274), fixes [2043](i18next/i18next#2043)

### [`v24.1.2`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2412)

[Compare Source](i18next/i18next@v24.1.1...v24.1.2)

-   optimize fix: Bug Report: Unsafe Behavior in i18n.t Function Leading to Potential Code Execution [2273](i18next/i18next#2273)

### [`v24.1.1`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2411)

[Compare Source](i18next/i18next@v24.1.0...v24.1.1)

-   fix: Bug Report: Unsafe Behavior in i18n.t Function Leading to Potential Code Execution [2273](i18next/i18next#2273)

### [`v24.1.0`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2410)

[Compare Source](i18next/i18next@v24.0.5...v24.1.0)

-   try to address [2270](i18next/i18next#2270) by cloning the store data [2271](i18next/i18next#2271)

### [`v24.0.5`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2405)

[Compare Source](i18next/i18next@v24.0.4...v24.0.5)

-   remove extra log for [2268](i18next/i18next#2268)

### [`v24.0.4`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2404)

[Compare Source](i18next/i18next@v24.0.3...v24.0.4)

-   simplify fix: incorrect locale detected [2268](i18next/i18next#2268)

### [`v24.0.3`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2403)

[Compare Source](i18next/i18next@v24.0.2...v24.0.3)

-   fix: incorrect locale detected [2268](i18next/i18next#2268)
-   fix: Intl.getCanonicalLocales throws with custom regions [2267](i18next/i18next#2267)

### [`v24.0.2`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2402)

[Compare Source](i18next/i18next@v24.0.1...v24.0.2)

-   if no Intl api, log error and use dummy rule

### [`v24.0.1`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2401)

[Compare Source](i18next/i18next@v24.0.0...v24.0.1)

-   early return and log error, if no Intl api

### [`v24.0.0`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2400)

[Compare Source](i18next/i18next@v23.16.8...v24.0.0)

**This is a major breaking release:**

-   remove support for older environments
-   remove old i18next JSON formats
    -   To convert your existing v3 translations to the v4 format, have a look at [i18next-v4-format-converter](https://github.com/i18next/i18next-v4-format-converter) or this [web tool](https://i18next.github.io/i18next-v4-format-converter-web/).
-   remove support for compatibility to v1 API
-   Intl API is mandatory now and will not fallback anymore
-   possible compatibility layer for older formats: `test/compatibility/v4/v4Compatibility.js`
-   rename `initImmediate` to `initAsync`
-   fallback to `dev` language if plural rule not found
-   remove TypeScript v4 support. TypeScript v5 is now an optional peer dependency
-   addresses
    -   [2244](i18next/i18next#2244)
    -   [2184](i18next/i18next#2184)
    -   [2213](i18next/i18next#2213)
    -   [2206](i18next/i18next#2206)
    -   [2208](i18next/i18next#2208)
    -   [2148](i18next/i18next#2148)
    -   [2254](i18next/i18next#2254)

➡️ check out the [migration guide](https://www.i18next.com/misc/migration-guide#v23.x.x-to-v24.0.0)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS41Ny40IiwidXBkYXRlZEluVmVyIjoiMzkuNzUuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Reviewed-on: https://git.tristess.app/alexandresoro/ouca/pulls/384
Reviewed-by: Alexandre Soro <code@soro.dev>
Co-authored-by: renovate <renovate@git.tristess.app>
Co-committed-by: renovate <renovate@git.tristess.app>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants