Desktop vs. Mobile… an exploration of site delivery

So, I’m nearing the full beta release of a desktop site/webapp I’ve been building for awhile. And one thing I realized is that the design/UX of the site works great for desktop and probably is too much for most smartphones (maybe not ipads) to really be that usable. So, it occurs to me ways that I could rearrange and simplify (greatly) the UX (the JS and the CSS, and some of the HTML) for a better mobile experience.

Figuring out how to arrange a site more vertically (for mobile smartphones) and with less complication (more touch-friendly, instead of mouse oriented) is doable, and not really the point of this post. The point of this post is, given these two different site experiences, how should I serve them to different devices?

It’s clear that a smartphone (~320×480 type screen size) probably should get my mobile-optimized UX design. This means that there’s a whole bunch of CSS and JS for my desktop site that doesn’t need to be served to those devices (because that would be a lot of wasted bandwidth). Conversely, the mobile site will certainly have some CSS and JS that will only be for the mobile-optimized experience, and would be wasted/ignored for the desktop-optimized site.

But, what about the trend of “in-the-middle” devices like tablets. It’s pretty clear that a lot of them are nearly as capable as their desktop counter-parts. Capability aside, though, my primary concern is, will my desktop design UX be appropriate on a tablet? My guess is, yes, it’d be more appropriate than my slimmed-down mobile site UX design. So, for tablets, and for desktops, the default behavior should be the full site, and for the much smaller screens, the mobile design should be the default.

Notice I said default. I mean it. I’m only seeking to optimize the choice of the default experience. On BOTH versions of the site, a link will be present which will let someone manually toggle to change to the other experience. If my guess or default is wrong, the user will be able to switch. And do so with a cookie (if possible), so that the switch is remembered from then on.

So, what it comes down to is, I’m basically wanting to fork the two site versions based on screen dimensions (and to some extent, PPI resolution). The two site versions have some overlap, but it seems like there’s enough that’s unique to each, that one is not really a sub-set or super-set of the other. And for the sake of this discussion, let’s just assume that my desktop site is 300k (including ALL resources), my mobile site is 50k, and the overlap between the two is about 15k (content the same, some JS the same, a few images the same, etc).

So, what are my options?

  1. Full UA sniffing on the server, serving only one version of the site (300k) or the other (50k)
  2. Serve a big combined site (~335k) with content/css/js for both sites all being sent, and use CSS3 media-queries to simply show/hide various bits of content from each type of device/computer as screen geometry dictates. (AKA, “responsive design”, “responsive …”, etc)
  3. JavaScript logic served at first page-load, to determine screen geometry, and then take appropriate action to load the appropriate site content/css/js. (300k or 50k)

Pros/Cons

For (1), the obvious con is having to maintain a full UA sniffing. Why? because the server doesn’t know the screen size (not in the UA string). So, I’d have to construct (or use existing) UA sniffing logic for all the various mobile browsers… and moreover, I’d have to account for tablets in that checking, too. If the iPad were the only tablet, that wouldn’t be so bad. But there’s now dozens of different tablet models on the near horizon. That means lots of complicated UA sniffing to correctly identify each one/type.

And, it means committing to keeping up that UA sniffing for all new types of “in-the-middle” devices, making decisions individually based on each. For instance, is a 7″ device big enough? What about a 5″ or 6″ version of the same device (will it’s UA even be different)? What about the 9″ or 10″ versions? That’s going to mean LOTS of testing and maintenance overhead to get that right and keep it right going forward. Ugh.

But the big pro is, if the UA sniff (aka “guess”) is correct, the user only downloads exactly what’s necessary for their device. Mobile users get only 50k, and Desktop or “in-the-middle” users only get 300k.

For (2), the obvious con is the larger size of the full combined set of resources (335k). For a desktop, that’s about 12% more than it really needs. For mobile, though, that’s about 570% more than it really needs. Are there tricks to reduce the unnecessary loading? Sure. But the point is, a lot of HTML, and a lot of JS, and at least some CSS, will get loaded unnecessarily, especially in the mobile case, where bandwidth is likely to be more of a limiting factor. This just doesn’t feel like the right solution.

Another con is that media queries have good, but not universal, support. Namely, no IE supports it until IE9. That means all mobile IE’s are left out of the party. Unless you use something like Respond from Scott Jehl, which patches IE6-8 (and probably others) for media-query support, specifically for width/height geometry. But that adds a little extra weight (3.5k before gzip). So, it’s something to consider.

Of course, clearly the huge pro is that you avoid all UA sniffing and all the terrible junk that comes along with it.

For (3), the obvious con is that for non-JavaScript (like mobile devices that don’t have JS enabled), they’d basically be totally left out. Of course, a <noscript> tag could probably use some redirect (meta tag or manual <a> link) to give such a user a way forward. That’s workable, but it’s less than ideal. Then again, do I even care if my non-JS visitors can get to my site? For some sites, they don’t care. For me, however, I do care. I probably need a non-JS solution.

The pro is, like with (1), only one version of the site is served. And even more likely to be correct than in (1), with a lot less work/maintenance.

Bottom line, none of these 3 options is really great. I’m sure a lot of sites employ something like them for this type of functionality. But they all seem like they’re sub-optimal, for various reasons.

So what should I do?

Let me just say up front, I’ve not fully decided, nor do I really know for sure the best answer. This post is basically just to explain my experimental/explorative thoughts on the topic, and to solicit feedback from the community on what they think.

I got to thinking, what if CSS3 media queries could be used to do the checking on the screen’s size, and without any JavaScript, set a cookie that would let the server know which site version to serve, on the next refresh.

So, here’s how I might accomplish that.

  1. On first request to server, check if a cookie is set for site version. If so, respect it, and deliver the proper site directly. If not, use basic UA sniffing to identify mobile webkit and a few other well known mobile browsers. Don’t worry at all about device type, just identify common mobile browsers. If it seems like a mobile device from this coarse guess, serve up a “check” page. If not, assume the best, and serve up the full desktop site. Again, set a cookie for next time.
  2. In the “check” page, have a few bits of inline <style>, using CSS3 media queries, to do the screen geometrics testing. In each block, have it make a background-image request, with a particular parameter in it, indicating to the server the screen size category. The server then sets a cookie appropriately. In theory, only one of these two requests should go out, and if cookies are enabled, then it should identify it fairly reliably.
  3. Include a meta-refresh tag, and JavaScript redirect (just in case), and lastly an <a> link for the user to follow to refresh the page. If the cookie setting worked, this refresh should now serve the appropriate version of the site.

Gotchas

This idea is not perfect, by any means. There’s plenty of pitfalls.

For instance, if the browser doesn’t support cookies, this won’t work. Then again, for *my* site, I think I want to require cookies, so perhaps that’s not a deal breaker. I could detect cookie-setting failure, and display a message to the user that the site requires cookies to proceed. Or I could just default to either version of the site if the cookie setting failed, and just let the user figure out that it’s not gonna work as expected, in some respects.

Also, there’s the case where on mobile, there was a redirect that happened. This is an unfortunate extra delay/bandwidth/etc. But, I’m hoping that this refresh/redirect that occurs is less penalty than shoving 570% too much HTML/JS down the pipe on the first view.

What about if the browser doesn’t request background-images? Perhaps the CSS could also use content:after to create an <img> tag to force the request.

How do I force the meta-refresh/JS redirect/link clicking to “wait” for the cookie setting to occur after the background-image response comes back? For JS, this is easy, just poll for the image to finish loading. For the meta-refresh and the link clicking, not so much. There’s a few quirky ideas I could explore, but I’m not really entirely certain how to force this part to work correctly. But I’m also not convinced that it has no solution. And remember, it might only fail if the user doesn’t have JS… so as a fallback, the meta and links could always force one version (regardless of cookie), whereas the JS waits for the cookie, and does a refresh.

I’m sure there are other pitfalls I’m not realizing yet. I’d love to get some feedback from you, the reader. Am I crazy? Is this over architecting? Does this have promise? Will I fail?

Please, though, keep in mind a few things when providing feedback:

  1. Having already built the full site, and at least sketched out what the mobile site will look like, radical/significant changes to the design of either are not only impractical, but irrelevant. Please don’t comment if this is your suggestion. The spirit of what I’m asking is, making the best with my current situation, which is basically two site versions.
  2. UA sniffing is, in my opinion, generally evil. I want to avoid it as much as possible. I only introduce it in the above idea because it helps the “guess” and reduces to some extent how many people get the “check” page (and its delays, thereof). And, of course, the simple basic UA sniffing I’m talking about is orders of magnitude easier to write/maintain compared to full-blown UA sniffing.
  3. I am forking primarily based on my intended UX for small screens vs. big screens. I’m not forking for JS vs. non-JS, or because of low-powered/incapable devices, etc. I’m only forking based on screen geometry, because of its direct correlation to usability of layout.

That’s it. I hope to hear some great ideas. Thanks!