html5 canvas移动设备渲染测试
最近项目闲着没什么事,又想起了canvas, 针对移动端设备默认浏览器,做了点渲染方面效率的测试,手头设备不多(有一些低端机型和pc chrome做对比),现将测试数据分享给大家吧,本想和css3 animation动画一起测试比较一下,发现animation水的不行,效果跟canvas差很多(可能是因为我代码写的不好),webgl还没有普及到移动设备,所以也不做比较了,曾经看过一篇文章drawImage比putImageData效率低,但测试了一下drawImage的性能更好,还请大牛指导。测试使用cocos2dx的dancer做动画,全屏幕刷新,没使用脏矩形刷新,根据动画个数,屏幕缩放大小两方面测试(值为fps):
1 | 10 | 50 | 100 | 200 | 500 | 1000 | 1 | 20 | 50 | 100 | 200 | 500 | 1000 | 1 | 10 | 50 | 100 | 200 | 500 | 1000 | 1 | 10 | 50 | 100 | 200 | 500 | ||
320*200 | V | V | V | V | V | V | V | |||||||||||||||||||||
480*320 | |
V | V | V | V | V | V | V | ||||||||||||||||||||
800*480 | |
V | V | V | V | V | V | V | ||||||||||||||||||||
1024*800 | |
V | V | V | V | V | V | V | ||||||||||||||||||||
chrome | 75 | 75 | 75 | 75 | 73 | 46 | 46 | 75 | 73 | 72 | 67 | 62 | 41 | 26 | 61 | 59 | 58 | 56 | 53 | 34 | 20 | 29 | 29 | 29 | 29 | 27 | 21 | 14 |
chiwi v88 | 165 | 108 | 55 | 36 | 25 | 12 | 8 | 116 | 83 | 46 | 36 | 23 | 12 | 6 | 61 | 57 | 43 | 30 | 21 | 10 | 6 | 53 | 48 | 35 | 27 | 18 | 6 | 6 |
moto ME722 | 78 | 55 | 22 | 12 | 8 | 4 | 2 | 76 | 47 | 16 | 11 | 7 | 4 | 2 | 43 | 30 | 17 | 12 | 7 | 4 | 2 | 23 | 23 | 17 | 12 | 8 | 4 | 2 |
iphone 4 | 61 | 61 | 60 | 58 | 43 | 22 | 12 | 61 | 61 | 61 | 54 | 42 | 22 | 12 | 61 | 61 | 57 | 48 | 38 | 22 | 12 | 49 | 50 | 46 | 39 | 32 | 21 | 12 |
GALAXY SII | 79 | 60 | 27 | 16 | 14 | 9 | 6 | 77 | 55 | 25 | 14 | 10 | 7 | 4 | 75 | 54 | 26 | 16 | 8 | 6 | 4 | 50 | 37 | 26 | 12 | 8 | 5 | 3 |
做了几张图方便大家对比:
不同分辨率(这里网页缩放使用meta标签适配全屏):
不同机型(chiwi v88为驰为v88,具体配置大家自查吧):
结果iphone必须是最牛的,貌似最高有60fps的渲染限制,以上测试仅供参考(仅仅是渲染部分,没有逻辑代码),希望能帮到大家(^-^)
后附部分代码(有些的不好的地方求指导)注释前部分是putImageData渲染,后部分是使用css3 animation
$(document).ready(function(e) { var canvas=document.getElementById("canvas"); var tag = document.getElementById("tag"); var sprite_info = {"s":"dance_atlas.png", 'w':85, 'h':120, 'f':[[0, 0], [85, 0], [170, 0], [255, 0], [340, 0], [0, 120], [85, 120], [170, 120], [255, 120], [340, 120], [0, 240], [85, 240], [170, 240], [255, 240]], "fd":[]}; var sprites=[]; var SPEED = 60; var image_data = null; var image_ele = new Image(); var data = null; var timestamp; var fps = 60; var canvas_width = canvas.width; var canvas_height = canvas.height; var canvas_context = canvas.getContext('2d'); image_ele.src = sprite_info.s; image_ele.onload = function() { var i = 0; //getImageData(); while(i<1) { createParticles(); i++ } start(); } function drawloop() { updateParticles(); drawParticles(); } /*function putloop() { updateParticles(); putParticles(); }*/ /*function getImageData() { canvas_context.drawImage(image_ele, 0, 0, image_ele.width, image_ele.height); for(var index = sprite_info.f.length - 1; index > -1; index--) { var cf = sprite_info.f[index]; sprite_info.fd[index] = canvas_context.getImageData(cf[0], cf[1], sprite_info.w, sprite_info.h); } }*/ function createParticles() { var sp = Math.floor(Math.random() * SPEED); sprites.push( { x: Math.floor(Math.random() * (canvas_width - sprite_info.w)), y: Math.floor(Math.random() * (canvas_height - sprite_info.h)), s: sp, cs: 0, i:0 }); } canvas.addEventListener('click',createParticles, false); canvas.addEventListener('touchstart',createParticles, false); function updateParticles() { for(var index = sprites.length - 1; index > -1 ;index--) { var sprite = sprites[index]; if(sprite.cs == 0) { sprite.cs = sprite.s; if(sprite.i == sprite_info.f.length - 1) sprite.i = 0; else sprite.i++; } else { sprite.cs--; } } } function drawParticles() { canvas_context.clearRect(0,0,canvas.width,canvas.height); for(var index = sprites.length - 1; index > -1 ;index--) { var sprite = sprites[index]; var frame_i = sprite_info.f[sprite.i]; canvas_context.drawImage(image_ele, frame_i[0], frame_i[1], sprite_info.w, sprite_info.h, sprite.x,sprite.y, sprite_info.w, sprite_info.h); } } function putParticles() { canvas_context.clearRect(0,0,canvas.width,canvas.height); for(var index = sprites.length - 1; index > -1 ;index--) { var sprite = sprites[index]; var frame_i_d = sprite_info.fd[sprite.i]; canvas_context.putImageData(frame_i_d, sprite.x,sprite.y); } } var requestAnimationFrame = window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function(func){setTimeout(func, 0);}, startTime = window.mozAnimationStartTime || Date.now(), fra = 0; function updateProgress(){ drawloop(); var drawStart = (timestamp || Date.now()); fra++; if(drawStart - startTime > 1000) { tag.innerText = "fps:" + fra; startTime = drawStart; fra = 0; } if (true){ requestAnimationFrame(updateProgress); } } function start() { requestAnimationFrame(updateProgress); } /* var pnl = document.getElementById("app"); var SPEED = 10; var spy = null; var fps = 60; var r_time = Math.floor((1000 / fps) * 14); function createParticles() { var new_dancer = document.createElement("div"); var inner = document.createElement("div"); new_dancer.appendChild(inner); pnl.appendChild(new_dancer); new_dancer.style["left"] = Math.floor(Math.random() * (/(\d+)px/.exec(pnl.style["width"])[1] * 1 - sprite_info.w)) + 'px'; new_dancer.style["top"] = Math.floor(Math.random() * (/(\d+)px/.exec(pnl.style["height"])[1] * 1 - sprite_info.w)) + 'px'; //var sp = Math.floor(Math.random() * SPEED); inner.style['-webkit-animation-duration'] = r_time + 'ms'; sprites.push(new_dancer); spy = new_dancer; } var drawStart, startTime = Date.now(), fra = 0, timestamp; function updateProgress(){ debugger; var drawStart = (timestamp || Date.now()); fra += 14; if(drawStart - startTime > 1000) { debugger; tag.innerText = "fps:" + fra; startTime = drawStart; fra = 0; } } function start() { var i = 0; while(i<100) { createParticles(); i++ } spy.addEventListener("webkitAnimationIteration", updateProgress, false); } start();*/ });