Canvas性能技巧:必须知道的Canvas性能技巧

文章简介:你还在抱怨自己写的canvas demo徘徊在10帧以下吗?你还在烦恼打开自己写的应用就听见CUP风扇转吗?你正在写一个javascript Canvas库吗?那么下面九点就是你必须知道的!

你还在抱怨自己写的canvas demo徘徊在10帧以下吗?你还在烦恼打开自己写的应用就听见CUP风扇转吗?你正在写一个javascript Canvas库吗?那么下面九点就是你必须知道的!

一.预渲染
错误代码:

      var canvas = document.getElementById("myCanvas");
      var context = this.canvas.getContext('2d');
      var drawAsync = eval(Jscex.compile("async", function () {
          while (true) {
              drawMario(context);
              $await(Jscex.Async.sleep(1000));
          }
      }))
      drawAsync().start();
正确代码:

      var canvas = document.getElementById("myCanvas");
      var context = this.canvas.getContext('2d');
      var m_canvas = document.createElement('canvas');
      m_canvas.width = 64;
      m_canvas.height = 64;
      var m_context = m_canvas.getContext('2d');
      drawMario(m_context);
      var drawAsync = eval(Jscex.compile("async", function () {
          while (true) {
              context.drawImage(m_canvas, 0, 0);
              $await(Jscex.Async.sleep(1000));
          }
      }))
      drawAsync().start();
这里m_canvas的宽度和高度控制得越小越好。

二.尽量少调用canvasAPI
错误代码:

  
    for (var i = 0; i < points.length - 1; i++) {
          var p1 = points[i];
          var p2 = points[i + 1];
          context.beginPath();
          context.moveTo(p1.x, p1.y);
          context.lineTo(p2.x, p2.y);
          context.stroke();
      }
正确代码:

      context.beginPath();
      for (var i = 0; i < points.length - 1; i++) {
          var p1 = points[i];
          var p2 = points[i + 1];
          context.moveTo(p1.x, p1.y);
          context.lineTo(p2.x, p2.y);
      }
      context.stroke();
三.尽量少改变CANVAS状态
错误代码:

      for (var i = 0; i < STRIPES; i++) {
          context.fillStyle = (i % 2 ? COLOR1 : COLOR2);
          context.fillRect(i * GAP, 0, GAP, 480);
      }
正确代码:

      context.fillStyle = COLOR1;
      for (var i = 0; i < STRIPES / 2; i++) {
          context.fillRect((i * 2) * GAP, 0, GAP, 480);
      }
      context.fillStyle = COLOR2;
      for (var i = 0; i < STRIPES / 2; i++) {
          context.fillRect((i * 2 + 1) * GAP, 0, GAP, 480);
      }
四.重新渲染的范围尽量小
错误代码:

  context.fillRect(0, 0, canvas.width, canvas.height);
正确代码:

      context.fillRect(20, 20, 100, 100);
五.复杂场景使用多层画布
 <canvas  width="600" height="400" style="position: absolute; z-index: 0">
</canvas>
<canvas  width="600" height="400" style="position: absolute; z-index: 1">
</canvas>
六.不要使用阴影
      context.shadowOffsetX = 5;
      context.shadowOffsetY = 5;
      context.shadowBlur = 4;
      context.shadowColor = 'rgba(255, 0, 0, 0.5)';
      context.fillRect(20, 20, 150, 100);
七.清除画布
详细性能差别:
http://simonsarris.com/blog/346-how-you-clear-your-canvas-matters
一般情况下:clearRect的性能优于fillRect优于canvas.width = canvas.width;

八.像素级别操作尽量用整数
几种取整数的方法:

      rounded = (0.5 + somenum) 0;
      rounded = ~ ~(0.5 + somenum);
      rounded = (0.5 + somenum) << 0;
九.使用Jscex制作动画效果
     var drawAsync = eval(Jscex.compile("async", function () {
          while (true) {
              context.drawImage(m_canvas, 0, 0);
              $await(Jscex.Async.sleep(1000));
          }
      }))
      drawAsync().start();
十.其他
与渲染无关的计算交给worker

复杂的计算交给引擎(自己写,或者用开源的),比如3D、物理

缓存load好的图片,canvas上画canvas,而不是画image

时间: 2024-08-31 19:32:44

Canvas性能技巧:必须知道的Canvas性能技巧的相关文章

必须知道的SQL编写技巧,多条件查询不拼字符串的写法

原文:必须知道的SQL编写技巧,多条件查询不拼字符串的写法 在做项目中,我们经常遇到复杂的查询方法,要根据用户的输入,判断某个参数是否合法,合法的话才能当作过滤条件,我们通常的做法是把查询SQL赋值给一个字符串变量,然后根据判断条件动态的拼接where条件进行查询.下面来简单说一下写SQL中遇到的问题和解决办法.   一.不确定字段名,而产生的SQL字符串拼接                                                                    

15个必须知道的chrome开发者技巧

来源:http://www.admin10000.com/document/6159.html 在Web开发者中,Google Chrome是使用最广泛的浏览器.六周一次的发布周期和一套强大的不断扩大开发功能,使其成为了web开发者必备的工具.你可能已经熟悉了它的部分功能,如使用console和debugger在线编辑CSS.在这篇文章中,我们将分享15个有助于改进你的开发流程的技巧. 一.快速切换文件 如果你使用过sublime text,那么你可能不习惯没有Go to anything这个功

工具推荐:你必须知道的11款新型编程工具

本文讲的是工具推荐:你必须知道的11款新型编程工具,对于开发人员来说,工具是至关重要的.工具可以使开发人员的日常工作更加轻松.高效,因为只要关注最重要的事情即可.对于开发人员来说,想要寻找到更好的替代工具往往比坚持使用熟悉的.过时的工具要困难得多. 在这篇文章中,我们将列出你可以在日常工作中使用的一些新的编程工具.对在线流媒体感兴趣的许多开发人员也已经开始在其开发环境中使用这些新工具,因为这些工具与其陈旧的设施相比具有明显的优势. 你可能会想,如果旧的工具可以完成工作,那么是否还有必要去寻找新的

读书感受 - 软件设计师 - 你必须知道的.NET (C#类型存储方式分析)

      这几天花了些时间,相对仔细的阅读了<你必须知道的.NET>这本书,因为没有多少时间,请大家在看该书的时候一定要理解内容,转变成自己的经验.下面仅做简单的书评.         该书详细的介绍了C#类型的存储分配问题,对于值类型和引用类型的存储和类型的转换,都用了大篇幅来进行说明,如果还想再详细些,就得去看.net framework中的底层方法和机制了.其实它的这个存储分配,不该说是C#,应该是.net这个框架的存储分配方式.对于其它语言,比如VB.NET,VC++.NET也是一致

[你必须知道的.NET]第二十回:学习方法论

说在,开篇之前 本文,源自我回答刚毕业朋友关于.NET学习疑惑的回复邮件. 本文,其实早计划在<你必须知道的.NET>写作之初的后记部分,但是因为个中原因未能如愿,算是补上本书的遗憾之一. 本文,作为[<你必须知道的.NET>]系列的第20回,预示着这个系列将开始新的征程,算是[你必须知道的.NET]2.0的开始. 本文,作为一个非技术篇章,加塞儿到<你必须知道的.NET>队伍中,我想至少因为回答了以下几个必须知道的非技术问题:.NET应该学习什么? .NET应该如何学

iOS程序员必须知道的Android要点

iOS程序员必须知道的Android要点 2014/05/06 | 分类: ANDROID, 开发 | 0 条评论 | 标签: ANDROID 本文由 伯乐在线 - chris 翻译自 objc.欢迎加入Android小组.转载请参见文章末尾处的要求. 本博客英文原文副本 http://blog.csdn.net/opengl_es/article/details/25243257 在移动应用飞速发展的今天,APP只针对IOS平台进行开发已经不够了,如今Android在移动设备占有近80%的市场

《你必须知道的495个C语言问题》一第1章 声明和初始化(1.1-1.20)

第1章 声明和初始化 你必须知道的495个C语言问题 C语言的声明语法本身实际上就是一种小的编程语言.一个声明包含如下几个部分(但是并非都必不可少):存储类型.基本类型.类型限定词和最终的声明符(也可能包含初始化列表).每个声明符不仅声明一个新的标识符,同时也表明标识符是数组.指针.函数还是其他任意的复杂组合.基本的思想是让声明符模仿标识符的最终用法.(问题1.21将会更加详细地讨论这种"声明模仿使用"的关系!) 基本类型 让一些程序员惊奇的是,尽管C语言是一种相当低级的语言,但它的类

你必须知道的.NET

[你必须知道的.NET]第三十五回,判断dll是debug还是release,这 [你必须知道的.NET]第三十四回,object成员,不见了! [你必须知道的.NET]第三十一回,深入.NET 4.0之,从"新"展望 [你必须知道的.NET]第三十三回,深入.NET 4.0之,Lazy<T> [你必须知道的.NET]第三十二回,,深入.NET 4.0之,Tuple一二 [你必须知道的.NET]第三十回:.NET十年(下) [你必须知道的.NET]第二十九回:.NET十年(

[你必须知道的.NET]第二十七回:interface到底继承于object吗?

说在,开篇之前 在.NET世界里,我们常常听到的一句话莫过于"System.Object是一切类型的根,是所有类型的父类",以至于我在<你必须知道的.NET>8.1节 以"万物归宗:System.Object"这样的title为System.Object授予至高荣誉.所以,基于这样的观点就有了下面这句"接口是否也继承于System.Object?",事实上这正是今天在技术群里小小讨论的一个插曲. 1 缘起 在.NET世界里,我们常常听