1. CSS Filters in the Real World

    Filter effects landed in WebKit quite some time ago, but it’s never easy to find an application in the real World for the new CSS hotness, so I never had the chance to actually experiment with them. When I finally did, I certainly did not expect that it would come at a cost…

    I really wanted to fiddle around with filter effects in a proper, real World context. A few weeks ago, I decided to tweak our modal box script to add a blur effect to the overlay. How complicated could that be? I simply applied a blur class to an element wrapping the entire site (except the modal box itself) to blur the contents of the page sitting below the modal box:

    .blur {
      -webkit-filter: blur(5px);
    }

    And here is the expected effect (with and without blur):

    Blur effect causes performance drops

    We sat down with the graphic designer and the UX designer, played around with it a little and thought “this is pretty cool, let’s keep it!”.

    Then, as I am pretty concerned by the performance of our front-end, I ran a quick benchmark of the paint time of the page, which is a good indicator of how smooth the experience will be. I turned on “Enable continuous page repainting” in the Chrome developer tools and watched what was happening as I was switching on and off the filter property in the inspector.

    Blur effect causes dramatic performance drops

    On the left of this graph, blur is on, with a very high painting time of approximatively 250 ms. In the middle of the graph we can see that for a few seconds I disabled the effect, causing the painting time to drop down to 40 ms. On the right of the graph, I reapplied the effect and the painting time went up again to its initial value. The lower the paint time, the better the scrolling experience and responsiveness of the user interface will be.

    Results were staggering: the performance drop was so extreme that I’m not sure we could implement the blur effect at the scale of a full page (which was our case). Scrolling was slow, and even typing in form fields felt sluggish.

    So I thought I’d force hardware acceleration to help with rendering performance. I used the translate3d(0, 0, 0) trick (works with translateZ(0) as well):

    .blur {
      -webkit-filter: blur(5px);
      -webkit-transform: translate3d(0, 0, 0);
    }

    And it worked! My system, which was struggling to perform processing-heavy operations in the browser without hardware acceleration on a 24 inches monitor, was suddenly performing very well with hardware acceleration turned on. As a result, the experience felt a lot smoother, but a major problem remained…

    While testing in Windows 7, the lovely Serena Rizzo, QA maestro, found out that an element wasn’t rendered properly. The blur effect was causing a select box to render rather strangely:

    Blur effect causes undesired rendering bug on select boxes with Chrome in Windows 7

    This kind of visual bug is a deal breaker, and we had to drop the blur effect after all…

    After experimenting a little bit more with other filter effects, I could also witness rendering bugs when using the drop-shadow filter in Safari 6 and Chrome 26 on some macs, and I would advise against its use for the time being.

    I guess some of the very advanced CSS goodness is still not suited for use in production websites (even with a progressive enhancement approach), but it shouldn’t keep us from trying to implement cutting-edge properties if they enhance the user experience.

    To make sure your code isn’t affecting badly the paint times and as a result, the experience, you can start learning more about how browsers work internally and most of all, know your tools.

    Edit 17/04/2013: Colt McAnlis wrote an article published on HTML5 Rocks about evaluating the impact of CSS properties on front-end performance: CSS Paint Times and Page Render Weight.

Notes

  1. kaelig posted this