Page MenuHomePhabricator

Allow javascript modules to register themselves as suitable for mobile
Closed, ResolvedPublic

Description

Currently one of the things blocking porting ResourceLoader into the MobileFrontend extension is that javascript modules can be registered by any extension, many of which are not suitable for mobile or not applicable to certain pages.

The problem on mobile is it is essential payload is as small as possible due to the slower bandwidth and the fact that certain devices will refuse to serve the page if the payload is too huge.

I suggest that javascript modules should be able to register if they are suitable for mobile.

When initialising resource loader it should be possible for MobileFrontend to say "give me only the mobile optimised stuff". Any modules which have said they are mobile enabled should then be served. Anything which has not said anything should not be loaded.


Version: unspecified
Severity: enhancement

Details

Reference
bz40033

Event Timeline

bzimport raised the priority of this task from to Normal.Nov 22 2014, 1:06 AM
bzimport set Reference to bz40033.
bzimport added a subscriber: Unknown Object (MLST).

We've had this discussion before but I think going doing it that way leads to duplication and outdated code.

It is perfectly possible for code to work fine in both mobile and desktop. Only exceptional modules need to adapt their logic for module. And for those cases ResourceLoader already has the ability to serve mobile a special version built-in, and has had for a long time and it is about time we start using it.

'skinStyles' and 'skinScripts' (because essentially mobile is just a skin, eventually/ideally we might move to a situation where there is 1 consistent design across platform and the skin adapts itself, as opposed to being another skin class - but that's future talk).

The vast majority of modules that just add a button or link or implement backend logic (not even a UI) need to just be loaded without having to be marked as "mobile compatible" because that principle will not scale and fail.

When a module is encountered that is not mobile compatible, then file a bug report, so it will either be fixed or moved into a skin-specific module file that will naturally not be loaded in mobile skin.

MobileFrontend can start properly using ResourceLoader already without needing anything else.

Also, as said before, most "mobile" issues are not mobile issues. They are general issues affecting desktops and mobile the like. It is just that desktop users have somewhat gotten used to it.

Table based layouts, hover-dependent interaction etc. etc. those are never good. Not on desktop (window sizes, accessibility, etc.) and not on mobile. For different reasons maybe but it doesn't need mobile specific treatment or labels.

And solutions for those layouts must NOT be implemented in a "mobile" module, but in the general module.

Things like gadgets, site scripts, user scripts and simple extensions that add a sidebar link or core modules that add table sorting etc. those need to be just loaded without needing any mobile label, as-is.

I agree that "it is perfectly possible for code to work fine in both mobile and desktop" however the thing I'm trying to protect against is the situation where we enable resource loader and then have to spend time vigorously testing code on the mobile site.

There is also a danger that some code will just not be useful on mobile.

  • For instance on the desktop when hovering over a reference a popup shows - hover effects will not work on mobile therefore this code is adding bloat.
  • Personally I think mobile feedback in it's current form is not suitable for mobile - it needs to be presented in a different way as on a mobile device in its current form it takes up a lot of real estate. This in itself is a huge task on the article feedback extension and would delay resource loader migration.

Trying to QA and improve all existing extensions would be a mammoth task and the migration would never be done as we would be forever blocked by issues in javascript modules which break or do not work on obscure mobile devices. We can do this but this is not an agile way of doing things.

In the interest of moving forward quickly I therefore believe it is vital that we have some mechanism to whitelist/blacklist modules. I had suggested extensions registering themselves as mobile suitable but a whitelist/blacklist in a config file would also do.

I see things working like this:

  1. Migrate to full blown resource loader with all javascript modules disabled.
  2. Review modules and vigourously test them one mondule at a time raising and fixing blocking bugs
  3. Enable modules when confident they work across mobile devices AND make sense on a mobile device.

Not doing this would be a recipe for disaster and from experience will take much longer than it needs to.

The problem is that the module manifest being provided to mobile would include
lots of modules, many of which are not appropriate for mobile. This is a large
amount of data on a mobile phone that's purged every 5min on the client - that
sucks.

The solution to this problem is simple:

  1. Add a "target" option to module registration

1.a) Omitting the target option will result in only the "default" target being
used
1.b) Specifying a target will exclusively provide the module to those targets
1.c) Target can be an array, allowing a module to target both "default",
"mobile" and others
1.d) There is intentionally no way to provide a module to all targets without
specifying their names to ensure that future targets are able to start fresh

  1. Passing a "target" URL parameter to load.php will trigger the startup module

to only send a module manifest that includes modules that match that target
2.a) Make Startup module include resources/startup.[target].js files and move
non-generic stuff out of resources/startup.js (and possibly organize this stuff
into resources/mw.startup/ or something)

  1. Add target options to mobile modules
  1. Modify mobile front-end to include the startup module, and use the target

parameter

"target" is basically just a disarmed version of isMobileFriendly (since boolean options are evil by design[1], target = mobile === isMobileFriendly = true). The implementation Trevor describes sounds pretty straight forward and clean, I like it.

However until we give it a bit more thought I'm still a bit on the fence with this. Especially with:

  • dependencies
  • inline mw.loader.using calls
  • cross-wiki dependencies
  • registry of "targets" (freeform? registry? hook?)
  • not to mention cross-source (cross-wiki) loading and using.

There is a big can of worms packed in a grid of pandora boxes being tickled here. We need to step back and really look at the bigger picture here.

I haven't spend as much time on mobile as I'd like, but I have observed so far and feel that there is a mind set in mobile right now that is leaning on wanting too specific treatment that when given into as-is we will regret, doesn't scale and is encouraging bad design.

A module isn't just a bunch of CSS and visually-related javascript. There is a lot of logic in modules these days. Take modules like 'jquery.byteLength' and 'jquery.colorUtil' for instance. Those need to be registered without anything fancy and available everywhere. And that should be the default for each and every module.

If a module is skin-specific then it needs to implement its components skin-specific as well, its that simple. It can choose to provide a fallback for unknown skins or it can decide to only load in known skins. That's all already possible. Some modules would have to be fixed to get a uniform design that is better everywhere or it may need skin- or browser-specific sub components. Note that skin-specific module components are only loaded in the skin needed, this does not bloat output or response size.

Call me extreme, but modules that rely on hover (for example) may be shot on sight with questions asked later. That is not acceptable, anywhere. We can completely disregard "mobile" from that (very valid) user interface problem.
The few characters in the stylesheet addressing ":hover" are unlikely a problem as the bulk of hover-type interaction is the declarations inside the rule (not the selector). For example the actions menu in MediaWiki can be triggered by hover, and alternatively on focus or click. The styles for this come at no cost because the styles are shared (e.g. x:hover { .. } -> x:hover, x.opened, x:focus { .. }). Even if one could or would optimize on that, I'd say don't (in order to keep related things together for ease of maintenance) and perhaps it can even become significant in the (far, potential) future (e.g. detection where the finger is hovering close over the screen - nothing better than getting new functionality for free when an app is correctly designed in the past).

Mobile isn't a single tangible environment, it is a combination of factors (device orientation, screen dimension, user input method, browser software, device component APIs (cam, mic, filesytem, location services, ..)), that define it together. They are factors on their own and different subsets of those apply to other environments as well. We need to make sure we properly cover or drop out for those factors as needed. And an "environment", "target" or "canDoMobile" parameter is imho not the solution for this, not by a long shot.

Here's a quick list of factors that we as front-end developers can miss when developing code that ideally would support all of the below. Could lead to covering for cases separately (mouse-mode, touch-mode), or implementing some cases and properly avoiding others (eg. touch-only) or by some universal implementation that works on both (e.g. a simple UI button or logic code like jQuery.Callbacks):

Availability and/or convenience of:

  • a mouse
  • touch
  • keyboard (e.g. keyboard shortcuts are impossible or unpleasant on iOS devices, though copy/paste exists native)
  • audio/video input
  • location services
  • device orientation
  • window orientation & size (most mobile devices only support maximized windows)
  • device resolution
  • which version is implemented of the specification of HTML, CSS and/or JS
    • and bugs they introduced when doing so
    • in other words any version of any browser ever developed that as of writing does not support the latest standards completely (old IE, old Firefox, old mobile browsers, bugs in newer IE..., bugs in old IE)

What I'm getting at is that there are so many things (listed above) we now know about the web and how it is used, that we all have learned to take care of, such as

  • compatibility with IE6 and other old browsers (feature-detection, polyfill, give up etc.)
  • usability
  • accessibility (keyboard access, touch access, mouse access)
  • semantics (screen readers)
  • etc.

"mobile" does not belong in this list, but the individual factors that apply there do. And just to hypothesize a bit, say we do have a "target: mobile" property we can set. What would that even mean? What mobile devices, browsers and versions? What are the requirements to make it "mobile-able"?

Assuming we won't implement a "target" for certain versions of IE or for being "accessibility proof", we shouldn't for "mobile" either.

As with all factors, we develop the best we can. And when stuff fails, we patch it to detect the previously unanticipated case and work around it by adding support or changing the code to not get there in those cases. We do so for IE6 and accessibility too. And even at those we're not 100% there.

[1] off-topic:

But regardless, the "target" approach has won the vote.

This has been implemented a while ago and has been alive and deployed since.