Page MenuHomePhabricator

immediate kicking in of the Bridge: Move service creation out of init
Closed, ResolvedPublic3 Story Points

Description

As as user I want links which qualify for bridge to truly opened in bridge.

Problem:
If a user clicks the edit pen too quickly after loading the page then the Bridge hasn't finished loading and the user gets thrown to Wikidata instead.
A smaller init file will reduce the time it takes for the module to be loaded & consequently link listeners to be attached.

BDD
GIVEN an article
AND a Bridge-enabled infobox
WHEN loading the page
AND clicking the edit pen shortly afterwards
THEN the Bridge opens

Acceptance criteria:

  • time between page loading and Bridge being ready is reduced on slow internet connection

Tech notes

  • creation of ServiceRepositories is moved out of init - either into a dedicated module, or into app
  • pass along what is required to create its contents (e.g. ForeignApi)
  • ServiceRepositories is created using instances of data-access "repositories". These can be huge and are not technically needed at init-time
  • this was researched in T233305: delayed kicking in of Bridge

Details

Related Gerrit Patches:
mediawiki/extensions/Wikibase : masterbridge: move createServices from init to app module
mediawiki/extensions/Wikibase : masterbridge: move service creation from init to app

Event Timeline

Restricted Application added a project: Wikidata. · View Herald TranscriptOct 17 2019, 2:39 PM
Restricted Application added a subscriber: Aklapper. · View Herald Transcript
Lydia_Pintscher moved this task from Needs work to Ready to estimate on the Wikidata-Bridge board.
Lydia_Pintscher renamed this task from Move service creation out of init to immediate kicking in of the Bridge: Move service creation out of init.Nov 1 2019, 1:37 PM
Lydia_Pintscher triaged this task as Medium priority.Nov 4 2019, 10:02 PM

Some inspiration for how this could be measured can be found in @Lucas_Werkmeister_WMDE post T233305#5555763

Lydia_Pintscher set the point value for this task to 3.Nov 5 2019, 11:38 AM

Okay, with a WIP patch:

filesize beforesize after
data-bridge.init.js94 kB59 kB
data-bridge.init.js (gzipped)30 kB17 kB
data-bridge.common.js305 kB416 kB
data-bridge.common.js (gzipped)69 kB95 kB

So after gzip, we almost cut the init module in half (☺) but bloat the app module by more than that amount (☹). Probably worth a bit more investigation. (That’s using SI prefixes, btw, and gzip default settings.)

Change 550873 had a related patch set uploaded (by Lucas Werkmeister (WMDE); owner: Lucas Werkmeister (WMDE)):
[mediawiki/extensions/Wikibase@master] bridge: move service creation from init to app (WIP)

https://gerrit.wikimedia.org/r/550873

Okay, using the “development mode + grep !***” trick from T228857#5556518, it looks like the init module shrinks by 96 included files, whereas the app module grows by 76 included files. I’ve pasted the difference in P9637 – removed lines (begin with -) correspond to files that disappear from the init module without being added to the app module (usually because they were already present there), added lines (begin with +) are files that are added to the app module without being removed from the init module, and context lines (begin with ) are files that cleanly moved from the init to the app module (including the contents of data-access). I’m not sure what to make of this yet.

There are a lot of names that appear to occur twice or more in our bundles:

$ grep _promise-resolve includes-app-after 
  !*** ./node_modules/core-js/library/modules/_promise-resolve.js ***!
  !*** ./node_modules/core-js/modules/_promise-resolve.js ***!
$ grep get-prototype-of includes-app-after 
  !*** ./node_modules/@babel/runtime-corejs2/core-js/object/get-prototype-of.js ***!
  !*** ./node_modules/core-js/library/fn/object/get-prototype-of.js ***!
  !*** ./node_modules/core-js/library/modules/es6.object.get-prototype-of.js ***!
$ grep _promise-resolve includes-init-after 
  !*** ./node_modules/core-js/library/modules/_promise-resolve.js ***!
  !*** ./node_modules/core-js/modules/_promise-resolve.js ***!

I wasted a bit of time tracking down how prevalent this is, but after looking at a few of the files, I think those are actually different, they just import one another (e. g. the get-prototype-ofs in @babel and core-js both import es6.object.get-prototype-of). Not a real problem.

EDIT: No, wait, the _promise-resolve.js ones are really two identical files that we include under different paths…

So after gzip, we almost cut the init module in half (☺) but bloat the app module by more than that amount (☹).

It occurred to me that a lot of this might be due to the fact that the init module is more minified than the app module, so here’s another table with even more numbers.

filesize beforesize after
init92 kB58 kB
init, gzip29 kB17 kB
init, uglifyjs91 kB58 kB
init, uglifyjs, gzip29 kB17 kB
app323 kB429 kB
app, gzip72 kB97 kB
app, uglifyjs104 kB141 kB
app, uglifyjs, gzip32 kB43 kB

(Numbers obtained by running for file in dist/data-bridge.{init,common}.js; do wc -c < "$file"; gzip < "$file" | wc -c; uglifyjs -c -m < "$file" | wc -c; uglifyjs -c -m < "$file" | gzip | wc -c; done | numfmt --to=iec on master and my branch. kB means 1000 bytes, gzip is v1.9, uglifyjs is uglify-es 3.0.19.) So after uglification, init shrinks by 33 kB and app grows by 37 kB, a 4 kB difference; after uglification and gzip, init shrinks by 12 kB and app grows by 11 kB, a 1 kB difference in the other direction.

While there are probably some rounding errors in there and this might vary by gzip/uglify settings (you could also use a different uglifier), in general this suggests to me that my change does not, in fact, bloat the app module with code conjured out of thin air. A roughly equivalent size of code seems to have moved from the init to the app module – it just looked otherwise because it moved from a more-compressed module to a less-compressed one.

(I don’t quite remember if the app module being less optimized/compressed was a conscious decision we made or just a consequence of how we set things up. In theory, it’s nice to be able to see the original code in the browser debugger when using ResourceLoader debug mode, but I admit I haven’t actually made use of that yet. Perhaps we should compress the app module after all?)

Change 551532 had a related patch set uploaded (by Lucas Werkmeister (WMDE); owner: Lucas Werkmeister (WMDE)):
[mediawiki/extensions/Wikibase@master] bridge: move createServices from init to app module

https://gerrit.wikimedia.org/r/551532

I uploaded an alternative version of the change. The size changes are exactly the same as in T235771#5666594, at least when rounded.

Change 550873 abandoned by Lucas Werkmeister (WMDE):
bridge: move service creation from init to app

Reason:
it looks like there’s general consensus to prefer Id1e6f4c1ce over this

https://gerrit.wikimedia.org/r/550873

Change 551532 merged by jenkins-bot:
[mediawiki/extensions/Wikibase@master] bridge: move createServices from init to app module

https://gerrit.wikimedia.org/r/551532

Lydia_Pintscher closed this task as Resolved.Mon, Nov 25, 10:00 AM
Lydia_Pintscher moved this task from Verification to Done on the Wikidata-Bridge-Sprint-9 board.
Lydia_Pintscher added a subscriber: Lydia_Pintscher.

\o/