【问题标题】:Javascript Rendering Animations on HTML5 DOM from Array. First Run SLOW! Second Run Smooth. How come?Javascript 在 Array 的 HTML5 DOM 上渲染动画。第一次运行慢!第二次运行平稳。怎么会?
【发布时间】:2012-06-28 02:17:31
【问题描述】:

我有一个关于使用 DOM 在 HTML 中通过 javascript 动画的问题。在这种情况下,我使用绝对位置和 css + jQuery 并为 div 设置动画。

因此,当我运行大量位置 x,y 时,动画运行非常缓慢。我以 100 毫秒(80 毫秒)的间隔运行,但似乎渲染速度不够快,我的动画耗时超过 10 秒...

重新运行动画时,似乎指令已被某种方式缓存(渲染)并且我的动画运行得非常完美。

如果我再等 5 分钟,它会再次变慢。 (好像是低级机器码内存被删除了,因为没有再使用?)

如果我的动画是第一次执行,我只是不知道如何让我的动画顺利运行。 我尝试使用 fabric.js 来渲染动画......同样的问题。在第一次运行它很慢。第二轮和后续都很顺利。

function render_mouse()
 {
     if(play_pos < mousefile_length)
         {
            $('.mouse').remove();
            $("body").append(
            $('<div id="mouse" class="mouse"></div>')
            .css('position', 'absolute')
            .css('top', play_mousefile[play_pos+1] + 'px')
            .css('left', play_mousefile[play_pos] + 'px')
            .css('width', mousesize)
            .css('height', mousesize)
            .css('background-image', 'url(images/cursor.png')
                    );
            play_pos = play_pos +2;
            }
    else {
        clearInterval(play_mousetimer);
         }
   }

UPDATED:
 $('#mouse').animate({
                 left: rec_mousefile[play_pos]+"px",
                 top : rec_mousefile[play_pos+1]+"px"
                 },80);

【问题讨论】:

  • 在此处发布您的代码将有助于解决问题
  • 邮政编码。到目前为止,我最好的猜测是您正在尝试实时栅格化图像,而不是使用精灵。
  • 这里是渲染鼠标的函数:pastebin.com/8gswL79R 我将 remove 替换为 animate x,y pos。但仍然存在同样的问题
  • pastebin.com/PtuwrfRB 使用 jQuery animate 的较新版本。
  • 原始代码如此缓慢的部分原因是因为您每次都删除并插入 DIV。 IIRC,每次这样做都会导致回流。

标签: javascript html dom animation canvas


【解决方案1】:

如果不是每次都对鼠标 div 做这么多的操作,动画会更快。

基本上,将鼠标附加到 dom 一次,以及初始渲染所需的所有 CSS,缓存对附加元素的引用,然后仅操作动画所需的 css 属性。

通过将元素保留在 dom 中,而不是每次都删除并重新添加,您应该会看到一点性能提升。此外,保存对附加元素的引用将防止您在进行另一次更新之前必须重新查询 dom。

由于缓存,动画在第二次运行时应该总是快一点,但这些优化应该至少有助于初始运行。

**根据评论进行编辑**

您可以在函数外部缓存对鼠标 div 的引用,或者将其挂在渲染函数本身之外,例如:

var mouseDiv = $('#mouse');

function render_mouse()
{
    if(mousefile_length > play_pos)
                {
                 mouseDiv.animate({
                 left: rec_mousefile[play_pos]+"px",
                 top : rec_mousefile[play_pos+1]+"px"
                 },80);

                 play_pos=play_pos+2;
        }
   else {playtimer.stop();}
}

function render_mouse()
{
    // query the first time, and then use the cached version thereafter
    render_mouse.mouse = render_mouse.mouse || $('#mouse');
    if(mousefile_length > play_pos)
                {
                 render_mouse.mouse.animate({
                 left: rec_mousefile[play_pos]+"px",
                 top : rec_mousefile[play_pos+1]+"px"
                 },80);

                 play_pos=play_pos+2;
        }
   else {playtimer.stop();}
}

【讨论】:

  • 感谢您的建议。我已经在 pastebin 中发布了更新的代码。它使用动画。我正在按照你在这里所说的那样做。第一次执行它时仍然很慢。二、三等运行平滑渲染。
  • 明白了。您仍然可以在函数外部缓存对鼠标 div 的引用,或者将其挂在函数本身之外,这样您就不必每次都使用 $('#mouse') 来选择它。我将发布一个代码示例。
  • 再次感谢。我像你说的那样更新了我的代码。仍然有性能问题。您说“由于缓存,动画在第二次运行时应该总是快一点,但这些优化应该至少有助于初始运行。”是否有可能以某种方式预先缓存动画?我真的需要它像第二次运行一样快。
  • 我想可以先尝试在隐藏的 div 中运行动画。说,可见性:隐藏而不是显示:无。这仍然会使包含元素占用 dom 中的空间(display:none 基本上将其从流程中移除)。我猜大多数浏览器会足够聪明,以至于这个技巧不起作用,但值得一试。或者,您可以尝试将鼠标从屏幕上移开,为其设置动画,然后将其放回到实际动画的正确位置。
  • 再次感谢。我试过这个,但对执行速度没有影响。似乎无法解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 2018-11-03
  • 1970-01-01
  • 2020-03-28
相关资源
最近更新 更多