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

✨ [Story localization] Localize system layer async #37870

Merged
merged 47 commits into from
Mar 22, 2022

Conversation

mszylkowski
Copy link
Contributor

@mszylkowski mszylkowski commented Mar 14, 2022

Make the system layer localize asynchronously. This means loading the aria-labels and the textContents async.

Why change the signature of registerLocalizationStringBundles?
Every time we add a new localization bundle we need to check if any usages are waiting for that string, so when we want to install the 20 languages bundled with amp-story, we want to just make one call to registerLocalizationStringBundles. For that reason the function needs to allow registering many languages at once, and at the end make a call to the observable.

When is the observable going to fire? What's it going to fire?
Only when the strings arrive after the components request the strings, the observable will have handlers that use the strings presented (this is when fetching the JSON from the cache). If the strings are registered before that (eg: with an inline JSON), the observer will never be used and the string requests will be resolved immediately.

Drafted on: #37303
Requires fix: #37887
I2I: #37344

dist/v0/amp-story-auto-ads-0.1.js: Δ +0.03KB
dist/v0/amp-story-1.0.js: Δ +0.11KB

mszylkowski and others added 30 commits December 21, 2021 14:45
Co-authored-by: Gabriel Majoulet <gmajoulet@google.com>
src/core/data-structures/observable.js Outdated Show resolved Hide resolved
src/service/localization/index.js Outdated Show resolved Hide resolved
src/service/localization/index.js Outdated Show resolved Hide resolved
Copy link
Contributor

@gmajoulet gmajoulet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will review tests once the code is right :))

.registerLocalizedStringBundle('zh-cn', LocalizedStringsZhCn)
.registerLocalizedStringBundle('zh-TW', LocalizedStringsZhTw)
.registerLocalizedStringBundle('en-xa', enXaPseudoLocaleBundle);
this.localizationService_.registerLocalizedStringBundles({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we lazy loading auto-ads strings as a follow up? Where is this tracked?
How many kbs are removed from the critical render path by doing so?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is part of the change in signature of registerLocalizationStringBundles to receive a map of languageCode: bundle. We can make the auto-ads async at some point but it's not the goal of this effort now (can be a stretch goal); we could add the strings to the amp-story JSONs or a new set of JSONs, because this architecture allows for both, though it will require more work on the infra side. The auto-ads strings are not in the critical render path of the story so we can analyze it later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The answer to this is in the FAQ section of the I2I as well. I added it in the description of the PR so it's easier to follow.

extensions/amp-story/1.0/amp-story-system-layer.js Outdated Show resolved Hide resolved
extensions/amp-story/1.0/amp-story-system-layer.js Outdated Show resolved Hide resolved
Comment on lines 157 to 172
const localizeSystemLayer = (systemLayer, parentElement) => {
const localizationService = getLocalizationService(parentElement);
systemLayer.querySelectorAll('[data-aria-label]').forEach((el) => {
localizationService.localizeEl(
el,
el.getAttribute('data-aria-label'),
'aria-label'
);
el.removeAttribute('data-aria-label');
});
localizationService.localizeEl(
systemLayer.querySelector('.i-amphtml-story-has-new-page-text'),
LocalizedStringId_Enum.AMP_STORY_HAS_NEW_PAGE_TEXT
);
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't have any LocalizedStringId_Enum key in here, this should just be a post processing function using the data provided by developers within templates.

Also, this should be a helper that can be re-used for all other templates in other files.

A few additional questions:

  1. How will you block rendering on strings that need to be rendered synchronously
  2. If you add a string asynchronously but it is visible to users, then it needs to run in a mutateElement context

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Block rendering can happen like so: localize(template).then(() => {document.appendChild(template)})
  2. Yes, in that scenario it will likely be a render-blocking localization, which currently happens in a mutate context so we just do that after the promise.

@gmajoulet
Copy link
Contributor

Also, can you please improve how you track this feature, and open an issue explaining the change + listing all the files you have to update? Being more transparent will help wit a lot of things, from understanding the scope of this PR and its place in the overall project, to tracking progress.

@mszylkowski
Copy link
Contributor Author

@gmajoulet there is already an I2I on #37344 that contains that info. There are a few implementation details that are not there, so I added them in a comment.

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