【问题标题】:WebKit browsers slow to update canvasWebKit 浏览器更新画布很慢
【发布时间】:2013-06-05 10:32:58
【问题描述】:

我在 javascript、Canvas 和 Chrome/Safari 中创建了一个简单的二进制时钟,即使我每秒多次在画布上绘图,但它每秒只更新一次屏幕。

FireFox 会在我绘制到画布的瞬间进行更新,我认为我的代码是高效的(活动监视器显示,在动画运行时浏览器正在使用 5% 到 10% 的单个 CPU 内核)。

如何让 webkit 浏览器更频繁地更新?我的实际代码在 jsfiddle:

http://jsfiddle.net/mqGKR/

但基本上这就是我正在做的事情:

function updateCanvas()
{
  if (!canvasNeedsUpdating()) {
    return;
  }

  var ctx = blockView.getContext("2d");
  ctx.clearRect(0, 0, width, height);

  if (canvasNeedsFill()) {
    ctx.fillStyle = "rgba(255,255,255,1.0)";
    ctx.fillRect(0, 0, width, height);
  }

  window.setTimeout(updateCanvas, 10);
}

【问题讨论】:

  • 我确认您的发现。最近几个 webkit 版本的画布性能很差,也有一些意想不到的故障。 :(
  • 试一试...如果您使用 canvas.width=canvas.width 而不是 ctx.clearRect 清除它会加快速度吗?
  • @markE 我试过了,但没有帮助。我不认为这是性能问题,我认为这是 WebKit 中的故意行为。

标签: javascript performance canvas webkit


【解决方案1】:

哇。这很奇怪。

这与画布无关。它与您的 BinaryTime 类有关。至少 Chrome 和 Firefox 之间的 Date 对象的功能存在一些差异。

beginningend 在 FireFox 中是 13703184000001370404800000。每次。大概这就是您想要查看 cmets 的内容。

它们在 Chrome 中每次都在变化,这意味着它们绝对不会像您的 cmets 建议的那样代表今天早上的午夜和今晚的午夜。

换句话说,Chrome/webkit 中的 Date 对象出现已损坏。但它更准确。它在 Firefox 中以更微妙的方式不太准确,但现在让我们专注于修复。 (今晚晚些时候,我会一边对着一桶冰淇淋哭,一边提交一些错误报告。

但 Chrome 在这里做的是正确的事情,因为您调用 setMilliseconds 并且 chrome 尊重这一点。 Firefox 变得很奇怪并且做错了事,但它恰好是你想要的。

所以无论如何,最简单的方法是使用 setHours 和所有四个参数:

// init "beginning" timestamp as midnight this morning
var beginning = new Date();
beginning.setHours(0, 0, 0, 0);
beginning = beginning.getTime();

// init "end" timestamp as as midnight tonight
var end = new Date(date);
end.setHours(0, 0, 0, 0);
end.setDate(end.getDate() + 1);
end = end.getTime();

我现在就这么做。工作示例:

http://jsfiddle.net/wvR6H/

稍微复杂一点的问题是,在 Chrome/WebKit 中,您需要也设置毫秒:

blah.setMilliseconds(0);

您也需要在 FireFox 中进行设置,因为您现在正在编写代码,因此您正在利用一种 Firefox 错误。如果你有beginning = new Date(),它也会在 Firefox 中被“破坏”,换句话说,它有一个空的构造函数。例如见这里:http://jsfiddle.net/VbWnk/

碰巧 Firefox 中的 new Date(new Date()) 会为您减少毫秒数。实际上,公平地说,IE 的工作方式相同,因此 Chrome/Webkit 是一个奇怪的结果。 ECMAScript 规范并不清楚谁是正确的(FF/IE 似乎是正确的,但 EcmaScript 6 的讨论表明它们可能是特殊情况 new Date(Date)。从技术上讲,Date 对象不是 Date 构造函数的可接受参数,但字符串是, 并且 Date 字符串不包含毫秒。这表明 FireFox/IE 更正确,但 WebKit 的方式也可以理解,并且将来可能是正确的。

...不过不管怎样,setHours(a,b,c,d) 将小时、分钟、秒、毫秒设置为速记,这样更容易编写。

希望你的项目进展顺利。

【讨论】:

  • 我不确定它是否真的是 Firefox 的错误。 ECMA Spec for Date 除非我读错了,否则它应该按规范自动指定为 0 毫秒。很高兴您发现了这个问题,但它仍然很模糊。
  • 是的,显然在 ECMAScript 6 演讲中讨论了将其设为特殊情况 new Date(Date)。在此处查看评论:bugzilla.mozilla.org/show_bug.cgi?id=868496#c2
  • 嗯,好的。日期对象在处理各种错误和跨浏览器问题时总是有点奇怪。希望第 6 版确实解决了其中一些差异,尽管我不希望它在我们的浏览器中出现很长时间(FF 才开始实现第 5 版功能,如.map
  • 哇,谢谢!它工作得很好。我主要使用这个二进制时钟来测试各种不同的编程语言……你可以把它称为图形软件的我的你好世界。这也远不是我在 javascript 的日期处理中发现的最奇怪的错误......呃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多