Page MenuHomePhabricator

CentralAutoLogin delays fully load time
Closed, DuplicatePublic

Description

Observing http://wpt.wmftest.org/result/160325_FX_93/1/details/ for anonymous users on 2G connections I see a request for https://login.wikimedia.org/CentralAutoLogin/checkLoggedIn?type=script&wikiid=enwiki&mobile=1&proto=https&mobile=1

This starts at 14.2s and finishes at 20s (rest of the page finishes loading around 16.5
It seems unfair to include this request in the calculation for fully loaded time and I wonder if there is a way to either speed this request up, not make it (the user is anonymous?) or delay it so that it doesn't impact the initial user experience.

Event Timeline

The offending line is in ext.centralauth.centralautologin.js

mw.loader.load( url );

I wonder if this should only be executing on a window onload event (but there are some caveats we'd have to think through such as the cases where images load from cache)

It uses mw.loader.load() though it could use $.getScript() (or $.ajax({ dataType: 'script' })). Either way it's a cross-origin script that needs to result in script execution.

Right now it's triggered right away, and as any subresource added before window load event fires, it ends up requiring the browser to wait for that resource before emitting the window load event.

We can work around it either by delaying the code to not run until window-load. Alternatively, we can use a request method that doesn't result in the request becoming a subresource. E.g. something that doesn't add a script tag to the DOM.

Looks like this could be an XHR request with CORS. And only fallback to a script tag if needed. We'll need to figure out how this affects the redirect and script execution behaviour. I think it'd be preferable not to delay this until window load but keep it as-is.

The script execution can probably be refactored to return pure data as JSON and have the logic be in the consuming module instead. That would remove the need for it to be script execution always.

It will still internally be script execution for older browsers without CORS (the fallback for cross-domain XHR without CORS is JSON-P which is a script tag with a callback passing the JSON).

This is a pattern I use fair bit:

$.ajax({
	// Server must respond with pure JSON. Or, if a callback query parameter is present
	// with script wrapping the JSON in said callback.
	url: ..,
	data: { .. },
	// JSON: Uses XHR (with CORS, if url is cross-domain).
	// JSON-P: Uses a script tag ands add 'callback' query parameter
	dataType: $.support.cors ? 'json' : 'jsonp',
	cache: true // No cache-buster query string 
});

(server example extracted from MediaWiki: Krinkle/intuition:/api.php#L31-L57.

Note core has a ForeignApi module specifically for managing CORs requests.

It seems this code has always loaded, but now when images are lazy loaded it has become more of a problem, skewing results more.

Compare
http://wpt.wmftest.org/result/160323_VM_9S/
with
http://wpt.wmftest.org/result/160327_W5_21/1/details/

On a side note, is it just me or does it seem like image downloads are blocking JavaScript at the bottom from loading?

Uhhh, how does this block T124390: [GOAL] Load images with care?

It could be blocking our ability to measure the performance improvement accurately. I'm still investigating.