Page MenuHomePhabricator

"mw.config.values.wbSiteDetails" module downloads 27.3 kB of compressed JavaScript on Vector-22 page load
Open, HighPublic

Description

I was looking at Vector-2022's JavaScript payload today and noticed that there is a request that downloads 196 kB of uncompressed JavaScript (27.3 kB after gzip) on page load. The bulk of this is related to the mw.config.values.wbSiteDetails module downloaded from the Wikibase extension.

Notably, this module does not download on page load for legacy Vector. It appears this is due to a skin script.

2023-03-10_09-49-04 (2).png (1×3 px, 1 MB)

Questions:

  1. What is the purpose of all of this JavaScript?
  2. Does it need to download during page load? Can it be lazy loaded?

Acceptance Criteria

  • Clarification to the preceding questions
  • Create tickets if necessary

Event Timeline

nray renamed this task from "mw.config.values.wbSiteDetails" repo loads 196 kB of uncompressed JavaScript in Vector-2022 skin to "mw.config.values.wbSiteDetails" module downloads 196 kB of uncompressed JavaScript in Vector-2022 skin.Mar 10 2023, 11:30 PM
nray renamed this task from "mw.config.values.wbSiteDetails" module downloads 196 kB of uncompressed JavaScript in Vector-2022 skin to "mw.config.values.wbSiteDetails" module downloads 196 kB of uncompressed JavaScript on Vector-22 page load.
nray updated the task description. (Show Details)

Looks like this was added in T310259 @Michael and @LucasWerkmeister could you help us clarify what this is for, as this is problematic for our first input delay metrics and we'll like to see how we could optimize it. Could you help us prioritize this higher within WMDE?

I looked into it briefly to remind myself of what is going on. This was added in context of T310259. And looking at that script https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/extensions/Wikibase/+/60a3d9821fe5460930a47a9565b1aa0559cf1fbf/client/resources/wikibase.client.vector-2022.js:

wikibase.client.vector-2022.js
	var itemId = mw.config.get( 'wgWikibaseItemId' );
	if ( !itemId || [ null, 'error', 'registered' ].indexOf( mw.loader.getState( 'ext.uls.interface' ) ) !== -1 ) {
		return;
	}

	// wait for ext.uls.interface to be ready,
	// and lazy-load the other dependencies now that we know they're needed
	mw.loader.using( [
		'mw.config.values.wbRepo',
		'mw.config.values.wbSiteDetails',
		'ext.uls.interface',
		'oojs-ui.styles.icons-editing-core'
	], function () {

The intention is indeed to lazy-load these dependencies. But we may have misunderstood how something in how ResourceLoader works and made a mistake there?

Another approach could be to create a config module that contains the client config only for the current site and not all sites, that should then be much smaller than wbSiteDetails. Though that might be a non-trivial thing to do.

Also, this loads all the icons in oojs-ui.styles.icons-editing-core, would be nice if we could only load the one icon that we actually need.

Lucas_Werkmeister_WMDE renamed this task from "mw.config.values.wbSiteDetails" module downloads 196 kB of uncompressed JavaScript on Vector-22 page load to "mw.config.values.wbSiteDetails" module downloads 27.3 kB of compressed JavaScript on Vector-22 page load.Mar 31 2023, 8:36 AM
Jdlrobson added a subscriber: santhosh.

Hey @Michael thanks for the note! Yes, this is not lazy loaded, as it's being executed unconditionally on any page where ULS is present.

I think if the main purpose is to provide these configuration variables for ULS, it would make sense for ULS to load the dependency when the language button is clicked.
Could you use mw.hook( 'mw.uls.settings.open' ).add here instead of jQuery.ready to delay the execution of this code until the ULS dialog has been opened? If not, I'd suggest getting the language team to create a new hook that delays the load until the right user interaction. Adding @santhosh to see if he has any ideas.

Using a hook would also negate the need for the check at the beginning

example diff:

diff --git a/client/resources/wikibase.client.vector-2022.js b/client/resources/wikibase.client.vector-2022.js
index 7d6c6de6c2..1ec4642525 100644
--- a/client/resources/wikibase.client.vector-2022.js
+++ b/client/resources/wikibase.client.vector-2022.js
@@ -3,13 +3,10 @@
  *
  * @license GPL-2.0-or-later
  */
-( function () {
+mw.hook( 'mw.uls.settings.open' ).add( function () {
 	'use strict';
 
 	var itemId = mw.config.get( 'wgWikibaseItemId' );
-	if ( !itemId || [ null, 'error', 'registered' ].indexOf( mw.loader.getState( 'ext.uls.interface' ) ) !== -1 ) {
-		return;
-	}
 
 	// wait for ext.uls.interface to be ready,
 	// and lazy-load the other dependencies now that we know they're needed
@@ -35,4 +32,4 @@
 		// eslint-disable-next-line no-console
 		console.error( e );
 	} );
-}() );
+} );
Jdlrobson raised the priority of this task from Medium to High.Apr 5 2023, 11:38 PM
Jdlrobson added a project: SEO.

FYI: This is a high priority from web team's side. Reducing JS is a high priority as Google is apparently reporting many of our pages having low first input delay scores.

Thank you for bringing this up again. I had another look and 'mw.uls.settings.open' is unfortunately not what we need. This hook is fired when the language selector on a multilingual site like Wikidata or Commons is opened, so that one can change the UI language.
However, it is unfortunately not fired when the language/site selector on a monolingual site, like English Wikipedia, is opened.

I'm now wondering: is there a way to subscribe to _all_ js hooks? That way, one could figure out if there is a suitable one for us to use. But I'm curious to hear @santhosh's perspective on this as well.

IMHO the lazy loading is the wrong thing to focus on, and we should instead reduce the amount of data we’re loading:

Another approach could be to create a config module that contains the client config only for the current site and not all sites, that should then be much smaller than wbSiteDetails. Though that might be a non-trivial thing to do.

Adding a separate RL module for just the local site brings some cost with it, but if it lets us mostly skip loading the much heavier module of all sites’ information, it could still be worth it. (Alternatively, if we think this information is needed frequently enough, we could perhaps add it to the parser output of all pages, without needing to load a RL module at all.)

Reducing the amount of data would also be a good way to fix this!

I'm now wondering: is there a way to subscribe to _all_ js hooks? That way, one could figure out if there is a suitable one for us to use. But I'm curious to hear @santhosh's perspective on this as well.

It would be relatively straightforward to introduce a new hook so this code is loaded at the right time. Another option would be to not call OutputPage::addModules here and add the dependency inside ULS.

Prio Notes:

  • Affect end users / production
  • Does not affect development efforts
  • Does not affect onboarding
  • Affects additional stakeholders (WMF web team)

Story Writing Notes:

  • As the Wikidata team, we can try to minimize the initial payload by not including so much configuration.
  • We will create a new ticket to handle this work in the coming sprint.