高性能渲染——详解Html Canvas的优势与性能
本文由葡萄城技术团队原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。
一、什么是Canvas
想必学习前端的同学们对Canvas 都不陌生,它是 HTML5 新增的“画布”元素,可以使用JavaScript来绘制图形。
Canvas元素是在HTML5中新增的标签用于在网页实时生成图像,并且可以操作图像内容,基本上它是一个可以用JavaScript操作的位图(bitmap)。Canvas 由一个可绘制区域HTML代码中的属性定义决定高度和宽度。JavaScript代码可以访问该区域,通过一套完整的绘图功能的API生成动态的图形。
二. 引入Canvas的重要性
HTML5 在 2012 年已形成了稳定的版本,在此之前很长一段时间,开发者们绘制图形选择的方案更多是SVG来实现。SVG使用XML来定义图形,就像使用HTML标签一样来控制元素的排布,SVG的本质就是一个DOM元素。当图形内容太过丰富后,性能和内存上就会大打折扣。一旦涉及频繁的图片绘制场景,这个实现对于用户的体验将是毁灭性的。
渲染动画的基本原理,无非是反复地擦除和重绘。为了动画的流畅,留给开发者渲染一帧的时间,只有短短的 16.67ms。在这16.67ms中,我不仅需要处理一些绘制逻辑,计算每个对象的位置、状态,还需要把它们都画出来。如果消耗的时间稍稍多了一些,用户就会感受到“卡顿”。所以,在编写动画时,开发者们无时无刻不担忧着动画的性能,唯恐渲染的耗时过长。
在现代 Web 开发中,开发者们更多的会借助 Canvas 提供的API去绘制上下文,可以自由绘制各种2D和3D图形,创建富有视觉冲击力的游戏场景和角色。Canvas的使用可以使得游戏能够实现流畅的动态效果和用户交互。无论是简单的小游戏还是复杂的游戏引擎,Canvas 都被广泛应用。
下面是做的一个简单的对比试验,可以很明显感受到两者的差距,分别使用SVG和Canvas绘制一个包含着100w个圆形的500*500的图片,根据耗时计算对比,Canvas耗费的时间几乎只有SVG的一半:

三. 计算与渲染
把动画的一帧渲染出来,需要经过以下步骤:
- 计算:处理网页渲染逻辑,计算每个对象的状态和位置。
- 渲染:真正把对象绘制出来。
- JavaScript 调用 DOM API(包括 Canvas API)以进行渲染。
- 浏览器(通常是另一个渲染线程)把渲染后的结果呈现在屏幕上的过程。

之前提到过,在动画设计和开发中,每帧只有16.67毫秒的时间用于渲染。这个数值是通过计算每秒60帧得出的平均每帧渲染时间。实际上,并不是所有设备都能够稳定地达到60FPS。因此,为了确保在不同设备上实现一致性的动画效果,最好将每帧的渲染时间控制在10毫秒以内。
大家都知道,通常情况下,渲染的开销远大于计算(相差3~4个量级)。除非使用了一些时间复杂度很高的算法,否则不需要过于深入优化计算环节。Canvas的渲染是在JavaScript引擎中执行绘制逻辑,通过构建画布在内存中,并遍历所有像素点的颜色,最终输出到屏幕上。这种强大的功能可能会增加学习成本,但如今仍然有很多开发者选择和接受Canvas,这要归功于Canvas最大的优势:渲染性能的出色表现。
四. Canvas渲染性能优势
当谈论图形渲染技术时,就不得不提到DOM驻留模式和Canvas快速模式。
DOM驻留模式
DOM驻留模式是一种基于文档对象模型(DOM)的渲染技术。在DOM驻留模式下,页面的布局和样式是由DOM树来掌管的。当页面需要更新时,浏览器会重新计算布局和样式并重新渲染。此模式非常灵活,特别适用于处理动态页面交互和多样化的样式控制。然而,由于需要频繁地重新计算布局和样式,对于复杂的图形渲染任务来说,性能开销相对较高。
Canvas快速模式
Canvas快速模式利用HTML5的Canvas元素进行图形渲染。在这种模式下,开发者可以使用Canvas提供的2D或3D绘图API直接在画布上绘制图形。相比于DOM驻留模式,Canvas快速模式更加高效。它不关心页面的布局和样式,而是在需要时只重绘受影响的部分。这样就避免了频繁的布局和样式计算,提高了渲染性能。
- 分层提高Canvas性能
开发者们通过分析大量实际场景,总结出一套可以进一步提升Canvas性能的策略,即对变化较少和变化较多的内容进行分开渲染。这种策略就是所谓的分层Canvas。它能够显著降低完全没有必要的渲染性能开销。分层渲染的思想被广泛应用于各种图形相关的领域,从古老的皮影戏、套色印刷术,到现代电影/游戏工业以及虚拟现实领域等等。而分层Canvas只是分层渲染思想在Canvas动画上的一个基础应用。

分层Canvas的核心理念是,动态页面中的每种元素(层)对于渲染频率的需求是不同的。对于许多金融会计等大数据行业的从业者来说,主要数据内容的变化频率和幅度较大(他们通常面临数据变动和频繁计算),而背景表格样式的变化频率或幅度相对较小(基本不变,或者变化缓慢,或者仅在特定时机变化)。因此,需要频繁更新和重绘数据,但对于背景,可能只需要绘制一次,或者每隔200毫秒才重绘一次,而没有必要每16毫秒就重绘一次。

- 视野之外的绘制
在许多情况下,Canvas 仅仅作为数据展示页面的一部分,充当着一个“窗口”的角色。如果在每次数据更新时,都将所有数据完全绘制到 Canvas 上,很可能会出现大量内容绘制到Canvas 范围之外的情况。虽然调用了绘制 API,但实际上并没有产生任何效果。
因此,判断对象是否位于 Canvas 范围内需要进行额外的计算(例如,需要通过对游戏角色的全局模型矩阵求逆来得出对象的世界坐标,这是一项相对耗时的操作),同时也会增加代码的复杂性。因此,关键是是否需要这样做。
通过在本地代码中进行测试,比较了在视野内和视野外分别绘制100万个圆的耗时。在视野内绘制耗时8936ms,而在视野外绘制耗时2540ms。考虑到计算和绘制之间的耗时差距在3~4个数量级,因此通过计算来判断并避免绘制视野外的内容是一种非常有效的方法。

五. Canvas的应用
之前探讨了SVG和Canvas的绘制性能差异以及Canvas常见的优化方法。知道,对于使用快速模式渲染的Canvas来说,浏览器的每次重绘都是由代码驱动的,无须进行多层解析,因此它的速度非常快。除了速度快之外,Canvas的灵活性也显著优于DOM。可以通过代码精确控制何时以及如何绘制出期望的效果。
在资源消耗方面,DOM的驻留模式意味着场景中的每一个新增元素都会导致额外的内存消耗,而Canvas则没有这个问题。这种差异在页面元素数量增多时尤为明显。
在Canvas出现之前,前端渲染表格只能通过构建复杂的DOM来实现。然而,这种方式会导致浏览器性能成为Web应用的瓶颈,许多开发人员因此放弃了在浏览器上实现电子表格的想法。
Canvas出现后,其快速模式带来的出色性能优势成为了一大亮点,大量、复杂的DOM渲染处理所带来的性能问题因此有了解决之道。
回到电子表格的应用场景,现在已经出现了使用Canvas绘制画布的表格组件。这类组件在渲染数据层时无须重复创建和销毁DOM元素,而且在画布的绘制过程中受到的限制也比DOM元素渲染更少。其中,葡萄城公司的纯前端表格控件——SpreadJS就用到了Canvas实现表格绘制,除了表格之外,Canvas也为数字孪生可视化大屏、页面游戏等应用场景带来了变革(如下图所示)。

六、总结
本文通过介绍Canvas的原理、Canvas的重要性、Canvas在计算与渲染上的作用、Canvas渲染性能优势和Canvas的应用这五个部分,全面而系统地阐述了HTML Canvas在高性能渲染方面的相关知识和技巧。希望读者通过阅读本文能够深入了解Canvas的基本原理和特性,认识到Canvas在Web开发中的重要性,并掌握Canvas在计算与渲染上的作用。
七. 参考文章
《什么是canvas?有什么用?》黑马程序员
《Canvas最佳实践(性能篇)》
《HTML界的“苏炳添”——详解Canvas优越性能和实际应用》
扩展链接:
Redis从入门到实践
一节课带你搞懂数据库事务!
Chrome开发者工具使用教程
如何在前端系统中使用甘特图
窗口函数大揭秘!轻松计算数据累计占比,玩转数据分析的绝佳利器
探秘移动端BI:发展历程与应用前景解析
相关文章:
高性能渲染——详解Html Canvas的优势与性能
本文由葡萄城技术团队原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 一、什么是Canvas 想必学习前端的同学们对Canvas 都不陌生,它是 HTML5 新增的“画布”元素&#x…...
2023.10 各个编程语言 受欢迎指数 排行
目录 一、前言: 二、排行: 三、趋势: 四、历史排名: 五、名人堂: 一、前言: 来自tiobe...
『PyQt5-基本控件』| 15 如何设置主窗口居中?退出应用程序如何操作?
15 如何设置主窗口居中?退出应用程序如何操作? 1 如何实现主窗口居中显示?1.1 获取屏幕坐标1.2 获取窗口坐标1.3 居中计算1.4 移动位置1.5 完整代码1.6 效果演示2 如何退出应用程序?2.1 使用按钮退出2.2 信号与槽绑定2.3 布局和增加按钮2.4 定义一个按钮事件2.5 完整代码2.…...
scrapy+selenium框架模拟登录
目录 一、cookie和session实现登录原理 二、模拟登录方法-Requests模块Cookie实现登录 三、cookiesession实现登录并获取数据 四、selenium使用基本代码 五、scrapyselenium实现登录 一、cookie和session实现登录原理 cookie:1.网站持久保存在浏览器中的数据2.可以是长期…...
【实验五】题解
T1:缺失的数字 题目描述; 我是敦立坤的爹!!! 一个整数集合中含有n个数字,每个数字都在0n之间。假设0n的n1个数字中有且仅有一个数字不在该集合中,请找出这个数字。 分析: 这里引用一个桶的思…...
Android开发知识学习——Kotlin基础
函数声明 声明函数要用用 fun 关键字,就像声明类要用 class 关键字一样 「函数参数」的「参数类型」是在「参数名」的右边 函数的「返回值」在「函数参数」右边使用 : 分隔,没有返回值时可以省略 声明没有返回值的函数: fun main(){println…...
C++——定义一个 Book(图书)类
完整代码: /*定义一个 Book(图书)类,在该类定义中包括数据成员和成员函数 数据成员:book_name (书名)、price(价格)和 number(存书数量); 成员函数:display()显示图书的 情况;borro…...
深度学习之基于YoloV5的道路地面缺陷检测系统(UI界面)
欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、道路地面缺陷检测系统四. 总结 一项目简介 基于YoloV5的道路地面缺陷检测系统利用深度学习中的目标检测算法,特别是YoloV5算法&am…...
AcWing94. 递归实现排列型枚举:输出1~n的全排列
题目 把 1∼ n n n 这 n n n 个整数排成一行后随机打乱顺序,输出所有可能的次序。 输入格式 一个整数 n n n。 输出格式 按照从小到大的顺序输出所有方案,每行 1 个。 首先,同一行相邻两个数用一个空格隔开。 其次,对于两…...
神经网络多种注意力机制原理和代码讲解
多种注意力表格: 大神参考仓库链接: 魔鬼面具 对应 name 就是目录,点击即可跳转到对应学习。 nameneed_chaneelpaper SE (2017) Truehttps://arxiv.org/abs/1709.01507 BAM (2018) Truehttps://arxiv.org/pdf/1807.06514.pdf CBAM (2018) Tr…...
前端HTML
文章目录 一、什么是前端前端后端 前端三剑客1.什么是HTML2.编写前端的步骤1.编写服务端2.浏览器充当客户端访问服务端 3.浏览器无法正常展示服务端内容(因为服务端的数据没有遵循标准)4.HTTP协议>>>:最主要的内容就是规定了浏览器与服务端之间数据交互的格式 3. 前…...
Jenkins安装(Jenkins 2.429)及安装失败解决(Jenkins 2.222.4)
敏捷开发与持续集成 敏捷开发 敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发。在敏捷开发中,软件项目在构建初期被切分成多个子项目,各个子项目的成果都经过测试,具备可视、可集成和可运行使用的特征。…...
vue中哪些数组操作可以重排
以下是Vue中可以重排数组的常用方法的示例: push():在数组末尾添加一个或多个元素 // 初始化数组 let myArray [1, 2, 3]; // 在数组末尾添加一个元素4 myArray.push(4); console.log(myArray); // [1, 2, 3, 4] // 在数组末尾添加多个元素5和6 myArr…...
订单创建订单确认、收货创建收货确认取消收货、生成库存和领用单发料
本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:山JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文…...
yolox转rknn
使用瑞芯微版本的yolox:https://github.com/airockchip/YOLOXpip install torch1.8.1 torchvision0.9.1 torchaudio0.8.1 --no-cache -i https://pypi.tuna.tsinghua.edu.cn/simplepip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple --…...
llava1.5模型安装、预测、训练详细教程
引言 本博客介绍LLava1.5多模态大模型的安装教程、训练教程、预测教程,也会涉及到hugging face使用与wandb使用。 源码链接:点击这里 demo链接:点击这里 论文链接:点击这里 一、系统环境 ubuntu 20.04 gpu: 2*3090 cuda:11.6 二、LLava环境安装 1、代码下载…...
一个ppt带你读懂网络安全行业四大顶会之一的ndss论文<<Large Language Model guided Protocol Fuzzing>>
论文下载地址: Large Language Model guided Protocol Fuzzing...
ajax调用springboot后台接口
工具 api测试工具 由于后台接口不是同一个团队编写的,在文档缺失的情况下,需要测试后台接口接收参数类型,可以使用这个工具,注册很方便 页面如下所示,可以选择请求方法是get,或者post 重点介绍两种&…...
2021-arxiv-LoRA Low-Rank Adaptation of Large Language Models
2021-arxiv-LoRA Low-Rank Adaptation of Large Language Models Paper: https://arxiv.org/abs/2106.09685 Code: https://github.com/microsoft/LoRA 大型语言模型的LoRA低秩自适应 自然语言处理的一个重要范式包括对通用领域数据的大规模预训练和对特定任务或领域的适应。…...
dockefile
文章目录 应用的部署MySql的部署Tomcat的部署 dockerfileDocker原理镜像的制作容器转镜像Dockerfile 服务编排Docker Compose Docker 私有仓库 应用的部署 搜索app的镜像拉去app的镜像创建容器操作容器中的app MySql的部署 容器内的网络服务和外部机器无法直接通信外部机器和…...
VLC隐藏玩法:结合Lua脚本实现智能视频播放(比如根据时间切换片单)
VLC隐藏玩法:结合Lua脚本实现智能视频播放 你是否厌倦了手动切换播放列表?VLC作为一款开源多媒体播放器,其真正的潜力远不止于基础播放功能。通过Lua脚本接口,我们可以解锁VLC的自动化能力,实现根据时间、文件存在与否…...
pytorch-adapter:让 PyTorch 模型“无缝”跑在昇腾 NPU 上
pytorch-adapter:让 PyTorch 模型“无缝”跑在昇腾 NPU 上 之前帮朋友看 PyTorch 模型适配 CANN 的代码,发现他手写了很多适配层——把自己的 MyModel 一层层翻译成 AscendCL 接口,光写适配层就写了 2,000 行。 我告诉他:不用手…...
python文化旅游服务系统 小程序系统
目录同行可拿货,招校园代理 ,本人源头供货商项目概述核心功能技术栈项目亮点应用场景项目技术支持源码获取详细视频演示 :同行可合作点击我获取源码->->进我个人主页-->获取博主联系方式同行可拿货,招校园代理 ,本人源头供货商 项目概述 Python文化旅游服…...
汽车零部件品牌升级方法拆解:复杂B2B能力如何被客户看懂
从B2B表达方法看,汽车零部件品牌升级可以理解为一个“客户判断结构化”的问题。企业不是简单输出自我介绍,而是要把技术能力、项目经验、质量体系、协同机制与证据材料,转化为客户不同角色都能使用的判断信息。很多汽车零部件企业已经完成了实…...
ISTA 7D-2007 全解析|运输包装温度循环测试标准(CSDN 完整版)
前言ISTA 7D-2007 是 ISTA 7 系列包装研发测试标准,专注于温控运输包装的温度环境模拟测试,用于评估保温箱、冷藏包、冷链包装在高低温循环环境下的隔热保温性能。该标准提供冬季 / 夏季、国内 / 国际、24h/48h/72h多套温度循环曲线,覆盖快递…...
创业公司如何利用 Taotoken 统一管理多个 AI 模型服务
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 创业公司如何利用 Taotoken 统一管理多个 AI 模型服务 对于资源有限的创业团队而言,快速验证产品想法、迭代功能是生存…...
LangChain-Chatchat 开发与应用(十) 企业级部署方案-Docker-Compose-K8s集群化实践
企业级部署方案:Docker Compose / K8s 集群化实践标签:Docker | Kubernetes | 高可用 | 生产部署 | DevOps一、从"单机玩具"到"生产系统" 前面九篇,咱们从 0 到 1 搭起了 Chatchat,做了二次开发,优…...
手语识别实战:CNN-LSTM混合架构与轻量化部署指南
1. 项目概述:手语识别不是“翻译”,而是构建一座可触摸的沟通桥梁手语识别这件事,我从2019年第一次在残联康复中心做志愿者时就盯上了。当时一位老师傅用双手比划“苹果”“医院”“谢谢”,而旁边的年轻人盯着手机里刚装的某款APP…...
JMeter分布式压测原理与高可用集群搭建实战
1. 为什么单台JMeter跑不出真实流量——分布式压测不是“加机器”那么简单 你有没有试过用Jmeter对一个新上线的订单服务做压测,本地配了200个线程,结果TPS卡在80就上不去了,CPU才用了35%,网络IO几乎为零?我第一次遇到…...
丙午年三月三十平镜里
丙午年三月三十平镜里 曾几风流里,皆逝日常中。 莫名春伤寒,妙在岁月功。 儿时不知道,青烟多捉空。 老壮老路上,庭院情境通。 谓花当此季,寻因那刻虹? 虚妄浮云聚,耕种顺序隆。 斯文源村落&…...
