ResourceLoader/Writing a MobileFrontend friendly ResourceLoader module

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
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.
 * Note that media queries are not supported in IE6,7,8. Either don't worry about this or use a JavaScript shim to pull in those styles for those browsers.

Why does mobile turn my ResourceLoader modules off by default?
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.

There is a good reason why that we decided to turn ResourceLoader modules off by default. "We want you to think about mobile."

By breaking your toy, we force you 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.

Provided your answer is not 4, your answer is acceptable :-)

We broke `your toy` because:
 * By breaking your feature it forces you to think about mobile experiences. 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).
 * 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. Using  you can decide to give a completely different experience to your mobile site users. 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.
 * We don't load 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. We were also not keen for existing users to have the mobile site explode in front of their faces due to assumptions made by these scripts e.g. I am on Vector and this DOM element is available.

Decide if you should (important!)
Just because you can you must decide whether this is worthwhile. If you are not sure it is suggested that you start a conversation on the mobile-l mailing list and also gather feedback from the communities that will use your module.
 * 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 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

Decide when to load the module
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.

Enabling your existing modules
First things first make define the  property on the module you want to enable ensuring its dependencies are also available in mobile. If your dependencies are in core and don't set targets you will need to stop using them first. Set it to  AND desktop. This ensures your module can run in mobile and desktop target modes.

Here is an example used to enable CentralNotice for mobile.

Testing your modules

 * 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
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: but this should only be used in circumstances where you want to blacklist the skin to avoid support.

Experimenting with mobile
You can experiment with mobile by making use of a user script/style in your username space:

User:YourName/minerva.css, User:YourName/minerva.js

Note that if you want to run code on all mobile skins (e.g. also on Vector skin in mobile ) use:

User:YourName/mobile.css and User:YourName/mobile.js