1

As an example, on a laptop that has a large screen, but no dedicated graphics card, the rule:

.menu-item:hover {
    filter: blur(5px);
}

lags significantly, but it's not easy to target with just a @media (max-width: 600px) or @supports query.

Ideally, it would be amazing to have something like

@performance ("good enough to handle whatever it is in question") {}

or if the @supports media query took performance into account.

Does such a thing exist? Or is there any way to work out something analogous?

Matt Gross
  • 45
  • 1
  • 8

2 Answers2

3

JavaScript could do something like requestAnimationFrame and time the FPS during animations (using event registration on transition/transitionEnd and animation/animationEnd) then if framerate deemed too low, it could apply a style such as:

*, *:before, *:after {
    transition-property: none !important;
    transform: none !important;
    animation: none !important;
    /* ... */
}

But a CSS-only option that targets low-power laptops... my recommendation would be to first try this trick:

-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);

That will make sure it ends up using the dedicated graphics card if available. It might be enough to get the performance up.

You may also want to look at @keyframes which will help when the framerate is inconsistent.

Graeme Wicksted
  • 1,770
  • 1
  • 18
  • 21
  • Unfortunately in the case of filters, the translate3d trick doesn't do enough. Edit: Wouldn't the js way of detecting framerates require the transition to run at least once before it triggered? – Matt Gross Dec 16 '17 at 20:30
  • @MattGross you are correct - it (or some form of animation/filter) would have to run at least once and could default to disabled if you have a high number of low powered devices connecting. If the menu items you're blurring are static, you could pre-blur them and use CSS sprites. Alternatively, there are additional CSS options and canvas tricks available. See the answers here: https://stackoverflow.com/questions/31713468/css-blur-filter-performance – Graeme Wicksted Dec 18 '17 at 15:43
  • unfortunately the blur was supposed to happen dynamically when clicking a button (we're blurring out the rest of the page when a menu is activated, then un-blurring when it's de-activated). – Matt Gross Dec 18 '17 at 18:25
2

You can detect most browser features with Modernizr for example. Take a look at the documentation to see what you can detect.

However, there is no truly reliable way to detect the hardware via either CSS or JavaScript. You could try to detect FPS like illustrated here: calculate FPS in Canvas using requestAnimationFrame

I have found some code on GitHub that may work for you:

var canvas = document.createElement('canvas');

var gl;
var debugInfo;
var vendor;
var renderer;

try {
  gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
} catch (e) {
}

if (gl) {
  debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
  vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
  renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
}

// Sample output:
//
// » console.log(renderer);
// ATI Technologies Inc. AMD Radeon R9 M370X OpenGL Engine

It detects the graphics hardware vendor name via WebGL, so obviously it requires a browser with WebGL support. If that's no problem for you, this may well do what you need.

Regarding a CSS-only solution I'm afraid you're out of luck.

herrbischoff
  • 3,294
  • 1
  • 29
  • 50
  • This seems like a pretty big hole in web technologies, especially with the advent of phones that rival some older laptops, and lightweight workstations that don't have a ton of graphics power. @herrbischoff With this approach, wouldn't you need to have a fairly extensive list of graphics cards? – Matt Gross Dec 16 '17 at 20:37
  • As the common graphics chips themselves are made by just a handful of companies (ATI, Nvidia, Intel) this should not be too hard to do with a regex or string match. I haven't tested the code, so the results on mobile devices may be very different. If what you want to know is whether the graphics chip is a dedicated one or shares memory with the CPU, you would indeed have to maintain a specialized list. However, as mobile devices are always SoC, the distinction between integrated vs. dedicated wouldn't get you very far there anyway. – herrbischoff Dec 17 '17 at 09:59
  • Most of the modern built-in graphics are quite powerful. It would only be very low-end hardware (or a very busy system) that could not process a blur in a reasonable amount of time. The full list would be quite extensive (over 1000 models) and might impact load time of the site itself. A blacklist might be a better option although getting the official names would require some work. Perhaps https://www.videocardbenchmark.net/low_end_gpus.html – Graeme Wicksted Dec 18 '17 at 15:38
  • I'm currently getting the poor performance on a 2014 MBPro, I think it has Intel's integrated 4000 series. It's pretty safe to ditch the style on mobile, but something like a new iPad Pro has better graphics rendering than the mbp. Looks like it'll be tricky regardless. – Matt Gross Dec 18 '17 at 18:46
  • Given the Intel Integrated 4000, I would bet that the problem is more in the amount of separate items you are trying to blur than the hardware you're doing it on. The 4000 is plenty powerful for effects like these, given you're using 3D acceleration in the style @GraemeWicksted suggests. – herrbischoff Dec 18 '17 at 21:04