In that bug I'm skipping one feature of the JSM code which is a prefetch.
Prefetch is a feature that can work in sync or async mode, and gives us a couple potential performance benefits.
The current model without prefetch looks like this:
- Document parsing begins
- Parser reaches
<link rel="localization"/> in
<head/> and create
DocumentL10n instance for it.
- Parser reaches end of
</head> and nothing happens
- Parser collects
data-l10n-id elements to be localized
- Parser reaches end of the document
- Document triggers
DocumentL10n::TranslateElements for all pending elements
- That triggers (a)sync I/O load of all FTL resources needed by the l10n context
- FTL is applied, document is ready for first paint
Sync prefetch is easy, since it happens all on the same thread.
In sync mode, prefetch allows us to fiddle with when are we blocking the thread on I/O. The model we'll use after bug 1613705 lands, without prefetch, is:
Prefetch would allow us to move the I/O to be triggered by (3). It's still a sync operation, so it may not even be desirable to block document parsing on Fluent I/O, because maybe some operations are async (images, scripts, iframe loading) and currently can be triggered between (3) and (5) and continue being executed while (7) blocks on sync load.
The other rearchitecture we might explore with prefetch, would be that we could then, instead of collecting localizable elements, directly localize them as a step after parser parses it effectively simplifying the document parsing and having the document ready and localized by the moment end of the document is reached.
This may be worth exploring, although such model would need to handle a scenario where an element doesn't have localization and that triggers I/O for fallback localization, all in synchronous mode. The rebuttal is that this fallback has to be performed and blocks first paint anyway, so where it happens may not matter.
We should test the hypothesis.
Async prefetch is similar to sync, except that it doesn't block document parsing and all auxiliary events triggered during it. The FTL loading would happen in parallel.
The basic idea would be that we'd try to parallelize FTL load triggering it at (3) while the document is being parsed in (4) until (5).
In such a model, we would be banking on the idea that document parsing is CPU bound while FTL load is I/O bound and by the time the document is fully parsed, the FTL is ready to apply translations.
We could then, similarly as in sync mode, explore it further and have a switch between collecting pending translations, and switching to applying translation as parser reaches an element to be triggered if the load is ready during document parsing.
The whole prefetch is a feature that gives us a number of toggles to shuffle operations around trying to optimize parallelism.