ResourceLoader/Writing a mobile friendly ResourceLoader module

shortcut: RL/M
From mediawiki.org

This document provides guidance on developing ResourceLoader modules to run in mobile site as provided by the MobileFrontend extension. When building JS/CSS we need to think carefully about when and if to load code because:

  1. Many modules were not designed nor tested to run on mobile. Loading them can severely impact the user experience and sometimes make parts of the site unusable.
  2. On mobile the screen resolution can vary greatly - many beautifully designed modules will not function on mobile if they are specifically designed for a desktop screen.
  3. Many features available on desktop are not available on mobile (many product managers might descope mobile as part of their deliverables)
  4. Reducing payload - many mobile users are on slow internet connections - adding modules to the mobile experience can increase the time for users to load.
  5. The mobile CSS/JavaScript landscape is very different from desktop. Many of the user interaction methods are different - for example hover event behaves very differently or is nonexistent.

Styling for mobile first[edit]

By default you should style for mobile and use the following rules:

  • Restrict your design to a 320px screen, maybe simplifying the user interface where needed.
  • Use % widths and em's - avoid using pixels as much as possible!
  • If you need to use px's make sure they are no bigger than 50px.
  • Use media queries to style for desktop. Adapt your design when the minimum width of the screen is 768px. This will make your design look good on mobile, tablet and desktop screens.
/* width-breakpoint-tablet is a global LESS variable which defines the threshold when to invoke tablet styles */
@import 'mediawiki.skin.variables.less';
@media ( max-width: @max-width-breakpoint-tablet ) {

Note good web practice states that you should have good fallbacks for non-JavaScript users. There are variety of reasons why you should care about non-JavaScript experiences and if the crucial functionality of your feature is not working on mobile, it's probably time to go back to basics and make sure it does.

Why did mobile turn my ResourceLoader modules off by default prior to MediaWiki 1.41?[edit]

Prior to MediaWiki 1.41, MobileFrontend required modules to explicitly enable themselves on mobile via a targets property. This allowed time for code written prior to the mobile era, to adapt themselves to the new platform that was mobile devices.

By breaking an experience, the intention was to trigger the developer to make a decision. Namely that decision is 1) Do I do the bare minimum to get it working 2) Do I rethink my feature for mobile 3) Do I support only desktop mode (and make that obvious to the user) or 4) Do I leave my feature broken.

By January 2024, we decided this was no longer necessary and in fact had become a problematic anti-pattern so this behaviour was removed. The default behaviour led new products to build themselves as desktop only features or features for mobile friendly features as mobile. Note, we still do notload common scripts or MediaWiki:Common.js/css as these were designed without mobile in mind - many of the rules are not useful for mobile screens and greatly increase the payload.

If you see ResourceLoader modules with "targets" please consider submitting a patch or reporting an issue pointing to this Phabricator ticket for reference: https://phabricator.wikimedia.org/T328497

Why is my desktop code not working on mobile?[edit]

If you've noticed it is broken, you care and can think about it. Making breakage less obvious could have the adverse effect of your feature staying broken (given it is relatively trivial in most cases to get it work).

The reason it could be broken might be one of the following:

  • Some modules may not have been built with mobile in mind and could cause a mobile browser to crash due to heavy CPU usage. e.g. a maps based application.
  • An interface built ten years ago may have been built with desktop devices in mind, and may require a desktop experience e.g. it might optimise for viewing with a resolution of at least 600px
  • Sometimes a completely different experience is warranted. You can decide to give a completely different experience to your mobile site users by conditionally loading a different code path. For instance a photo curation tool might work better on mobile devices if it has a swipe left/swipe right interface rather than a table experience on desktop.
  • Certain key interface elements may not be easily clickable on mobile - for instance a list of search results which is less than 40px (Haven't been designed for the fat finger)
  • Making a site mobile friendly is not necessarily a case of slapping some media queries on to it - another approach would be to make your site mobile first and rethink your feature altogether.
  • In mobile we care a lot about resources loaded. We are trying our darn hardest to shrink the size of assets down as far as possible to give our users in countries with slower connections the best possible experiences. As a result we only allow standard JavaScript libraries and standard styles for interface elements as decided by the ux standardisation project.
  • If your module uses jquery.ui - it's time to rewrite it. On mobile it would be irresponsible to load jquery.ui and oojs.ui when both libraries solve similar problems.

Making your modules mobile friendly[edit]

Decide if you should (important!)[edit]

Just because you can you must decide whether this is worthwhile.

  • Will people on mobile really use your module?
  • It is useful to slow down the mobile experience by providing this module?
  • IS there some other library already enabled for mobile that does this thing already. For instance if you are styling a button, why not use the mediawiki.ui.button library in core?

If you are not sure it is suggested that you start a conversation on the wikitech-l mailing list and also gather feedback from the communities that will use your module.

If your module comes with a large amount of client side code it is a good indication that your module probably needs rethinking or not applying to mobile. Compare your module to the jQuery library - if it is bigger than that or even near to its size you are probably doing the wrong thing.

An alternative approach may be to present a message in your display saying "This tool only works on desktop. Please switch to desktop view to use this."

Consider using a lightweight bootstrap module with several lines of code which decides whether it should run

if ( window.innerWidth > 700 ) {
  // in desktop mode!
  mw.loader.using('mymodule')
} else {
  doFallback();
}

Decide when to load the module[edit]

Are you loading the module under the right circumstances? For instance if your module enhances the editing experience - make sure you only add that module when the user is on an edit page. You should be extremely careful about adding modules to pages as each module comes with a download penalty.

Testing your modules[edit]

  • At minimum you should test on the following browsers on real mobile devices (not emulators!):
    • Chrome
    • Safari
    • In-app Chrome and Safari
  • The MediaWiki JavaScript API is currently much smaller than the desktop API. Ensure that your modules do not use anything that is not available.
  • Many MediaWiki-based projects should work on as many devices as possible.
  • Note the increase in CSS or JS before and after the change. Is it minor? If not what can be adjusted in the code to make it more lightweight.
  • Review any dom parsing - this is expensive. When adding click handlers you may want to consider $(document).on('click', '#mybutton', callback) pattern to avoid use of querySelectorAll.
  • Some things to test in the styles themselves?
    • Do floats only get enabled on tablet and higher? e.g. via a media query. Floats rarely work on mobile screens and will need to be scoped to tablet and desktop.
    • Are any widths fixed? How will these degrade on a mobile resolution? Fixed widths in general should be avoided, but where necessary they should be scoped to tablet and desktop via a media query.
    • Are any font sizes fixed? How will these change as the user zooms in and out of the mobile device? Font sizes generally should be defined in terms of em, rem and %.

Targeting mobile devices[edit]

The mobile skin on Wikimedia servers runs on the Minerva skin, however it's worth noting you can also get the Vector skin in mobile and the Minerva skin in desktop. It's thus not helpful to have the mindset "I only want to run this code on mobile".

When targeting mobile devices think about features available, e.g. DOM elements on the page OR think in terms of how the browsers available viewport. How does your feature work at 320px? How does it work at 720px? What happens if the DOM element #caEdit is not present on the page?

As a last resort you can also check the existing skin:

if ( mw.config.get( 'skin' ) === 'minerva' )

but this should only be used in circumstances where something specific to the skin is required for the feature to work.