3

我实现了这个有趣的页面:

http://www.xthema.it/misc/christmas-matrix.html

我重试以三种不同的方式执行此操作,但每次我都无法使用 Firefox 获得良好的性能结果(我使用的是 17 版)。

  • 第一次尝试是每次为每个单元创建和删除 div。
  • 第二次尝试是在开始时预分配所有 div 单元格并仅更改字符和颜色
  • 第三次尝试(当前的尝试)是创建一个列 div,只在底部添加新的 div 单元格,并在角色下降结束时删除整个列。

在 Chrome、Safari 和 IE 上,结果总是很好,但在 FF 上却很慢。

有什么建议吗?有人知道 FF 在访问 DOM 或 CSS 方面的一些弱点吗?没有人可以推荐任何优化吗?

4

3 回答 3

1

首先和普遍的优化将使用requestAnimFrame。它应该与每个动画一起使用。

我在你的代码中看到的是很多 dom 操作。特别是您调用 createElement 数千次调用 drawFall。这很慢。尝试在绘制之前准备秋天,然后对其进行动画更改颜色,然后移除秋天。(所以尽量减少 createElement 调用的数量)此外,您还可以使用documentFragment,它也可以提供帮助。

另一个想法是使用 WebGL 来实现它,然而,这是完全不同的故事。

于 2012-12-18T17:45:40.343 回答
1

我找到了另一种可能的(超级)快速解决方案:

描述:取半透明的 png 并将其放在您的矩阵字母上,以便其中一些是半可见的。移动png。难以描述 - 易于遵循附加的 jsfiddle 上的快速'n'dirty 实现。

快速而肮脏的实施:(见http://jsfiddle.net/zbHne/

<html>
<head>
<style type="text/css">
#box{
  height: 100px;
  width: 300px;
  overflow: hidden;
  border:2px solid;
  background: #000;
}

</style>
<script type="text/javascript">
onload = function(){
  var el = document.getElementById("test");
  el.style.position = "relative";

  var x = -700;
  function fly(){
    x += 10;
    el.style.left = x + "px";

    if(x > -100){
      x = -700;
    }
  }

  setInterval(fly, 50);
}
</script>
</head>

<body>

<div id="box">
<div style="position: relative; width: 1000px; color: green">test of letterstest of letterstest of letterstest of letterstest of letters</div>
<div id="test"><div style="width: 1000px; height: 100px; background: url(layer.png); position: relative; top: -50px">invisible</div></div>
</div>

</body>
</html>

您应该创建适当的 layer.png 半透明图像才能使其正常工作。

于 2012-12-20T10:55:22.410 回答
0

我尝试使用 requestAnimFrame,但没有显着改进。

使用萤火虫探查器似乎缓慢的操作正在改变颜色

cellEl.style.color = br;

所以在这一刻,我发现的唯一解决方案是在 FF 上最小化调色板

// BRIGHTNESS0 is the MAX brightness value
// BRIGHTNESSSTEPS is the palette size

// i : 31 = n : BRIGHTNESS0
var i = Math.floor(n * 31 / BRIGHTNESS0);
// brightness inc = BRIGHTNESS0 / BRIGHTNESSSTEPS
var inc = 31 / BRIGHTNESSSTEPS;
i = Math.floor(Math.floor(i / inc) * inc);

var brHex = '#';
if (i < 16) {
  var d = i * 16 + i;
  brHex += '0' + Number(i).toString(16) + '0';
} else {
  i -= 16
  var o = Number(i).toString(16);
  brHex += o + 'f' + o;
}

...

在 FF 上,我不使用 32 渐变,但使用更少,如果颜色没有改变,我会跳过style.color分配。

var br = BRIGHTNESSTABLERGB[cell[1]];
if (cellEl.style.color != br)
  changeBrightness(cellEl,br);

这种方式稍微好一点。还有什么建议吗?

于 2012-12-19T06:46:41.697 回答