Page MenuHomePhabricator

Move some page- and user-specific mw.config data out of HTML head, to end of body
Open, LowPublicFeature

Description

mw.Title already exists though it needs more work and could use some caching.

mw.User doesn't exist yet as a constructor, but preliminary work has already been done with a lazy-loading system (with the introduction of mw.user.getGroups and mw.user.getRights - similar to in PHP where those methods call ->init() which does nothing if already loaded and loads it if not).

Each of these would be constructed (without being initialized) by default in their lowercase equivalents (mw.title, mw.user, mw.page).

I suggest we write an abstract class that implements:

  • Caching by unique identifier
  • Methods to clear cache
  • Methods to populate cache
  • etc.

Eventually this will also allows us to clean up stuff that doesn't belong in mw.config (wgUserName, wgUserGroups, wgCategories, wgCurRevisionId, wgTitle).

And if those vars provide sufficient information to fully populate a cache, we can even optimize for the current context instances and prepopulate them.

Or do it the other way around (populate mw.user/title/page/revision from the page output, and put a backwards compatible thing in mw.config that accesses those from mw.user/title/page/revision)


Version: 1.20.x
Severity: enhancement

Details

Reference
bz39813

Event Timeline

bzimport raised the priority of this task from to Medium.Nov 22 2014, 12:51 AM
bzimport set Reference to bz39813.
Krinkle lowered the priority of this task from Medium to Low.Nov 24 2014, 2:57 PM
Krinkle set Security to None.
Phabricator_maintenance renamed this task from Implement immutable object constructors with caching for mw.User, mw.Title, mw.Page (tracking) to Implement immutable object constructors with caching for mw.User, mw.Title, mw.Page.Aug 13 2016, 11:29 PM

I'm reviving this and rephrasing it with the explicit goal of moving wgUserGroups and wgCategories values in mw.config from the <head> to the end of </body>, and (prior to that) give them documented and well-supported async JS methods to reliably access the data (asking users to manually wait for dom-ready and then access mw.config would be a fragile pattern to explain and support).

Prior art:

  • 2012: Rejected new addition of wgUserRights to mw.config data in page head. – T40151
  • 2012: Shipped mw.user with async methods .getRights() and .getGroups(). – T40151
  • 2016: Re-implement .getGroups() to make use of wgUserGroups. – https://gerrit.wikimedia.org/r/280753

I'm proposing the next steps:

  1. Deprecate access to wgUserGroups via mw.config, in favour of mw.user.getGroups (an async method).

I think this is rare enough to not cause widespread panic or take many years to migrate; and yet sufficiently common that it should get us through diverse and wide range of situations where this might be the first time a module dependency or async method is used, thus requiring us to address any unsolved challenges an extension, skin, or gadget might have.

After this first pilot, we can then look at further moving of data towards more async and anticipated workflows. This is loosely related to T183720 and T140664, in so far that they are also about improving page load performance, about letting data flow in one direction, about the server knowing what clients need and sending it to them for the client to wait for and react to in real-time; Instead of the traditional way (where we still are mostly) where as much as possible that might be needed is sent upfront and blocking rendering, then everything renders, and then JS starts looking combing through this stuff and making use of a few things that it was sent, which the user needlessly paid for several seconds ago but weren't used until now.

  1. Remove wgUserGroups from mw.config in OutputPage, and instead send it through an internal mw.hook() that mw.user.getGroups listens for. This would either be something specific like internal.user.groups, or something more general like internal.deferredConfig, which we could expose through something like mw.getDeferredConfig(). The latter might make sense so that extensions don't have to reinvent as much and can instead leverage more of the same infrastructure for their own use cases.
  1. Do the same for wgCategories.
Krinkle renamed this task from Implement immutable object constructors with caching for mw.User, mw.Title, mw.Page to Move some page- and user-specific mw.config data out of HTML head, to end of body.Apr 25 2021, 7:34 PM
Krinkle moved this task from Inbox to Backlog: Future Goals on the Performance-Team board.
Aklapper changed the subtype of this task from "Task" to "Feature Request".Feb 4 2022, 11:14 AM
Aklapper removed a subscriber: TrevorParscal.