9

When adapting a web page for mobile devices I always rely on css media queries.

Recently I no longer worry only about the screen size, but also the javascript engine of many mobile devices. Some common javascript effects that rely on window scrolls or a quick sequence of DOM transformations work really bad on slow devices.

Is there any way to guess the device performance so I can enable/disable elements that look bad on slow devices?

So far I can only think of bad solutions:

  1. screen size. narrow screen "might" mean slow device
  2. user agent information. I could look at the device, browser or cpu, but that does not seem a stable long term solution because of the amount of devices to consider

UPDATE: Fixed my question to focus on one problem. In the comments there is a good solution for the touch interface problem.

SystematicFrank
  • 16,555
  • 7
  • 56
  • 102
  • What will you do differently if the browser is too slow? – Gabe Sep 15 '12 at 12:54
  • 2
    What do you think about an inverse approach: Finding fast browsers and enable effects for them - this could be done using a user agent query on Webkit, Firefox and recent Internet Explorers. – Gregor Sep 15 '12 at 12:56
  • @gabe I would disable some elements. For example those dynamic navigation bars that pop up when you scroll past the header look terrible. Also image galleries with animated transitions are not fluid, I would disable the image transition. – SystematicFrank Sep 15 '12 at 12:59
  • Just an observation but the native android browser can do hover events. It seems to have a concept of an invisible mouse cursor that is placed at the last touch location - so hover can be simulated by touching with a small drag to prevent a click. Not ideal and certainly not universally supported but worth knowing – Basic Sep 15 '12 at 13:09
  • You could perform some DOM operations and time them. Not perfect I know and you'd need to make sure it doesn't impact the page unduly but it might give you a fairly accurate idea of the speed of the client when manipulating elements – Basic Sep 15 '12 at 13:11
  • @gabe I updated the question to make it more generic. Look the UPDATE section. Your idea about an inverse approach is good today, but in the future there will be a combination of slow and awfully fast mobile devices. Therefore it does not seem a good stable long term solution. – SystematicFrank Sep 15 '12 at 13:11
  • 1
    This covers the hover question: http://stackoverflow.com/questions/4643443/how-do-i-detect-whether-a-browser-supports-mouseover-events – Matt Whipple Sep 15 '12 at 13:19

3 Answers3

3

The only way I could think of would be to run some kind of speed test in JS in the background either before or while using the effects. This should catch devices that are slow due to their processor speed or vice versa, catch devices that are time accurate/fast. However if the devices have optimisations meaning they use different processors to calculate graphical effects, this will not work.

var speedtest = function(){
  /// record when we start
  var target = new Date().getTime(), count = 0, slow = 0;
  /// trigger a set interval to keep a constant eye on things
  var iid = setInterval(function(){
    /// get where we actually are in time
    var actual = new Date().getTime();
    /// calculate where we expect time to be
    target += 100;
    /// 100 value here would need to be tested to find the best sensitivity
    if ( (actual - target) > 100 ) {
      /// make sure we aren't firing on a one off slow down, wait until this
      /// has happened a few times in a row. 5 could be too much / too little.
      if ( (++slow) > 5 ) {
        /// finally if we are slow, stop the interval
        clearInterval(iid);
        /// and disable our fancy resource-hogging things
        turnOffFancyAnimations();
      }
    }
    else if ( slow > 0 ){
      /// decrease slow each time we pass a speedtest
      slow--;
    }
    /// update target to take into account browsers not being exactly accurate
    target = actual;
    /// use interval of 100, any lower than this might be unreliable
  },100);
}

Of course by running this you'll affect the speed of the device as well, so it's not the best solution really. As a rule I tend to disable animations and other superfluous things simply when the screen is small.

One other downside to this method - that I've experience before - is that one certain browsers that implement multi-tabbed environments setIntervals are automatically limited to a certain speed when the tab is not being viewed. This would mean for this browsers tabbing away would automatically downgrade their experience - unless this imposed speed limited could be detected some way.

Pebbl
  • 34,937
  • 6
  • 62
  • 64
  • I like your code, but as you said, it has some downsides. Also I am not very convinced about using speed tests as a good design approach. On the other hand, it looks like there is no such thing as a good solution :( – SystematicFrank Sep 15 '12 at 13:51
  • Yeah no worries, I wouldn't use this approach myself in production, I just like experimenting with JS. On the other hand you do always have an alternative... You could ask the user, or at least expose some kind of control, that would allow them to disable the fancy parts if they don't want them. I know many users who would like to disable the graphical extras even on desktop viewing. – Pebbl Sep 15 '12 at 18:35
3

It certainly seems as though there is no particularly good solution for this issue (which would make sense since this type of stuff is normally supposed to be the type of stuff that's hidden away). I think either way your best starting with UA detection to take care of those platforms that are known to fall into one category or another. Then you'd have 2 options to flexibly adapt to unknown/uncertain platforms:

  1. Progressive Enhancement: Start with a stripped down test and load a small performance test or tests to gauge the device performance and then load the files for the appropriate enhancements. Test such as already provided or at: Skip some code if the computer is slow

  2. Graceful Degradation: Wrap those features that are candidates for causing unfavorable UX on slower devices in a higher order function that replaces them if they take too long on first execution. In this case I'd probably add it to Function.prototype and then allow an acceptable delay argument to be chained on to the function definition. After the first invocation store the time lapsed, and then on the second invocation if the time lapsed is over the delay swap out the function with a fallback. If the time elapsed is acceptable then remove the profiling code by swapping in the standard function. I'd need to sit down and work out sample code (maybe this weekend). This could also be adjusted by additional arguments such as to profile multiple times before swapping.

The first option would likely be the friendlier option, but the 2nd may be less intrusive to existing code. Cookies or collecting further UA data would also help from continuing to profile after information is retrieved.

Community
  • 1
  • 1
Matt Whipple
  • 7,034
  • 1
  • 23
  • 34
  • I like the idea of graceful degradation since I believe that a "heavy" widget can itself be a speed test. I asked about detecting slow devices when what I really wanted was to detect if some widget was running too slow in the client. The problem with other speed test solutions is that after getting a numerical result, one must find a threshold of what is acceptable or not. – SystematicFrank Sep 18 '12 at 07:30
  • no worries, I got very clear how to implement that. For me it is complicated the detail of every case and how to react fast enough, otherwise the user must experience at least once a UI glitch – SystematicFrank Sep 18 '12 at 12:23
  • That would be one of the downsides, depending on what the UI enhancements are (and what the first triggered one is), there may be no way around having one noticeable jump. I'd just say just add a message that slides in briefly from the top or bottom saying something like "optimizing settings for your device" so the user knows that this is a feature and not one or more bugs. – Matt Whipple Sep 18 '12 at 12:34
1

You could make your own mini benchmark of sorts. Do some demanding calculations and time the result. If it's slower than the device you consider to be slowest supported device then you drop to a less intensive version of your site.

You could also just make an easily accessible link to switch to the more basic site if the user is experiencing performance issues.

Going off screen size is not a good idea. Plenty of modern phones have small screens with fast processors.

DWilliams
  • 451
  • 8
  • 22
  • Imo going on screen size is acceptable if all you are doing is graceful degradation of non essential superfluous "magic" :) - but yep, for anything else you'll hamper the user experience as phones and tablets improve over time. – Pebbl Sep 15 '12 at 18:39