Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-39345

Use js-modules to coordinate async loading of i18n translation bundles as part of dependant JavaScript bundle

    • indian, arctic, tasman, pannonian

      A.K.A "translation keys instead of content keep showing up and flashing to the localised version on first load"

      Use new/extended js-modules/js-builder API delivered as part of JENKINS-39322 to automatically coordinate the async loading of i18n translations as part of the loading of a blueocean bundle that depends on the translation.

      This will allow synchronous access to the translations at runtime (because we can guarantee that they are already loaded in the browser), which in turn allows a much nicer programming model around i18n, removing the need to tie translation resource loading into react lifecycle etc (i.e. no need for e.g. react-i18next shim for react components - would need something else for non react components).

      Assigned to tfennelly for now, but should be doable by anyone if we get JENKINS-39322 right.

          [JENKINS-39345] Use js-modules to coordinate async loading of i18n translation bundles as part of dependant JavaScript bundle

          Tom FENNELLY added a comment - - edited

          Issues around async loading of translations are becoming more apparent now (guessing because we've made the page loading times faster). When a user switches lang they initially still see English after the page loads. They need to start clicking around before the text changes.

          Tom FENNELLY added a comment - - edited Issues around async loading of translations are becoming more apparent now (guessing because we've made the page loading times faster). When a user switches lang they initially still see English after the page loads. They need to start clicking around before the text changes.

          Cliff Meyers added a comment -

          michaelneale jamesdumay we discussed this issue as a group in today's meeting and agreed this should be addressed as soon as is feasible. Can we pull this one into the sprint?

          Cliff Meyers added a comment - michaelneale jamesdumay we discussed this issue as a group in today's meeting and agreed this should be addressed as soon as is feasible. Can we pull this one into the sprint?

          Tom FENNELLY added a comment -

          Yeah, it looks a bit ugly now in spots. This was always an issue but is more obvious/visible now because of recent changes in core-js.

          Tom FENNELLY added a comment - Yeah, it looks a bit ugly now in spots. This was always an issue but is more obvious/visible now because of recent changes in core-js.

          Cliff Meyers added a comment - - edited

          jamesdumay just to clarify the need / benefits:

          1. Every string displayed in the UI needs that defaultValue specified. So all i18n code looks like this:

          <div>{t('creation.git.step1.title'), { defaultValue: "Connect to Git" })}</div>

          After making this change it could simply be

          <div>{t('creation.git.step1.title')}</div>

          This would be a huge benefit from a maintainability standpoint.
          2. Right now, the UI will render with whatever "defaultValue" in specified in the JS code and then re-render after the language bundle loads (async, after the initial render). So for anyone that doesn't have English set as their language, they will see the UI paint in English and then repaint in their language a moment later.
          3. Anywhere that we might access localized strings in a more programmatic fashion (outside of JSX, e.g. in a list of radio buttons where we build up the button labels in JS code) we will have to introduce some pattern to delay the execution of that code until after the bundle loads, otherwise the defaultValue string will display instead of the correct value.

          Cliff Meyers added a comment - - edited jamesdumay just to clarify the need / benefits: 1. Every string displayed in the UI needs that defaultValue specified. So all i18n code looks like this: <div>{t( 'creation.git.step1.title' ), { defaultValue: "Connect to Git" })}</div> After making this change it could simply be <div>{t( 'creation.git.step1.title' )}</div> This would be a huge benefit from a maintainability standpoint. 2. Right now, the UI will render with whatever "defaultValue" in specified in the JS code and then re-render after the language bundle loads (async, after the initial render). So for anyone that doesn't have English set as their language, they will see the UI paint in English and then repaint in their language a moment later. 3. Anywhere that we might access localized strings in a more programmatic fashion (outside of JSX, e.g. in a list of radio buttons where we build up the button labels in JS code) we will have to introduce some pattern to delay the execution of that code until after the bundle loads, otherwise the defaultValue string will display instead of the correct value.

          Ivan Meredith added a comment -

          You can see this issue in action if you set your browser to german default, then go to ci.blueocean.io/blue . The Dashboard label first shows as English then switches to german.

          Ivan Meredith added a comment - You can see this issue in action if you set your browser to german default, then go to ci.blueocean.io/blue . The Dashboard label first shows as English then switches to german.

          James Dumay added a comment -

          OK good stuff. I've added this to the release-candidate queue but we need to get to some other things first. Will re-review on monday.

          James Dumay added a comment - OK good stuff. I've added this to the release-candidate queue but we need to get to some other things first. Will re-review on monday.

          Michael Neale added a comment -

          I think we should bring this forward, tfennelly is right, this one will bite (cliff is seeing it with creation flow).

          Tom - how "destructive" will these changes be? hard to say?

          Michael Neale added a comment - I think we should bring this forward, tfennelly is right, this one will bite (cliff is seeing it with creation flow). Tom - how "destructive" will these changes be? hard to say?

          James Dumay added a comment -

          ... and is there any way for us to try it before committing to master?

          James Dumay added a comment - ... and is there any way for us to try it before committing to master?

          Tom FENNELLY added a comment -

          I think we should bring this forward

          It was puzzling me how making the "Quick Language Switcher" work could have been higher priority than getting BO itself to switch language properly. So yes, bringing this forward seems consistent to me

          Tom - how "destructive" will these changes be? hard to say?

          Hmmm ... atm I don't think it will be destructive. I would expect/hope the component JavaScript code to not change at all. The plugins might have to "declare" their i18n bundles e.g. in the same yaml file as they declare Extension Points. We (the build) could auto-detect the default bundle, which atm is all any of the core BO plugins are using afaik.

          The bigger changes would be in js-modules and js-builder, building in generic hooks (so we can potentially do this for other "stuff" e.g. kzantow did some work for extension decorators that would be able to use something like this too) to allow us hook into the bundle loading process i.e. to allow us inject resource loading "functions" that return a Promise that needs to be fullfilled along with the normal javascript loading stuff before the bundle can start executing.

          After that, we wire the above into blue ocean's plugin for js-builder and get it to inject resource loading for i18n resources. That resource loading would load i18next with the resource bundle it's told to load (declared by the plugin - detected by js-builder plugin etc) and would only resolve its promise once that's done, blocking the dependant/owner javascript bundle from executing.

          I'm sure there'll be kinks that need working out, but that's the general idea.

          Tom FENNELLY added a comment - I think we should bring this forward It was puzzling me how making the "Quick Language Switcher" work could have been higher priority than getting BO itself to switch language properly. So yes, bringing this forward seems consistent to me Tom - how "destructive" will these changes be? hard to say? Hmmm ... atm I don't think it will be destructive. I would expect/hope the component JavaScript code to not change at all. The plugins might have to "declare" their i18n bundles e.g. in the same yaml file as they declare Extension Points. We (the build) could auto-detect the default bundle, which atm is all any of the core BO plugins are using afaik. The bigger changes would be in js-modules and js-builder, building in generic hooks (so we can potentially do this for other "stuff" e.g. kzantow did some work for extension decorators that would be able to use something like this too) to allow us hook into the bundle loading process i.e. to allow us inject resource loading "functions" that return a Promise that needs to be fullfilled along with the normal javascript loading stuff before the bundle can start executing. After that, we wire the above into blue ocean's plugin for js-builder and get it to inject resource loading for i18n resources. That resource loading would load i18next with the resource bundle it's told to load (declared by the plugin - detected by js-builder plugin etc) and would only resolve its promise once that's done, blocking the dependant/owner javascript bundle from executing. I'm sure there'll be kinks that need working out, but that's the general idea.

            tfennelly Tom FENNELLY
            tfennelly Tom FENNELLY
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: