你必须知道的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 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









C 言語では、他の変数のアドレスを格納するポインタを表し、& は変数のメモリ アドレスを返すアドレス演算子を表します。ポインタの使用に関するヒントには、ポインタの定義、ポインタの逆参照、ポインタが有効なアドレスを指していることの確認が含まれます。アドレス演算子の使用に関するヒントには、変数アドレスの取得、配列要素のアドレスを取得するときに配列の最初の要素のアドレスを返すことなどが含まれます。 。ポインター演算子とアドレス演算子を使用して文字列を反転する実際の例。

Ollama は、Llama2、Mistral、Gemma などのオープンソース モデルをローカルで簡単に実行できるようにする非常に実用的なツールです。この記事では、Ollamaを使ってテキストをベクトル化する方法を紹介します。 Ollama をローカルにインストールしていない場合は、この記事を読んでください。この記事では、nomic-embed-text[2] モデルを使用します。これは、短いコンテキストおよび長いコンテキストのタスクにおいて OpenAI text-embedding-ada-002 および text-embedding-3-small よりも優れたパフォーマンスを発揮するテキスト エンコーダーです。 o が正常にインストールされたら、nomic-embed-text サービスを開始します。

さまざまな Java フレームワークのパフォーマンス比較: REST API リクエスト処理: Vert.x が最高で、リクエスト レートは SpringBoot の 2 倍、Dropwizard の 3 倍です。データベース クエリ: 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 関数は文字列の書式設定に使用されます。パフォーマンス分析によると、1 つの例の実行にかかる時間はわずか 0.05 ミリ秒であり、関数が適切に実行されることが証明されています。したがって、関数を賢く使用すると、アプリケーションをより高速かつ効率的に実行できます。

静的関数のパフォーマンスに関する考慮事項は次のとおりです。 コード サイズ: 静的関数にはメンバー変数が含まれないため、通常は小さくなります。メモリ占有: 特定のオブジェクトに属さず、オブジェクト メモリを占有しません。呼び出しオーバーヘッド: 低くなり、オブジェクト ポインターまたは参照を介して呼び出す必要がありません。マルチスレッド セーフ: クラス インスタンスに依存しないため、通常はスレッド セーフです。
