你必须知道的10个提高Canvas性能技巧
你还在抱怨自己写的canvas demo徘徊在10帧以下吗?你还在烦恼打开自己写的应用就听见CUP风扇转吗?你正在写一个javascript Canvas库吗?那么下面九点就是你必须知道的! 一.预渲染 错误代码: var canvas = document.getElementById( "myCanvas" ); var cont
你还在抱怨自己写的canvas demo徘徊在10帧以下吗?你还在烦恼打开自己写的应用就听见CUP风扇转吗?你正在写一个javascript Canvas库吗?那么下面九点就是你必须知道的!
一.预渲染
错误代码:
<span>var </span><span>canvas = document.getElementById(</span><span>"myCanvas"</span><span>); </span><span>var </span><span>context = </span><span>this</span><span>.canvas.getContext(</span><span>'2d'</span><span>); </span><span>var </span><span>drawAsync = eval(Jscex.compile(</span><span>"async"</span><span>, </span><span>function </span><span>() { </span><span>while </span><span>(</span><span>true</span><span>) { drawMario(context); $await(Jscex.Async.sleep(</span><span>1000</span><span>)); } })) drawAsync().start(); </span>
正确代码:
<span>var </span><span>canvas = document.getElementById(</span><span>"myCanvas"</span><span>); </span><span>var </span><span>context = </span><span>this</span><span>.canvas.getContext(</span><span>'2d'</span><span>); </span><span>var </span><span>m_canvas = document.createElement(</span><span>'canvas'</span><span>); </span><span>m_canvas.width = </span><span>64</span><span>; m_canvas.height = </span><span>64</span><span>; </span><span>var </span><span>m_context = m_canvas.getContext(</span><span>'2d'</span><span>); drawMario(m_context); </span><span>var </span><span>drawAsync = eval(Jscex.compile(</span><span>"async"</span><span>, </span><span>function </span><span>() { </span><span>while </span><span>(</span><span>true</span><span>) { context.drawImage(m_canvas, </span><span>0</span><span>, </span><span>0</span><span>); $await(Jscex.Async.sleep(</span><span>1000</span><span>)); } })) drawAsync().start(); </span>
这里m_canvas的宽度和高度控制得越小越好。
二.尽量少调用canvasAPI
错误代码:
<span>for </span><span>(</span><span>var </span><span>i = </span><span>0</span><span>; i <span>1</span><span>; i++) { </span><span>var </span><span>p1 = points[i]; </span><span>var </span><span>p2 = points[i + </span><span>1</span><span>]; context.beginPath(); context.moveTo(p1.x, p1.y); context.lineTo(p2.x, p2.y); context.stroke(); } </span></span>
正确代码:
<span>context.beginPath(); </span><span>for </span><span>(</span><span>var </span><span>i = </span><span>0</span><span>; i <span>1</span><span>; i++) { </span><span>var </span><span>p1 = points[i]; </span><span>var </span><span>p2 = points[i + </span><span>1</span><span>]; context.moveTo(p1.x, p1.y); context.lineTo(p2.x, p2.y); } context.stroke(); </span></span>
三.尽量少改变CANVAS状态
错误代码:
<span>for </span><span>(</span><span>var </span><span>i = </span><span>0</span><span>; i <span>2 </span><span>? COLOR1 : COLOR2); context.fillRect(i * GAP, </span><span>0</span><span>, GAP, </span><span>480</span><span>); } </span></span>
正确代码:
<span>context.fillStyle = COLOR1; </span><span>for </span><span>(</span><span>var </span><span>i = </span><span>0</span><span>; i <span>2</span><span>; i++) { context.fillRect((i * </span><span>2</span><span>) * GAP, </span><span>0</span><span>, GAP, </span><span>480</span><span>); } context.fillStyle = COLOR2; </span><span>for </span><span>(</span><span>var </span><span>i = </span><span>0</span><span>; i <span>2</span><span>; i++) { context.fillRect((i * </span><span>2 </span><span>+ </span><span>1</span><span>) * GAP, </span><span>0</span><span>, GAP, </span><span>480</span><span>); } </span></span></span>
四.重新渲染的范围尽量小
错误代码:
<span>context.fillRect(</span><span>0</span><span>, </span><span>0</span><span>, canvas.width, canvas.height); </span>
正确代码:
<span>context.fillRect(</span><span>20</span><span>, </span><span>20</span><span>, </span><span>100</span><span>, </span><span>100</span><span>); </span>
五.复杂场景使用多层画布
<span><span>canvas </span><span>width=</span><span>"600" </span><span>height=</span><span>"400" </span><span>style=</span><span>"</span><span>position</span><span>: absolute; </span><span>z-index</span><span>: 0"</span><span>> </span><span>canvas</span><span>> <span>canvas </span><span>width=</span><span>"600" </span><span>height=</span><span>"400" </span><span>style=</span><span>"</span><span>position</span><span>: absolute; </span><span>z-index</span><span>: 1"</span><span>> </span><span>canvas</span><span>> </span></span></span>
六.不要使用阴影
<span>context.shadowOffsetX = </span><span>5</span><span>; context.shadowOffsetY = </span><span>5</span><span>; context.shadowBlur = </span><span>4</span><span>; context.shadowColor = </span><span>'rgba(255, 0, 0, 0.5)'</span><span>; context.fillRect(</span><span>20</span><span>, </span><span>20</span><span>, </span><span>150</span><span>, </span><span>100</span><span>); </span>
七.清除画布
详细性能差别:
http://simonsarris.com/blog/346-how-you-clear-your-canvas-matters
一般情况下:clearRect的性能优于fillRect优于canvas.width = canvas.width;
八.像素级别操作尽量用整数
几种取整数的方法:
<span>rounded = (</span><span>0.5 </span><span>+ somenum) | </span><span>0</span><span>; </span><span>rounded = ~ ~(</span><span>0.5 </span><span>+ somenum); </span><span>rounded = (</span><span>0.5 </span><span>+ somenum) <span>0</span><span>; </span></span>
九.使用requestAnimationFrame制作游戏或动画
<p></p><p> (<span>function</span> () {<br> <span>var</span> lastTime = 0;<br> <span>var</span> vendors = ['ms', 'moz', 'webkit', 'o'];<br> <span>for</span> (<span>var</span> x = 0; x window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];<br> window.cancelAnimationFrame =<br> window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];<br> }<br><br> <span>if</span> (!window.requestAnimationFrame)<br> window.requestAnimationFrame = <span>function</span> (callback, element) {<br> <span>var</span> currTime = <span>new</span> Date().getTime();<br> <span>var</span> timeToCall = Math.max(0, 16 - (currTime - lastTime));<br> <span>var</span> id = window.setTimeout(<span>function</span> () { callback(currTime + timeToCall); },<br> timeToCall);<br> lastTime = currTime + timeToCall;<br> <span>return</span> id;<br> };<br><br> <span>if</span> (!window.cancelAnimationFrame)<br> window.cancelAnimationFrame = <span>function</span> (id) {<br> clearTimeout(id);<br> };<br> } ());</p>
十.其他
与渲染无关的计算交给worker
复杂的计算交给引擎(自己写,或者用开源的),比如3D、物理
缓存load好的图片,canvas上画canvas,而不是画image
同步
本文已同步更新至:
HTML5实验室【目录】: http://www.cnblogs.com/iamzhanglei/archive/2011/11/06/2237870.html

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

C语言中,表示指针,存储其他变量的地址;&表示地址运算符,返回变量的内存地址。指针的使用技巧包括定义指针、解引用指针,需确保指针指向有效地址;地址运算符&的使用技巧包括获取变量地址,获取数组元素地址时返回数组第一元素地址。实战案例说明了使用指针和地址运算符反转字符串。

Ollama是一款超级实用的工具,让你能够在本地轻松运行Llama2、Mistral、Gemma等开源模型。本文我将介绍如何使用Ollama实现对文本的向量化处理。如果你本地还没有安装Ollama,可以阅读这篇文章。本文我们将使用nomic-embed-text[2]模型。它是一种文本编码器,在短的上下文和长的上下文任务上,性能超越了OpenAItext-embedding-ada-002和text-embedding-3-small。启动nomic-embed-text服务当你已经成功安装好o

不同Java框架的性能对比:RESTAPI请求处理:Vert.x最佳,请求速率达SpringBoot2倍,Dropwizard3倍。数据库查询:SpringBoot的HibernateORM优于Vert.x及Dropwizard的ORM。缓存操作:Vert.x的Hazelcast客户机优于SpringBoot及Dropwizard的缓存机制。合适框架:根据应用需求选择,Vert.x适用于高性能Web服务,SpringBoot适用于数据密集型应用,Dropwizard适用于微服务架构。

PHP数组键值翻转方法性能对比表明:array_flip()函数在大型数组(超过100万个元素)下比for循环性能更优,耗时更短。手动翻转键值的for循环方法耗时相对较长。

优化C++多线程性能的有效技术包括:限制线程数量,避免争用资源。使用轻量级互斥锁,减少争用。优化锁的范围,最小化等待时间。采用无锁数据结构,提高并发性。避免忙等,通过事件通知线程资源可用性。

函数对C++程序性能的影响包括函数调用开销、局部变量和对象分配开销:函数调用开销:包括堆栈帧分配、参数传递和控制权转移,对小函数影响显着。局部变量和对象分配开销:大量局部变量或对象创建和销毁会导致堆栈溢出和性能下降。

不同PHP函数的性能对应用程序效率至关重要。性能较好的函数包括echo、print,而str_replace、array_merge、file_get_contents等函数性能较慢。例如,str_replace函数用于替换字符串,性能中等,而sprintf函数用于格式化字符串。性能分析表明,执行一个示例仅需0.05毫秒,证明了函数性能良好。因此,明智地使用函数可以构建更快、更高效的应用程序。

静态函数性能考虑如下:代码大小:静态函数通常更小,因为不包含成员变量。内存占用:不属于任何特定对象,不占用对象内存。调用开销:更低,无需通过对象指针或引用调用。多线程安全:通常线程安全,因为不依赖于类实例。
