HTML界的“苏炳添”——详解Canvas优越性能和实际应用
Google Docs宣布将会把HTML迁移到基于Canvas渲染,这一消息的出现再次把几年前随HTML5诞生的标签重新推到了人们视线之中。Canvas在刚推出时主打的优势就是更快的渲染速度,堪称HTML届的“苏炳添”,刷新了人们对Web页面元素绘制速度的印象。但Canvas的优势仅限于此吗?

(苏炳添,亚洲百米第一人)
HTML绘图届的前辈:SVG
Canvas是HTML5时代引入的“新”标签。与很多标签不同,Canvas不具有自己的行为,只将一组API 展现给客户端 JavaScript ,让开发者使用脚本把想绘制的东西画到一张画布上。
在HTML5之前,人们通常使用SVG来在页面上绘制出图形。SVG使用XML来定义图形,就像使用HTML标签和样式定义DIV一样,我们也可以将一个空白的DIV想象为长方形的SVG,两者的设计思想是相通的,SVG的本质就是一个DOM元素。而Canvas则不同,Canvas提供的是 JavaScript 的绘图 API,而不是像 SVG那样使用XML 描述绘图,通过JavaScript API直接完成绘制,比起修改XML来说要更简便、更直接。
除了定义的方式不同,Canvas和DOM(当然也包含SVG)的差异更多的体现在浏览器的渲染方式上。
浏览器在做页面渲染时,Dom元素是作为矢量图进行渲染的。每一个元素的边距都需要单独处理,浏览器需要将它们全都处理成像素才能输出到屏幕上,计算量十分庞大。当页面上内容非常多,存在大量DOM元素的时候,这些内容的渲染速度就会变得很慢。

(Canvas)
而Canvas与DOM的区别则是Canvas的本质就是一张位图,类似img标签,或者一个div加了一张背景图(background-image)。所以,DOM那种矢量图在渲染中存在的问题换到Canvas身上就完全不同了。在渲染Canvas时,浏览器只需要在JavaScript引擎中执行绘制逻辑,在内存中构建出画布,然后遍历整个画布里所有像素点的颜色,直接输出到屏幕就可以了。不管Canvas里面的元素有多少个,浏览器在渲染阶段也仅需要处理一张画布。
然而这样更加强大的功能,不可避免的让使用canvas渲染有很高的门槛。Google Docs在构建Canvas的过程中重新定义了往常已经被人们所熟悉的内容,例如精确定位、文本选择、拼写检查、重画调优等。为什么更多开发者还是选择了接纳Canvas这个门槛更高的技术路线呢?这就得回到Canvas的最大优势:渲染性能。
Canvas的渲染模式
这里的渲染是指浏览器将页面的代码呈现为屏幕上内容的过程。Canvas和Dom的渲染模式完全不同,搞清楚这个差异对理解Canvas的性能优势至关重要。
Dom:驻留模式
驻留模式(Retained Mode)是Dom在浏览器中的渲染模式。下图粗略展示了这一过程的工作流程。

(驻留模式)
DOM的核心是标签,一种文本标记型语言,多样性很强且多个标签之间存在各种关联(如在同一个DIV下设置为float的子DIV)。浏览器为了更好的处理这些DOM元素,减少对绘制API的调用,就设计了一套将中间结果存放于内存的“驻留模式”。首先,浏览器会将解析DOM相关的全部内容(包含HTML标签、样式和JavaScript),将其转化为场景(scene)和模型(model)存储到内存中,然后再调用系统的绘制API(如Windows程序员熟悉的GDI/GDI+),把这些中间产物绘制到屏幕。
驻留模式通过场景和模型缓存减少了对绘制API的调用频次,将性能压力转移到场景和模型生成阶段,即浏览器需要根据DOM上下文和BOM中的尺寸数据,“自行判断”每一个元素的绘制结果。
Canvas:快速模式
Canvas采用了和DOM不同的快速模式(Immediate Mode),让我们先来看看快速模式是如工作的:

(快速模式)
Canvas的应用优点
上面介绍的两种不同的模式直接造成了Dom和Canvas的性能差异。对于使用快速模式渲染的Canvas而言,浏览器的每次重绘都是基于代码的,不存在能让处理流程变慢的多层解析,所以它真的很快。除了快之外,Canvas的灵活性也大大超出DOM。我们可以通过代码精确的控制如何、何时绘制出我们想要的效果。
在资源消耗上,DOM的驻留模式意味着场景中每增加一点东西就需要额外消耗一些内存,而Canvas并没有这个问题。这个差异会随着页面元素的数量增多而愈加明显。以B端的企业应用场景为例,表单那种数据量比较小的场景,不同渲染模式带来的效果差异并不明显;但在工业制造、金融财会等类Excel电子表格操作的场景下,单元格数量动辄便是上百万(5万行x 20列)甚至上亿个,浏览器需要对表格所有单元格本身内容进行渲染,同时还涉及到丰富的数据处理,情况就完全不同了。

(Web页面上的电子表格,包含1百万个单元格)
在Canvas出现之前,在前端渲染表格时只能通过构建复杂的DOM来实现。这种方式下,浏览器的性能成为了Web应用瓶颈,让很多开发者放弃了在浏览器上实现电子表格的想法。
在Canvas出现后,快速模式带来的性能优势无疑是一个巨大的亮点,大量、复杂的DOM渲染处理带来的性能问题终于有了解决途径。
回到电子表格的应用场景,业内已经出现了使用Canvas绘制画布的表格组件,这类组件在渲染数据层时不仅无需重复创建和销毁DOM元素,在画布的绘制过程中,也比Dom元素渲染的限制更少。除了表格之外,Canvas也为数字孪生可视化大屏、页面游戏等场景带来了变革。

(数字孪生大屏,精确控制各种形状、样式)
总结
总结一下,在渲染模式上,Canvas站在了DOM的对面,浏览器对其内容一无所知,一切渲染的权利回到了开发者的手上,这个改变带来了显著的性能优势。此外,我们可以使用Canvas绘制种类更为丰富的UI元素,如线形、特殊图形等,通过画法逻辑,还可以实现更加精准的UI界面渲染,解决了浏览器差异造成的样式误差,让更多应用场景可以顺利迁移到Web平台上来。
参考资料:
· Canvas社区
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。
HTML界的“苏炳添”——详解Canvas优越性能和实际应用的更多相关文章
- Android之canvas详解
首先说一下canvas类: Class Overview The Canvas class holds the "draw" calls. To draw something, y ...
- 【转】Android Canvas绘图详解(图文)
转自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1212/703.html Android Canvas绘图详解(图文) 泡 ...
- canvas arcTo()用法详解 – CodePlayer
canvas arcTo()用法详解 – CodePlayer canvas arcTo()用法详解
- Canvas使用渐变之-径向渐变详解
创建径向渐变使用 createRadialGrdient(x0,y0,r0,x1,y1,r1) 一共六个参数,分别代表: 起点的圆心坐标(第一个和第二个参数), 起点园的半径(第三个参数), 终点 ...
- Android中Canvas绘图基础详解(附源码下载) (转)
Android中Canvas绘图基础详解(附源码下载) 原文链接 http://blog.csdn.net/iispring/article/details/49770651 AndroidCa ...
- [js高手之路] html5 canvas系列教程 - 状态详解(save与restore)
本文内容与路径([js高手之路] html5 canvas系列教程 - 开始路径beginPath与关闭路径closePath详解)是canvas中比较重要的概念.掌握理解他们是做出复杂canvas动 ...
- Android为TV端助力 转载:Android绘图Canvas十八般武器之Shader详解及实战篇(上)
前言 Android中绘图离不开的就是Canvas了,Canvas是一个庞大的知识体系,有Java层的,也有jni层深入到Framework.Canvas有许多的知识内容,构建了一个武器库一般,所谓十 ...
- Android为TV端助力 转载:Android绘图Canvas十八般武器之Shader详解及实战篇(下)
LinearGradient 线性渐变渲染器 LinearGradient中文翻译过来就是线性渐变的意思.线性渐变通俗来讲就是给起点设置一个颜色值如#faf84d,终点设置一个颜色值如#CC423C, ...
- 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理
[微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...
随机推荐
- buu 新年快乐
一.查壳 发现是upx的壳. 二.拖入ida,发现要先脱壳. 题外话.总结一下手动脱壳,esp定律: 1.先单步到只有esp红色时,右键数据窗口跟随. 2.到数据窗口后,左键硬件访问,byte和wor ...
- Kong Admin API — 核心对象
目录 Service API详解 1. 添加服务 2. 列出service列表 3. 查找service 按条件查找service 查找与指定route关联的service 查找与指定Plugin关联 ...
- Selenium的Css Selector使用方法
什么是Css Selector? Css Selector定位实际就是HTML的Css选择器的标签定位 工具 Css Selector的练习建议大家安装火狐浏览器后,下载插件,FireFinder 或 ...
- PyVista:一款Python的三维可视化软件
技术背景 三维可视化是一项在工业领域中非常重要的技术,而Python中最热门的可视化工具matplotlib和plotly,更加倾向于在数据领域的可视化,用于展现数据的结果.类似的还有百度的pyech ...
- java并发编程基础—生命周期与线程控制
一.线程生命周期 线程被创建启动以后,他既不是一启动就进入执行状态,也不是一直处于执行状态,在线程的生命周期中,它要经过新建(New).就绪(Runnable).运行(Running).阻塞(Bloc ...
- Jmeter任在运行,线程数上不去
问题 jmeter在运行,但是线程数上不去(本来模型设计了100个总线程,但运行时线程只能上到5,根据图上观察总共也只能运行5个线程) 之前更新了random csv插件 解决办法 查看jmeter. ...
- synchronized锁机制(六)
前言 1.理解同步关键词synchronized 2.同步方法与同步代码块的区别 3.理解锁的对象this 脏读 一个常见的概念.在多线程中,难免会出现在多个线程中对同一个对象的实例变量进行并发访问的 ...
- 跨域jsonp+jQuery+json+html动态生成表格
1.什么是跨域 浏览器对于javascript的同源策略的限制,例如a.cn下面的js不能调用b.cn中的js,对象或数据(因为a.cn和b.cn是不同域),所以跨域就出现了. 凡是拥有scr这个属性 ...
- 基于Flask开发网站 -- 前端Ajax异步上传文件到后台
大家好,我是辰哥~ 辰哥最近利用空闲时间在写一个在线可视化平台,过程中也觉得一些技术还是比较有意思的,所以就以模块化的形式分享出来.如:从网页界面(前端)上传文件到服务器(后端). 放一下该模块的界面 ...
- jvm源码解读--16 锁_开头
现在不太清楚, public static void main(String[] args) { Object object=new Object(); System.out.println(&quo ...