Page MenuHomePhabricator

Remove inline Wikipedia.org Portal CSS code
Closed, DeclinedPublic

Description

The wikipedia.org portal page currently utilized inline CSS, which increases page size for users (including users on bad or very slow connections) and makes it impossible to easily distinguish between mobile and desktop traffic.

Let's convert the current inline CSS into separate files so that mobile users aren't having to load the desktop styles and we can get a good understanding of how much traffic we have from different platforms to the portal page.

Event Timeline

debt created this task.Feb 26 2016, 2:37 PM
Restricted Application added subscribers: StudiesWorld, Aklapper. · View Herald TranscriptFeb 26 2016, 2:37 PM
debt triaged this task as Normal priority.Feb 26 2016, 2:37 PM
debt moved this task from Backlog to What's Next on the Discovery-Portal-Sprint board.

First off, I'm not sure how loading the CSS from a separate file will give us insight on mobile traffic. I'd like some more clarity on what exactly analytics is looking for to distinguish mobile traffic from desktop. I would assume we'd be able to just parse user agent headers from the HTTP requests to determine who's on what device (like we do with event-logging), but the existence of this ticket tells me this is not the case.

If we were to just "remove the inline CSS" and put it into a single separate file, this wouldn't provide any benefit to anyone, mobile or otherwise. It wouldn't make the page any lighter, since everyone would still have to load all the CSS, just from a separate file (and it would just add an extra http request, which mobile users on slow connections would feel the most).

I think what this ticket is trying to get as is that we should have a separate CSS file for mobile and desktop users. This task is not as simple as just removing inline CSS, and has some challenges and repercussions that I'll discuss below.

The CSS is currently architected to target desktop by default, with media query added in to target mobile devices. This means that everyone downloads the same desktop CSS, and if they happen to have a small screen, they activate the extra 'small screen' CSS. The alternative is to take a 'mobile first' approach, where the default CSS targets small screens, and then extra media queries are added to target desktops. The 'mobile first' approach would involve a significant refactor of our CSS, but it's a mostly positive change, except that old desktop browsers that don't understand media queries (basically IE8 & below) will be given the mobile experience. Whether or not this is acceptable is up for debate.

We can theoretically separate the CSS into two files, one for mobile and one for desktop, like so (I just discovered this):

<link rel='stylesheet' media='all ' href='mobile.css' />
<link rel='stylesheet' media='screen and (min-device-width: 480px)' href='desktop.css' />

But, as it turns out, all browsers, mobile and desktop, still download both files. We can alternatively load separate CSS for desktop using javascript, but that approach is very fragile and slow. Even if the above approach did work, it would load desktop CSS for anything wider than 480px (are iPads mobile?). Also, because of the nature of CSS, (i.e. cascading style sheets) the desktop CSS would still largely dependant on the mobile CSS, so we would load both mobile + desktop CSS for large devices.

In summary, I don't see a clear client-side only way of loading mobile CSS only for mobile, and desktop CSS only for desktop.

Well, if both will download both this won't actually help :/. What we'd do on literally any other part of Wikimedia's infrastructure is rely on the fact that the platform detection in our varnish caches redirects people to *.m.* as appropriate, which it doesn't do for the portals. I was seeking to distinguish the files so we could also look for file download, but if both files are going to be grabbed anyway that won't actually do much :(. Ah well.

If CSS is turned off, will the browser still download the link'd css file? If not, this will allow us to 1. estimate % that have CSS enabled, and 2. make portal load even faster for someone who has CSS and JS turned off.

As for the initial motivation behind this (to let us estimate % of mobile vs % of desktop users), I wonder if we can include (or if there is already) a mobile-specific property that gets applied to an element, and then we can use JS to check if that element has the property, and then send that flag to the event logging schema? Thoughts, @Jdrewniak?

@Ironholds your right this particular page presents a unique challenge in detecting mobile, as it's one of our very few responsive properties & doesn't get redirected with varnish.

@mpopov loading a mobile only asset is an interesting approach. There is a CSS and a JS way of doing this, but both are less than ideal.

1.) the CSS way
We could load a fake or small 1byte asset inside of a CSS media query like so:

@media all and (max-device-width:960px) {
    .some-selector {
        background-image: url( assets/img/only-loaded-on-mobile.png ); 
    }
}

This would load the assets on devices that have a screen width smaller than 960px, This width encompasses most if not all current mobile & tablet devices in portrait mode, but some tablets are 1280 in landscape, and most are 1024, which could be the max-width of desktops as well.

2.) the JS way
There aren't any mobile only dom or element properties that I can think of that would accomplish this in JS. The only reliable JS way of doing this would be to do our own user-agent parsing on the page, and then load the 'mobile-only' asset if the user-agent matches a known mobile string. Given the very similar sizes of desktops and mobile mentioned above, this would be more reliable in determining a mobile device, but it would be JS only, and we know we have some "not insignificant" non-js mobile usage :/

p.s.
I don't see a problem with loaded the CSS externally for the purposes of seeing who uses CSS and who doesn't. It will load faster for non-css users, although, I do wonder how many of those are out there (even screen-readers parse some css).

@JGirault any thoughts on this?

debt added a comment.Feb 29 2016, 8:17 PM

@Ironholds and @mpopov - this is looking like it'll be a ton of work just to determine, from the client side, which of our visitors to the portal page are from a desktop browser vs mobile browser.

I'm not sure that we want to tackle this work at this time. Please let me know your thoughts.

@Ironholds your right this particular page presents a unique challenge in detecting mobile, as it's one of our very few responsive properties & doesn't get redirected with varnish.
@mpopov loading a mobile only asset is an interesting approach. There is a CSS and a JS way of doing this, but both are less than ideal.
1.) the CSS way
We could load a fake or small 1byte asset inside of a CSS media query like so:

@media all and (max-device-width:960px) {
    .some-selector {
        background-image: url( assets/img/only-loaded-on-mobile.png ); 
    }
}

Smart method :)

This would load the assets on devices that have a screen width smaller than 960px, This width encompasses most if not all current mobile & tablet devices in portrait mode, but some tablets are 1280 in landscape, and most are 1024, which could be the max-width of desktops as well.

And very good and valid concerns :)
Note that we could check the orientation as well as max-device-width, though it's not reliable :D (iOS devices don't work the same as other devices...).
Note also that max-width is different than max-device-width, so supposedly reliable as I don't think there are still many desktops with a max-device-width < 960px (total assumption)

I don't think this method is reliable.

2.) the JS way
There aren't any mobile only dom or element properties that I can think of that would accomplish this in JS. The only reliable JS way of doing this would be to do our own user-agent parsing on the page, and then load the 'mobile-only' asset if the user-agent matches a known mobile string. Given the very similar sizes of desktops and mobile mentioned above, this would be more reliable in determining a mobile device, but it would be JS only, and we know we have some "not insignificant" non-js mobile usage :/

I prefer this option, though as you say it is JS-only.
There are methods like https://github.com/gfranko/jquery.selectBoxIt.js/blob/master/src/javascripts/jquery.selectBoxIt.js#L69-L78 that seems to do most of the job right.

This method is reliable, *though* it only gives a representation of mobile VS desktop *within* the JS population, which is better than nothing (93%, of users, right?) and helpful at least to track the dynamic (desktop traffic decreasing vs mobile traffic increasing) .

p.s.
I don't see a problem with loaded the CSS externally for the purposes of seeing who uses CSS and who doesn't. It will load faster for non-css users, although, I do wonder how many of those are out there (even screen-readers parse some css).

I think CSS should be a requirement to use the page. Gonna jump on the conclusions, but I'd say it's too bad for those who don't enable CSS (not worth penalizing CSS users with an extra request and round trip in my opinion).
Supporting non-CSS users is like supporting absolutely all browsers.
I think we should ignore unless we have a very specific interest in displaying the page in a certain way without CSS.

mpopov added a comment.EditedFeb 29 2016, 11:53 PM

So here's what I meant:

test.html:

<html>
<head>
	<link rel='stylesheet' media='all ' href='mobile.css' />
	<link rel='stylesheet' media='screen and (min-device-width: 480px)' href='desktop.css' />
</head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="test.js"></script>
<body>
	<div id="platform_identifier">Visual indicator (optional)</div>
</body>

</html>

mobile.css:

#platform_identifier {
	color: red;
}

desktop.css:

#platform_identifier {
	color: blue;
}

test.js:

$(document).ready(function() {
	if ($("div#platform_identifier").css("color") == "rgb(255, 0, 0)") {
		console.log("mobile device");
	} else {
		console.log("desktop device")
	}
})

Yields the following detection results for a (simulated) mobile and desktop devices:

@mpopov That's assuming ONLY desktop devices satisfy the rule: min-device-width: 480px and I don't think it's a fair assumption.

That's fair. Julien, what's your idea?

I have to think a bit more, because for now I am not sure if a viable 100% CSS solution is actually possible...

I actually like the JS method to detect mobile, though:

There are methods like https://github.com/gfranko/jquery.selectBoxIt.js/blob/master/src/javascripts/jquery.selectBoxIt.js#L69-L78 that seems to do most of the job right.
This method is reliable, *though* it only gives a representation of mobile VS desktop *within* the JS population, which is better than nothing (93%, of users, right?) and helpful at least to track the dynamic (desktop traffic decreasing vs mobile traffic increasing) .

I want to precise on "seems to do most of the job right". We might not detect some mobile devices, but we should "really" be catching "most of them".

Jdrewniak added a comment.EditedMar 1 2016, 10:43 AM

here's another thought. As @Ironholds pointed out, for nearly all other wikimedia properties, varnish does the UA parsing and redirects mobile users to an m-dot domain. Could we get varnish do the UA parsing for this page without doing the redirect?

for everything else but portal, varnish does this:

                   mobile? -> en.m.wikipedia.org
                  /
request --> varnish         
                  \
                   desktop? -> en.wikipedia.org

For the portal, I'm assuming varnish just does this:

request--> varnish -> desktop -> wikipedia.org

could we get it to do this?

                   mobile? -> wikipedia.org
                  /
request--> varnish         
                  \
                   desktop? -> wikipedia.org

Essentially just using it to log mobile traffic?

Again, I have no idea if this is a feasible, desirable, or even a smart thing to do, and it would require a lot of ops work, but it would certainly be the most reliable approach.

@Gehel given your newfound varnish knowledge, does the above approach make any sense?

Jdrewniak added a subscriber: Gehel.Mar 1 2016, 3:32 PM
JGirault added a comment.EditedMar 1 2016, 6:01 PM

@Ironholds , @mpopov , here's an idea: Can we parse the user-agents of the requests that go to the portal page?

On http://reportcard.wmflabs.org/, we have graphs to show mobile traffic vs desktop traffic so I'm assuming we might be able to do something similar.

We have a table webrequest in Hive that contains the User-Agent.
We have both the raw user_agent, and a user_agent_map that contains already parsed information.

In Varnish this is how we parse the User-Agent https://github.com/wikimedia/operations-puppet/blob/production/templates/varnish/text-frontend.inc.vcl.erb#L22-L23 (at least this is what I found).

I'm not too comfortable with these traffic metrics, but I think this (distinguish between mobile and desktop traffic) can be achievable simply by looking at the user agent in hive, without any changes to the current page.

mpopov added a comment.Mar 1 2016, 6:43 PM

We have a table webrequest in Hive that contains the User-Agent.
We have both the raw user_agent, and a user_agent_map that contains already parsed information.

Right, but building a thorough list of "this is what a mobile user agent contains" is the issue in that case.

debt closed this task as Declined.Mar 1 2016, 9:26 PM

Closing this as declined at this time - I'll write a different ticket to handle how we deal with mobile users when they get to www.wikipedia.org (to not automatically forward to en.wikipedia.org).