HTML5 Canvas 在某些移动浏览器中的性能问题.
您好,我有一个应该能够在智能手机和桌面浏览器上运行的 Web 应用程序.虽然我期待在像 Iphone 这样的小型设备上会出现一些奇怪的行为,但我非常有信心它会在 Android Galaxy Tab 上运行良好,这是我目前可以运行测试的 Android 设备.
Hi I have a Webapp that should be able to run on both Smartphone and Desktop Browsers alike. While I was expecting to get some curious behaviour on small devices like the Iphone, I was pretty confident that it would run well on an Android Galaxy Tab which is the Android Device that I can run tests with at the moment.
现在我在 Galaxy Tab 上安装了一堆浏览器来测试:
Now I have installed a bunch of Browsers on the Galaxy Tab to test things with:
- Android 原生浏览器
- Android 版 Chrome
- 安卓版火狐
在我用过的桌面上
- 火狐
- 谷歌浏览器
最后我有一个 Iphone 可以测试.
and finally I have an Iphone to test with.
该网站使用 HTML5 画布进行基于像素和精灵的绘图,没有花哨的转换、过滤器或效果,主要是简单的路径和多边形.我确实会监听触摸事件并使用 requestAnimationFrame
进行正确的重绘.
The website uses HTML5 canvas for pixel and sprite based drawing no fancy transformation, filters or effects, mostly simple paths and polygons. I do listen to touch events and use requestAnimationFrame
for proper redrawing.
总体而言,该应用程序在桌面浏览器上运行良好,在 iOS Safari (iPhone) 和 Firefox-on-Android 上也运行良好.然而,Androids Native Browser 给我带来了麻烦.我已经设置好了,当 javascript 没有响应时屏幕会变成红色,并且几乎总是在触摸屏幕时闪烁.
Overall the application runs well on Desktop Browsers, it is also running great on iOS Safari (iPhone) and Firefox-on-Android. Yet Androids Native Browser is giving me trouble. I have set it up so that the screen flushes red when the javascript is not responsive, and it does flash almost always when touching the screen.
所以我想知道 Android Native App 和 HTML5 是否存在任何已知问题.由于本机浏览器的名称不存在,因此很难通过谷歌搜索相关信息.有什么想法可以让我获得更多信息吗?有什么想法可能导致原生 Android 浏览器滞后?
So I wonder whether there are any known issues with Android Native App and HTML5. Due to the nonexistent Name of the native Browser its quite hard to google information about this. Any ideas for me where I can get more information? Any ideas what might cause the lagging of the native Android browser?
关于这个问题有几个想法:
There are a few ideas about the issue:
iOS 不支持 requestAnimationFrame,因此我将其替换为基于超时的替换.如果我在 Android 的本机浏览器上使用该替换,问题仍然存在.
iOS does not support requestAnimationFrame, therefore I replaced it with a timeout based replacement. If I use that replacement on Android's native browser, the problem persists.
我经常使用 AJAX (google clojure xhrio) 从服务器检索数据.会不会是数据检索回调阻塞了我的事件管道?
I use AJAX (google clojure xhrio) quite regularly to retrieve data from the server. Could it be that data retrieval callbacks are cloggin my event pipeline?
是否已知日志控制台消息 (console.log) 会降低应用程序的速度?他们能否触发浏览器重新运行 DOM 树或任何相关内容?
Are log console messages (console.log) known to slow down applications? Could they trigger the browser to rerun through the DOM tree or anything related?
推荐答案
我在很多浏览器中用画布做了很多实验.我注意到的一些性能问题:
I've done a lot of experiments with canvas in many browsers. Some performance issues that I noticed:
首先,关于你的猜测:
当浏览器支持
requestAnimationFrame
时,绘图内容和应用程序本身的响应速度会更快.始终可以使用setTimeout
或setInterval
作为备用,但您需要注意时间安排.这个强大的 polyfill 可能会有所帮助,但与原生 requestAnimationFrame 相比没有任何帮助.
When
requestAnimationFrame
is supported by a browser, the drawing stuff and the app itself are more responsive. UsesetTimeout
orsetInterval
as a fallback are always possible but you need to be careful about the timing. This robust polyfill may help a little, but nothing compared to native requestAnimationFrame.
如果每帧(或几乎)调用 console.log,是的,性能会下降.由于原生 Android 浏览器没有控制台对象,因此每次调用它都会产生一个错误,这也会导致您的应用程序变慢.你可以这样做:
If console.log is called every frame (or almost), yes the performance goes down. Since native Android Browser doesn't have a console Object, every time it is called will generate an error that also contributes to slow down your application. You can do this:
if(typeof 控制台 === "未定义"){控制台 = {};}
对于密集的实时应用程序,网络套接字比 http 请求更快.不幸的是,旧的原生 android 浏览器不支持此功能.如果无法使用 Web 套接字,则应尽量减少 http 请求.
For intense real-time applications web sockets are faster then http requests. Unfortunately this feature is not supported by old native android browsers. If it's not possible to use web sockets, you should minimize the http requests.
注意:Android 版 Chrome 支持此处引用的大部分 HTML5 功能,包括 requestAnimationFrame
和 websockets
.
Note: Chrome for android support most of HTML5 features cited here, including requestAnimationFrame
and websockets
.
更多信息:
使用上下文 2d
fillText
绘制文本太昂贵了,但在某些浏览器中这更糟.在另一个画布中预渲染您的文本或使用位图字体.(在原生 Android 浏览器中,将filltext
绘图替换为预渲染内容后,在我制作的一些游戏中,性能从 10-15 FPS 提高到 30-45 FPS.
Drawing text using the context 2d
fillText
it's too expensive, but in some browsers this is even worse. Pre-render your texts in another canvas or use bitmap fonts. (In native Android Browser, after replacefilltext
drawing for pre-render stuff, the performance grew from 10-15 FPS to 30-45 FPS in some games I've made).
避免缩放和旋转上下文,因为它们也会导致性能下降.如果您只需要缩放或旋转一次精灵,也可以使用预渲染.
Avoid scale and rotate context because they also cause drop down in performance. If you need to scale or rotate a sprite only once, use pre-render either.
你需要最小化实时绘图.尽可能预渲染你的东西.仅重绘已更改且需要更新的内容.
You need to minimize the real time drawing. Pre-render your stuff whenever you can. Redraw only stuff that changed and needs to be updated.
尝试写内存高效和垃圾收藏家友好的代码.
Try to write memory efficient and garbage collector friendly code.
还有很多事情要做.我只是引用了一些.
There are a lot more things to do. I just cited a few.
提示:对您不确定是否会影响性能的功能进行一些压力测试并获取基准测试结果.
TIP: make some stress tests for features you don't sure if they are performance killers and capture the benchmark results.
在移动应用程序中,特别是实时应用程序,欢迎所有优化,无论是过度优化还是内存增加.
In mobile applications, specially real time apps, all optimizations are welcome no mater if it's just an over optimization or a bit of memory gain.
更多信息请点击以下链接:
For more information follow the links below:
- http://www.html5rocks.com/en/tutorials/canvas/performance/(这个绝对应该去看看)
- http://www.html5rocks.com/en/features/performance
- http://www.html5rocks.com/en/tutorials/canvas/performance/ (this one definitely should be visited)
- http://www.html5rocks.com/en/features/performance
还可以在 Posts &教程.
编辑
此 jsfiddle 代码片段 显示了此答案中涵盖的一些内容,并为基准测试提供了粗略的 fps 计数器.自己编辑这个小提琴并检查一下.
EDIT
This jsfiddle code snippet shows some stuff covered in this answer and provides a rough fps counter to benchmark. Edit this fiddle by yourself and check it out.
相关文章