最近項目閒着沒什麼事,又想起了canvas, 針對移動端設備默認瀏覽器,作了點渲染方面效率的測試,手頭設備很少(有一些低端機型和pc chrome作對比),現將測試數據分享給你們吧,本想和css3 animation動畫一塊兒測試比較一下,發現animation水的不行,效果跟canvas差不少(多是由於我代碼寫的很差),webgl尚未普及到移動設備,因此也不作比較了,曾經看過一篇文章drawImage比putImageData效率低,但測試了一下drawImage的性能更好,還請大牛指導。測試使用cocos2dx的dancer作動畫,全屏幕刷新,沒使用髒矩形刷新,根據動畫個數,屏幕縮放大小兩方面測試(值爲fps):css
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 |
作了幾張圖方便你們對比:css3
不一樣分辨率(這裏網頁縮放使用meta標籤適配全屏):web
不一樣機型(chiwi v88爲馳爲v88,具體配置你們自查吧):chrome
結果iphone必須是最牛的,貌似最高有60fps的渲染限制,以上測試僅供參考(僅僅是渲染部分,沒有邏輯代碼),但願能幫到你們(^-^)canvas
後附部分代碼(有些的很差的地方求指導)註釋前部分是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();*/ });