Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using CSS box-shadow for pulse animation eats considerable CPU

There was a requirement of showing a pulse animation over a label so as to highlight outstanding notifications. I came across this while researching online and have implemented the same. It works well, however, when the label is pulsing, the CPU usage is at a constant 50% while normally there is hardly anything. I would like to understand what or why this is happening, and if possible, a fix.

CSS:

.pulse {
   /*margin:100px;*/
   display: block;
   /*width: 22px;*/
   /*height: 22px;*/
   /*border-radius: 100%;*/
   background: #cca92c;
   cursor: pointer;
   box-shadow: 0 0 0 rgba(204,169,44, 0.4);
   animation: pulse 2s infinite;
 }

 .pulse:hover {
   animation: none;
 }

 @-webkit-keyframes pulse {
   0% {
     -webkit-box-shadow: 0 0 0 0 rgba(204,169,44, 0.4);
   }
   70% {
       -webkit-box-shadow: 0 0 0 10px rgba(204,169,44, 0);
   }
   100% {
       -webkit-box-shadow: 0 0 0 0 rgba(204,169,44, 0);
   }
 }

 @keyframes pulse {
   0% {
     -moz-box-shadow: 0 0 0 0 rgba(204,169,44, 0.4);
     box-shadow: 0 0 0 0 rgba(196,33,61, 0.85);
   }
   70% {
       -moz-box-shadow: 0 0 0 10px rgba(204,169,44, 0);
       box-shadow: 0 0 0 10px rgba(204,169,44, 0);
   }
   100% {
       -moz-box-shadow: 0 0 0 0 rgba(204,169,44, 0);
       box-shadow: 0 0 0 0 rgba(204,169,44, 0);
   }
 }

html:

    <a class="dropdown-toggle" data-toggle="dropdown" id="alertingDashboardDropdown" href="#">Alerts Dashboard
                    <span class="label {{alertCount.totalOpenAlertsLabelClass}} dropdown-subscript-white pull-right">{{alertCount.totalOpenAlerts}}</span>
                </a>
.
.

{{alertCount.totalOpenAlertsLabelClass}} basically returns "label-primary pulse"

like image 352
blueren Avatar asked Dec 12 '25 14:12

blueren


1 Answers

This happens because you are using box-shadow which is not very good for animations because it will trigger a repaint.

You can check here what properties trigger layout, paint and composite changes.

The best ones are opacity and transform, maybe you can change your animation to use those.

EDIT: Created 2 jsfiddle, one with box-shadow and another one with transform. I have edited your code but you can check the performance, study it, understand the changes and adapt it to your needs.

How I did it:

Added a :before pseudo-element that will have the animation running under the number. will-change: transform; tells the browser that the element's transform will change and the browser optimizes it.

.pulse {
  position: relative;
  display: inline-block;
  width: 22px; 
  height: 22px;
  line-height: 22px;
  border-radius: 100%;
  background-color: #cca92c;
  text-align: center;
  cursor: pointer; 
}

.pulse:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%; 
  height: 100%;
  background-color: #cca92c;
  border-radius: 100%; 
  z-index: -1;
  animation: pulse 2s infinite; 
  will-change: transform;
}

.pulse:hover:before {
  animation: none;
}

 @keyframes pulse {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  100% {
    transform: scale(2);
    opacity: 0;
  }
 }
<a class="dropdown-toggle" data-toggle="dropdown" id="alertingDashboardDropdown" href="#">
  <span>Alerts Dashboard</span>
  <span class="pulse">5</span>
</a>
like image 93
Ricardo Ribeiro Avatar answered Dec 14 '25 03:12

Ricardo Ribeiro