title: CSS3 filter performance & CPU usage: Why do certain filters tax the CPU?
body: <p>Consider this demo from <a href="https://zunostudios.com/blog/development/170-css-effects-convenience-at-a-price" rel="noreferrer">David Nuon</a>:  </p>
  
  <p><a href="http://zunostudios.com/demos/css32014-demos/filters.html" rel="noreferrer">http://zunostudios.com/demos/css32014-demos/filters.html</a></p>
  
  <p>As David notices in his post:   </p>
  
  <blockquote>
    <p>You'll notice that the more the sliders are to the right, the less
    responsive the page becomes.</p>
  </blockquote>
  
  <p>And that is true. After I altered the image, I saw how my CPU began to work a lot.   </p>
  
  <p>What I could not answer to myself is WHY after all the css modifications the page is so unresponsive. Like all the animations are 2fps.</p>
  
  <p>If the job is done why it keeps working? </p>
  
  <p><strong>Edit:</strong>
  With the help of xengravity I could see that maybe after all the filters are to the right it seems that the GPU does the following at an insane rate:      </p>
  
  <p>1.- takes the original image.<br>
  2.- modifies it (math calculations, blabla, etc). </p>
  
  <p>But always starting from the original image. Maybe thats why it seems all so slow....</p>
  
  <p><strong>Edit: Added demo into a snippet for future posterity</strong>
  <div class="snippet" data-lang="js" data-hide="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>   var update_filter = function () {
   
      
      var styles  = [
  
      'grayscale( ' +  parseInt($('#grayscale').val()) * .01 + ')', 
      'blur( ' +  $('#blur').val() + 'px)', 
      'sepia( ' +  $('#sepia').val() + '%)', 
      'brightness( ' +  parseInt($('#brightness').val()) * .01 + ')', 
      'contrast( ' +  $('#contrast').val() * .1 + ')', 
      'hue-rotate( ' +  $('#hue-rotate').val() * 3.6 + 'deg)', 
      'invert( ' +  $('#invert').val() + '%)', 
      'saturate( ' +  parseInt($('#saturate').val()) * .1 + ')', 
      'opacity( ' +  parseInt($('#opacity').val()) * .01 + ')', 
  
  
      'drop-shadow( ' +  (function (n) { 
  
        return '0px ' + 
               '0px ' + 
               n + 'px ' + 
               'black)'; } 
        )($('#drop-shadow').val()) , 
     ];
  
      var styles = '-webkit-filter:\n' + styles.map(function (e) { return '\t' + e;} ).join('\n') + ';';
     
      $('#image').attr('style', styles);
      $('#code').val(styles);
     };
  
     $('#reset').click( function () {
  
      $('#grayscale').val(  $('#grayscale').data('default') );
      $('#blur').val(  $('#blur').data('default') );
      $('#sepia').val(  $('#sepia').data('default') );
      $('#brightness').val(  $('#brightness').data('default') );
      $('#contrast').val(  $('#contrast').data('default') );
      $('#hue-rotate').val(  $('#hue-rotate').data('default') );
      $('#invert').val(  $('#invert').data('default') );
      $('#saturate').val(  $('#saturate').data('default') );
      $('#opacity').val(  $('#opacity').data('default') );
      $('#drop-shadow').val(  $('#drop-shadow').data('default') );
  
      update_filter();
  
  
     });
  
     $( 'input[type="range"]').change(update_filter );
  
     update_filter();</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>body, html {
    background: #fff;
   }
   
   .wrapper {
    width: 800px;
    height: 400px;
  
    background: #fff;
  
    border-radius: 5px;
    position: relative;
    margin: 60px auto 0 auto;
  
   }
  
   .controls {
    background: #ddd;
    
    width: 250px;
  
    position: absolute;
    right: 0;
    bottom: 0;
    top: 0;
   }
  
   .image {
    background: url(transparency.png);
    
    width: 550px;
  
    position: absolute;
    left: 0;
    bottom: 0;
    top: 0; 
   }
  
   .controls {
    padding: 0 0 0 0;
   }
  
   .controls li {
    list-style: none;
    margin: 0;
    padding: 5px 15px;
   
    border-bottom: 1px solid #aaa;
   }
  
   .controls li span {
    font-size: 13px;
  
   } 
   .controls li span::after {
    content: '()';
   }
  
   .controls li input {
    color: #333;
  
   
    float: right;
   }
  
   #code {
    position: absolute;
  
    left:0;
    right: 0;
    bottom: -155px;
  
    border:0;
  
    font-family: monospace;
   }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"&gt;&lt;/script&gt;
  &lt;div class="wrapper"&gt;
    &lt;div class="image"&gt;
     &lt;img id="image" src="http://i.imgur.com/WdIGZ1t.png" alt=""&gt;
    &lt;/div&gt;
    &lt;div class="controls"&gt;
     
  
   &lt;ul class="controls"&gt;&lt;li&gt;
   &lt;span&gt;blur&lt;/span&gt; 
    &lt;input type="range" id="blur" min="0" max="100" value="0" data-default="0"&gt;
   &lt;/li&gt;
   
   &lt;li&gt;
   &lt;span&gt;grayscale&lt;/span&gt; 
    &lt;input type="range" id="grayscale" min="0" max="100" value="0" data-default="0"&gt;
   &lt;/li&gt;
   
   &lt;li&gt;
   &lt;span&gt;drop-shadow&lt;/span&gt; 
    &lt;input type="range" id="drop-shadow" min="0" max="100" value="0" data-default="0"&gt;
   &lt;/li&gt;
   
   &lt;li&gt;
   &lt;span&gt;sepia&lt;/span&gt; 
    &lt;input type="range" id="sepia" min="0" max="100" value="0" data-default="0"&gt;
   &lt;/li&gt;
   
   &lt;li&gt;
   &lt;span&gt;brightness&lt;/span&gt; 
    &lt;input type="range" id="brightness" min="0" max="100" value="100" data-default="100"&gt;
   &lt;/li&gt;
   
   &lt;li&gt;
   &lt;span&gt;contrast&lt;/span&gt; 
    &lt;input type="range" id="contrast" min="0" max="100" value="10" data-default="10"&gt;
   &lt;/li&gt;
   
   &lt;li&gt;
   &lt;span&gt;hue-rotate&lt;/span&gt; 
    &lt;input type="range" id="hue-rotate" min="0" max="100" value="0" data-default="0"&gt;
   &lt;/li&gt;
   
   &lt;li&gt;
   &lt;span&gt;invert&lt;/span&gt; 
    &lt;input type="range" id="invert" min="0" max="100" value="0" data-default="0"&gt;
   &lt;/li&gt;
   
   &lt;li&gt;
   &lt;span&gt;saturate&lt;/span&gt; 
    &lt;input type="range" id="saturate" min="0" max="100" value="10" data-default="10"&gt;
   &lt;/li&gt;
   
   &lt;li&gt;
   &lt;span&gt;opacity&lt;/span&gt; 
    &lt;input type="range" id="opacity" min="0" max="100" value="100" data-default="100"&gt;
   &lt;/li&gt;
  
   &lt;li&gt;&lt;button id="reset"&gt;Reset&lt;/button&gt;&lt;/li&gt;
   
  
    &lt;/div&gt;
    &lt;textarea id="code" cols="20" rows="11"&gt;&lt;/textarea&gt;
   &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>