Chrome for android lags down after many setInterval

ぐ巨炮叔叔 提交于 2020-01-25 08:08:12

问题


I was trying this demo for one of my application but one of a touch screen TV is using android tablet 6.0.1 and it really lags after multiple clicks. Im suspecting due to the setinterval script there.

https://codepen.io/ShawnCG/pen/ZYVada

Here is the main javascript from that demo.

var d = document, $d = $(d),
    w = window, $w = $(w),
    wWidth = $w.width(), wHeight = $w.height(),
    credit = $('.credit > a'),
    particles = $('.particles'),
    particleCount = 0,
    sizes = [
      15, 20, 25, 35, 45
    ],
    colors = [
      '#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5',
      '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#4CAF50',
      '#8BC34A', '#CDDC39', '#FFEB3B', '#FFC107', '#FF9800',
      '#FF5722', '#795548', '#9E9E9E', '#607D8B', '#777777'
    ],

    mouseX = $w.width() / 2, mouseY = $w.height() / 2;

function updateParticleCount () {
  $('.particle-count > .number').text(particleCount);
};

$w
.on( 'resize' , function () {
  wWidth = $w.width();
  wHeight = $w.height();
});

$d
.on( 'mousemove touchmove' , function ( event ) {
  event.preventDefault();
  event.stopPropagation();
  mouseX = event.clientX;
  mouseY = event.clientY;
  if( !!event.originalEvent.touches ) {
    mouseX = event.originalEvent.touches[0].clientX;
    mouseY = event.originalEvent.touches[0].clientY;
  }
})
.on( 'mousedown touchstart' , function( event ) {
  if( event.target === credit.get(0) ){
    return;
  }
  mouseX = event.clientX;
  mouseY = event.clientY;
  if( !!event.originalEvent.touches ) {
    mouseX = event.originalEvent.touches[0].clientX;
    mouseY = event.originalEvent.touches[0].clientY;
  }
  var timer = setInterval(function () {
    $d
    .one('mouseup mouseleave touchend touchcancel touchleave', function () {
      clearInterval( timer );
    })
    createParticle( event );
  }, 1000 / 60)

});


function createParticle ( event ) {
  var particle = $('<div class="particle"/>'),
      size = sizes[Math.floor(Math.random() * sizes.length)],
      color = colors[Math.floor(Math.random() * colors.length)],
      negative = size/2,
      speedHorz = Math.random() * 10,
      speedUp = Math.random() * 25,
      spinVal = 360 * Math.random(),
      spinSpeed = ((36 * Math.random())) * (Math.random() <=.5 ? -1 : 1),
      otime,
      time = otime = (1 + (.5 * Math.random())) * 1000,
      top = (mouseY - negative),
      left = (mouseX - negative),
      direction = Math.random() <=.5 ? -1 : 1 ,
      life = 10;

  particle
  .css({
    height: size + 'px',
    width: size + 'px',
    top: top + 'px',
    left: left + 'px',
    background: color,
    transform: 'rotate(' + spinVal + 'deg)',
    webkitTransform: 'rotate(' + spinVal + 'deg)'
  })
  .appendTo( particles );
  particleCount++;
  updateParticleCount();

  var particleTimer = setInterval(function () {
    time = time - life;
    left = left - (speedHorz * direction);
    top = top - speedUp;
    speedUp = Math.min(size, speedUp - 1);
    spinVal = spinVal + spinSpeed;


    particle
    .css({
      height: size + 'px',
      width: size + 'px',
      top: top + 'px',
      left: left + 'px',
      opacity: ((time / otime)/2) + .25,
        transform: 'rotate(' + spinVal + 'deg)',
        webkitTransform: 'rotate(' + spinVal + 'deg)'
    });

    if( time <= 0 || left <= -size || left >= wWidth + size || top >= wHeight + size ) {
      particle.remove();
        particleCount--;
      updateParticleCount();
      clearInterval(particleTimer);
    }
  }, 1000 / 60);  
}

I have changed the jquery to gsap for the same animation. So instead of $(element).css(), im using Tweenlite.set()

Is there a way hardware speed up the browser for this sort of animation?

Any help would be appreciated.


回答1:


The biggest performance hit is because you're using DOM elements. If you were to use <canvas> for your particles instead, it would perform much better (you could get hundreds or thousands of particles without much of a performance risk if you wanted to).

However, you can make this DOM animation much more performant than it is currently. The biggest thing to change is to use transforms instead of top and left. In GSAP you can do that by affecting the x and y properties. You should also use transform's scale instead of affecting width/height. In GSAP you should also set the rotation instead of the actual transform itself (it generates the property transform for you). I also recommend using GSAP's .set() method instead of jQuery's .css(). For even more performance, use GSAP's .quickSetter() method.

Using GSAP's .delayedCall instead of setInterval will also be more reliable. Even better, use gsap.ticker() and call all of the update functions from within that!

Altogether you get this demo.

Other optimizations could be done, such as reusing the same particles and not creating/destroying the old ones, but the performance is about at its cap in terms of DOM animation. Like I said at the beginning, this sort of thing is perfect for <canvas>.



来源:https://stackoverflow.com/questions/59392482/chrome-for-android-lags-down-after-many-setinterval

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!