简体   繁体   English

CSS动画表现

[英]CSS animation performance

I have a small hobby project in which I try to build a matrix rain: 我有一个小业余爱好项目,我尝试建立矩阵雨: '矩阵雨' .

See demo here. 在这里看演示 Or this JSFiddle 或者这个JSFiddle

My question is: how can I make this more efficient, as I can see it gets slow when I add a lot of columns. 我的问题是:我如何才能提高效率,因为我可以看到当我添加大量列时它会变慢。

I have implemented it as rendering a lot of absolute positioned div s that are animated. 我已经将它实现为渲染了许多动画的absolute定位div

Here is my CSS: 这是我的CSS:

div
{
    position:absolute;
    width:1em;
    display:inline-block;
    color: black;
    animation-name: example;
    animation-duration: 2s;
    text-shadow: none; 
}

@keyframes example 
{
    0%   {color: white;  text-shadow: -1px 1px 8px white;}
    15%  {color: #5f5 ;  text-shadow: -1px 1px 8px #5f5 ;}
    100% {color: black;  text-shadow: none;}
}

In javascript I set some custom styling for each div , where I vary some settings, like font-size, animation speed etc. 在javascript中我为每个div设置了一些自定义样式,我改变了一些设置,如字体大小,动画速度等。

Main part of the JS: JS的主要部分:

var textStrip = ['诶', '比', '西', '迪', '伊', '吉', '艾', '杰', '开', '哦', '屁', '提', '维'];

var matrixcol = function()
{
    var top =  Math.floor(Math.random() * $(window).height() * 0.5);
    var size = 10 + Math.floor(Math.random()*10);
    var col =  Math.floor(Math.random() * $(window).width() - size);
    var ms  =  500 + Math.floor(Math.random()*1500);

            var timer;
    var aap = function()
    {
        var randomNumber = Math.floor(Math.random()*textStrip.length);

        var newelem = $("<div style='font-size:"+ size+ "px;top:"+top+"px; left:"+col+"px;animation-duration:"+ 2*ms + "ms'>" + textStrip[randomNumber] +  "</div>" );
        $('body').append(newelem);
        top+=size;
        setTimeout( function() {newelem.remove();}, (1.6*ms)-(ms/40)); 
        if (top>$(window).height()-size)
        {
            size = 10 + Math.floor(Math.random()*10);
            top=0; Math.floor(Math.random() * $(window).height() * 0.5);
            col =  Math.floor(Math.random() * $(window).width() -size);
            ms = 500 + Math.floor(Math.random()*1500);
                            clearInterval(timer);
            timer = setInterval(aap, ms/40);
        }
    }
    timer = setInterval(aap, ms/40);

}


$( document ).ready(function() {
   var i;   
   for (i = 0; i < 25; i++) {
       matrixcol();
}

I have tried to use the chrome profiling, that shows my a warning: 我试图使用chrome分析,这显示了我的警告:

Long frame times are an indication of jank and poor rendering performance. 长帧时间表示抖动和渲染性能差。

The link that is provided gives some insight; 提供的链接提供了一些见解; however, as far a I can see I don't have much layouting going on. 然而,就我所知,我没有太多布局。

tl;dr It is slow. tl; dr很慢。 What would be a good performance optimizations? 什么是良好的性能优化?

After several try, I think your best solution is looking to canvas, if the exact animation is desired. 经过多次尝试,我认为如果需要精确的动画,你最好的解决方案是寻找画布。

The ending result I get is here . 我得到的结果就在这里 Not as exact as yours but get a 50+ fps. 不像你的那么精确但得到50+ fps。 For every modification I have added comment, please check it out. 对于每次修改我都添加了评论,请查看。

Cache 高速缓存

The easiest thing you can do is cache $(window).height() . 你可以做的最简单的事情就是缓存 $(window).height() It is usually a stable number, no need to re-query it. 它通常是一个稳定的数字,无需重新查询。 And resize handler can be added to adapt viewport change. 并且可以添加resize处理程序以适应视口更改。 Cache window size changes my fps from 9~10 to 12~15. 缓存窗口大小将我的fps从9~10变为12~15。 Not big, but a low-hanging fruit. 不大,但是悬而未决的果实。

Expensive Style 昂贵的风格

The next thing you need to do is remove text-shadow , it is a very expensive style , given the node number in your case. 接下来你需要做的是删除 text-shadow ,这是一种非常昂贵的样式 ,给出你的情况下的节点号。 (Why? It requires CPU paints shadow and GPU cannot help here. read more here , and html5rocks ). (为什么呢?它需要CPU油漆阴影,GPU不能在这里帮助。读更多在这里 ,和HTML5ROCKS )。 If you are interested in Chromium implementation, text-shadow is done in TextPainter.cpp , painted by GraphicContext , which is done primarily by CPU. 如果您对Chromium实现感兴趣,则text-shadowTextPainter.cpp中完成,由GraphicContext绘制,主要由CPU完成。 And animating text-shadow is a performance nightmare. 动画文字阴影是一场表演噩梦。 Change this boost fps to 20+. 将此提升fps更改为20+。

DOM Access DOM访问

The last thing is DOM access, every frame update requires a dom insertion and, correspondingly, a dom removal by yet another timer. 最后一件事是DOM访问,每次帧更新都需要dom插入,相应地,还需要另一个计时器删除dom。 This is painful. 这很痛苦。 I try to reduce DOM removal , so I added a container for each column. 我尝试减少DOM删除 ,因此我为每列添加了一个容器。 And adding container does add DOM complexity, I have to wait for the animation end to update the container. 并且添加容器会增加DOM复杂性,我必须等待动画结束才能更新容器。 After all, it saves many dom manipulations, timers and closures. 毕竟,它可以节省许多dom操作,定时器和闭包。 Furthermore I updated setTimeout to requestAnimationFrame so that browser can orchestra DOM access better. 此外,我将setTimeout更新为requestAnimationFrame以便浏览器可以更好地管理DOM。

Combining the above three, I got a 50+ fps, not as smooth as 60fps. 结合上面三个,我得到了50+ fps,不像60fps那样平滑。 Maybe I can further optimize it by reducing DOM insertion , where all characters in a column is inserted once, and for each character the animation-delay is at interval. 也许我可以通过减少DOM插入来进一步优化它,其中列中的所有字符都插入一次,并且对于每个字符, animation-delay是间隔的。

Looking on Canvas 在画布上看

Still, your animation is quite harsh job for DOM based implementation. 尽管如此,对于基于DOM的实现,您的动画仍然非常苛刻。 Every column is updated, and text size varies frequently. 每列都会更新,文本大小会经常变化。 If you really want the original matrix effect, try canvas out. 如果你真的想要原始矩阵效果,请尝试画布

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM