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的wiki介绍

· canvas社区

· 基于canvas表格组件 spreadjs

到此这篇关于html-canvas的优越性能以及实际应用的文章就介绍到这了,更多相关canvas性能及应用内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!