When we enabled this warning mechanism in 2018, the most common violation was the Gadgets extension. Its noise was hiding pretty much all else.
This was fixed last week per T171180. I've re-enabled the detection logging with <https://gerrit.wikimedia.org/r/#/c/mediawiki/core/+/431816/>, but today during the group1 deployment, it became obvious there's a few more we missed that happen on basically all page views (warning detection disabled now again in prod per T235711).
These will need to be fixed before we can continue.
For each of these, the code currently calls `addModules()` on both mobile and desktop, but the lack of a `target` declaration is making the module get skipped client-side. We will need to set `targets=> [mobile, desktop]` on these and then decide either to let it load like the code tries already, or explicitly forego loading in some way.
| fixed | module | 4h total count |Bug
|--|--|--|--
|✅ | ext.uls.interlanguage | 809,041|T236943
| ✅| ext.visualEditor.desktopArticleTarget.init | 809,039|T236944
|| ext.visualEditor.desktopArticleTarget.noscript | 809,037|T236944
|✅ | ext.3d.styles | 809,036 |T235796
|✅ | ext.uls.interface | 809,035 | T237036, T237061
| ✅| ext.wikimediaBadges | 807,320 | T236946
|✅ | site | 783,608 |T237050
| ✅| site.styles | 783,606|T237050
| ✅| noscript | 783,604 | [[ https://gerrit.wikimedia.org/r/#/c/mediawiki/core/+/547674/ | gerrit ]]
| | ext.globalCssJs.user | 783,179 | T138727, T259047
| | ext.globalCssJs.user.styles | 783,177 | T138727, T259047
| | ext.uls.compactlinks | 747,326 | T237061
|✅| mmv.head | 378,848 | [[ https://gerrit.wikimedia.org/r/#/c/mediawiki/extensions/MultimediaViewer/+/547672 | gerrit ]]
|✅ | mmv.bootstrap.autostart | 378,845| [[ https://gerrit.wikimedia.org/r/#/c/mediawiki/extensions/MultimediaViewer/+/547672 | gerrit ]]
| | wikibase.client.init | 200,084 | T259048
| | mw.MediaWikiPlayer.loader | 103,683 | T217085
| | mw.PopUpMediaTransform | 102,323 | T217085
| | ext.tmh.thumbnail.styles | 102,322 | T217085
| | wikibase.ui.entitysearch | 102,041 | T259049
| | ext.wikidata-org.badges | 101,481 | T259050
| | wikibase.common | 97,583 | T259049
| | jquery.wikibase.toolbar.styles | 85,611 | T259049
| | jquery.ui.core.styles | 85,610
| | wikibase.ui.entityViewInit | 85,610 | T259049
|✅ | ext.popups | 82,738 | T236097
| | ext.citoid.wikibase.init | 82,524
| | wikibase.quality.constraints.suggestions | 80,423
| | propertySuggester.suggestions | 80,093
| | ext.3d | 76,091
| | filepage | 75,845
| | mediawiki.action.view.filepage | 75,844
| | ext.cx.eventlogging.campaigns | 74,886
| | ext.cite.ux-enhancements | 74,406
| | mediawiki.action.view.metadata | 53,789
| | ext.flaggedRevs.advanced | 40,314
| | mw.TMHGalleryHook.js | 34,020
| | ext.advancedSearch.init | 21,810
| | ext.advancedSearch.initialstyles | 21,810
|✅ | mediawiki.special.search | 21,810 | [[ https://gerrit.wikimedia.org/r/#/c/mediawiki/core/+/547673/1/resources/Resources.php | gerrit ]]
| | ext.scribunto.logs | 16,021
| | mediawiki.special.userlogin.login.styles | 12,910 | T211439
| | ext.charinsert | 12,849
| | ext.charinsert.styles | 12,849
| | mediawiki.action.edit.collapsibleFooter | 12,345
| | ext.CodeMirror | 12,332
| | mediawiki.special.userlogin.signup.js | 11,808 | T211439
| | mediawiki.special.userlogin.signup.styles | 11,808 | T211439
| | ext.TemplateWizard | 11,804
| | mediawiki.action.edit | 11,804
| | ext.wikiEditor | 11,793
### Acceptance criteria
[] When enabling modules ensure that they are needed by all pages. For example if code only runs on the login page, it should only run on the login page.
[] The new code should be compatible with the newer skins Minerva and Timeless. If not, it should check the skin and not add the module to these skins.
[] If the module is over 0.5kb it should use a bootstrap module before the targets is changed.
[] The correct loading strategy has been used
[] The correct performance strategy has been used
[] There is no (or a minor < 0.5kb) increase in JS or CSS on the critical path for an article page **on the mobile site** when enabling the module reported in the graphs on https://grafana.wikimedia.org/d/000000205/mobile-2g?orgId=1
### Loading strategies
1. If module should not run on mobile domain
Example would be mmv.head and ext.popups:
```lang=php,name=Server side
if ( ExtensionRegistry::getInstance()->isLoaded( 'MobileFrontend' ) && MediaWikiServices::getInstance()->getService( 'MobileFrontend.Context' )->shouldDisplayMobileView() ) {
// Add mobile specific modules
} else {
// MobileFrontend is not installed or you are in desktop so add desktop specific modules safely.
}
```
```lang=js,name=Client-side
if ( !mw.config.get('wgMFMode') ) {
mw.loader.using('desktopmodule');
} else {
mw.loader.using('mobilemodule');
}
```
2. If module should run only on mobile domain
Use the hook `MobileSiteOutputPageBeforeExec`
3. If module should run on all pages
Check the dependencies of the module.
Set the target to ['mobile', 'desktop']
### Performance strategies
1) Load module only on the page that needs it.
Certain modules only run on certain pages. For example, code may only be needed if a certain query string parameter is present or the user is on a certain special page. Where possible check for these things.
2) Load module on pages which have the feature using the strpos pattern
If a module progressively enhances an element that is sometimes and sometimes not in the page e.g.`<div class="feature"></div>`` using strpos check for the existence of the class before calling addModules
https://github.com/wikimedia/mediawiki/blob/fe598a9600/includes/skins/Skin.php#L210
3) Load larger modules on pages based on an interaction.
If code is only needed when something happens - e.g. if you click on X the rest of the code is loaded, the click pattern may be helpful.
This might be mixed with the bootstrap pattern (pattern #4) to prefetch code.
Echo does this to load code when the notifications icon is clicked:
https://github.com/wikimedia/mediawiki-extensions-Echo/blob/30dbae4c02/modules/ext.echo.init.js#L223-L244
4) Bootstrap pattern using mw.requestIdleCallback
For code which cannot be reduced and needs to be loaded on every page, you may want to follow the pattern of ext.popups and move JavaScript loading into an idle callback however the performance team there may be little to no benefit of doing this:
https://github.com/wikimedia/mediawiki-extensions-Popups/blob/9d72260851/resources/ext.popups/index.js