4、架构:Canvas VS DOM

news2024/11/26 14:34:23

可视化搭建的低代码平台中,设计器是一个非常关键的模块,可以帮助用户通过拖拽、配置等方式快速搭建应用界面

在技术选型方面,目前市面上主流的设计器技术包括基于 HTML/CSS/JavaScript 的 Web 设计器。

在渲染方案方面,主流的设计器通常采用基于虚拟 DOM 的渲染方案,比如 ReactVue 等,这种渲染方案可以提高渲染性能和开发效率,同时也支持组件化开发,使得设计器更加易于维护和扩展。

除了渲染方案,设计器的交互体验也非常重要,为了提高用户体验,主流的设计器通常会提供丰富的交互组件和动画效果,比如拖拽、缩放、动态添加组件等功能,以及实时预览、撤销重做等操作,这些功能会非常考验渲染方案的选择以及研发的设计与开发功底。

所以要设计一个易于使用、高效的低代码平台设计器,我们需要综合考虑技术选型渲染方案交互体验等多个方面的因素,本章将会针对设计器中可视化搭建的方案做一些技术上的选型探讨以及介绍一下市面上一些主流设计器的渲染方案。

浏览器渲染的方式


在开始进行渲染方式的选择之前,我们先来了解下在浏览器中渲染视图的常见方案:

  • HTML DOM:目前大多数都是使用其来绘制大部分的前端需求,使用起来非常的灵活和便捷,提供了配套全面的事件处理机制来处理相关的交互操作。主打的优势就是其便携性,学习成本低,上手简单容易。不过在内存开销、渲染速度等方面并不是很占优势,是其的薄弱环节;
  • Canvas(画布)HTML5 中,提供了 Canvas 画布元素,通过 <canvas/> 和绘制 API 在web页面上呈现图形、动画和图像。与 DOM 不同,Canvas 主打的优势在于灵活性高、性能出色、跨平台渲染等特点。但 Canvas 的上手成本很高,需要了解 JavaScript Canvas 相关画布 api,不支持 SEO 等等缺陷。设立的门槛让很多想尝试的前端同学望而却步;
  • WebGLWebGL 是比较新颖成熟的 3D 渲染引擎,主要用于在 Web 浏览器中呈现复杂的 3D 图像和动画。可以实现高性能的 3D 图形渲染和复杂场景绘制。同时支持硬件加速,调用 GPU 资源来渲染图形,极大的提高了渲染速度。基于 WebGL 的 Three.js 深受广大开发者的青睐。不过相应的缺点就是对基础设备有一定的要求,对低端设备不太友好。另外上手困难,不仅仅需要具备前端开发知识,同时也需要了解图形学、数学相关的一些理念和知识;
  • SVG:虽然 SVG 也能够在浏览器上绘制内容,但是与上面的几种技术相比,就明显薄弱很多了,不管是从性能上,还是易用程度而言都没有突出的亮点。不过 SVG 在浏览器图形高保真上有自己独有的优势,因此很多时候都会使用 SVG 的图标来保证相关设计的还原度,拥有更好的呈现效果的同时,也拥有比同位图文件更小的体积。

以上是在浏览器渲染视图的各种方案介绍,可以很明显的看出,DOM 与 Canvas 两种方案综合来看优势会比较明显,所以大部分的低代码产品会选择 DOM 和 Canvas 两者其中一个做为渲染器,不排除某些另辟蹊径的特殊项目有其他的选择。

其他平台的策略


上述提到了 DOM 和 Canvas 是比较好的选择,那么不妨先来看看目前市面上比较热门的一些编辑器它们内部究竟是怎么做抉择的呢?

下面只是做一些技术方案的横向对比,不一定是低代码平台,也包含了目前一些比较受欢迎的企业级 D2C 产品。

平台DOMCanvas是否开源
Retool☑️ 🙅
bubble☑️ 🙅
蓝湖 ☑️🙅
即时设计 ☑️🙅
figma ☑️🙅
lowcode-engine(宜搭)☑️ ☑️
amis☑️ ☑️

可以看出上述的 LowCode & D2C 产品,不管是商业化还是开源项目,可视化搭建类型的低代码产品多数都是使用 DOM 方案,而 D2C 类型的产品则是使用 Canvas 会多一些。

Canvas Vs DOM


那么为什么 D2C 产品会倾向选择 Canvas,而低代码平台则是更偏向 DOM 方案呢?

接下来会从一些常见的编辑器的侧重点来一一进行分析。

渲染性能

首先从性能入手,为了让同学更好的来了解。

在浏览器窗口内分别使用 Canvas 和 DOM 的绘制方式来插入 1000 个红色方块,最后使用计时代码记录当前的渲染时间。

可以看到 Canvas 的渲染速度比 DOM 是成倍提升的。

format,png

下面是两者比对的代码:

<div id="BoxContainer" ></div>
<script>
  const container = document.getElementById("BoxContainer");

  const startTime = performance.now();

  for(let i = 0; i < 1000; i++) {
    const square = document.createElement("div");
    square.style.width = "10px";
    square.style.height = "10px";
    square.style.background = "red";
    square.style.position = "absolute";
    square.style.left = Math.random() * 500 + "px";
    square.style.top = Math.random() * 500 + "px";
    container.appendChild(square);
  }

  const endTime = performance.now();
  const renderTime = endTime - startTime;
  console.log(`DOM render time: ${renderTime} ms`);
</script>

<canvas height="500px" width="500px" id="MyCanvas" ></canvas>
<script>
    const canvas = document.getElementById("MyCanvas");
    const ctx = canvas.getContext("2d");

    const startTime = performance.now();

    for(let i = 0; i < 1000; i++) {
        ctx.fillStyle = "red";
        ctx.fillRect(Math.random() * 500, Math.random() * 500, 10, 10);
    }

    const endTime = performance.now();
    const renderTime = endTime - startTime;
    console.log(`Canvas render time: ${renderTime} ms`);
</script>

从渲染的性能上来比,Canvas 无疑是碾压 DOM 的。

事件交互

浏览器 DOM 的优势在于每一个节点都是独立开的,并且具有一套完整易用的浏览器事件系统提供给开发者进行调用,而 Canvas 则是在一个画布平面当中,只能通过元素的 xy 的距离边界来确定交互的元素,然后通过事件的广播进行操作。

首先:看下 DOM 的事件绑定:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script>
      function handleCanvasClick(event) {
        console.log('鼠标点击了canvas');
      };
    </script>
  </head>
  <body>

    <div onclick="handleCanvasClick()" >click</div>

  </body>
</html>

然后:下面是 Canvas 的事件绑定:

<canvas id="myCanvas" width="400" height="400"></canvas>

<script>
    // 获取canvas元素
    var canvas = document.getElementById("myCanvas");

    // 获取画布上下文
    var ctx = canvas.getContext("2d");

    // 绘制一个圆形
    ctx.beginPath();
    ctx.arc(200, 200, 50, 0, 2 * Math.PI);
    ctx.fillStyle = "red";
    ctx.fill();

    // 添加点击事件监听器
    canvas.addEventListener("click", function(event) {
            // 获取点击位置的坐标
            var x = event.clientX - canvas.offsetLeft;
            var y = event.clientY - canvas.offsetTop;

            // 判断是否点击了圆形
            var distance = Math.sqrt(Math.pow(x-200, 2) + Math.pow(y-200, 2));
            if (distance <= 50) {
                    // 在圆形上方显示鼠标指针的坐标
                    ctx.fillStyle = "black";
                    ctx.font = "20px Arial";
                    ctx.fillText("Clicked at (" + x + ", " + y + ")", x, y - 10);
            }
    });
</script>

上述示例中,分别用 DOM 和 Canvas 实现了一个点击元素的事件。可以看到,两者的实现难度还是存在很大差异的,DOM 直接使用 onclick 来支持相关的事件绑定,而 Canvas 则是在事件内部通过 event 提供的 xy 坐标确定点击的内容归属。

选择

通过上述一些简单的示例,可以有一个比较明确的结论,Canvas 渲染器在图形渲染方面性能确实是非常好的,但从开发体验上来看 DOM 会更加简单,不管是添加内容还是事件系统都比 Canvas 方便,学习成本以及上手成本都会低于 Canvas 方案。

蓝湖即时设计等 D2C 平台绝大部分都是使用 Canvas 作为渲染引擎,其原因是随着设计师上传的素材切图越来越多,如果使用 DOM 来渲染的话,由于节点过多带来的图形渲染的瓶颈会造成使用体验的卡顿,且交互事件并不算太复杂,因此使用 Canvas 能够得到非常好的正向收益。

反观可视化的低代码平台则因为产物是实际应用的原因,不管是现如今 SPA 单页应用还是以前的 HTML 站点都是使用 DOM 来作为页面绘制的主要手段,且页面内容增长远远达不到 D2C 的节点规模的,所以渲染压力相对较小,同时又带有很强的交互逻辑性,物料组件也需要管理和开发,基于以上种种条件下,DOM 自然而然的成为了首选的渲染器绘制方式。

最后就是 Canvas 通常不利于搜索引擎优化(SEO),因为它的内容不易于解析和理解。同时也不支持选择、复制和粘贴等基本的用户界面功能,而 DOM 确很好的支持了这些点。

因此在编辑器渲染技术选型中,需要根据具体的应用场景和需求来选择使用哪种技术:

  • 需要高性能的图形和动画效果,不需要 SEO,可以选择 Canvas;
  • 需要更好的可维护性和易用性,可以选择 DOM

总结


在本章节,主要带大家了解 DOM 和 Canvas 在 D2C 和 Lowcode 领域中的一些应用和技术选型的一些细节点。为后续开发物料组件和渲染引擎模块做一些技术积累,为后续开发做一些知识储备。

但由于大部分的公司的组件化基本都是基于 ReactVue 来开发,在接入低代码平台中的物料中心的时候,采用 DOM 的方案可以节约大量的改造成本,使用过渡也会更为平滑。

所以最终我们可视化搭建的设计器也将选择 DOM 作为搭建技术方案,至于在设计器中存在大量组件渲染卡顿的情况,在本章开头也提到了,除了基础的原生技术方案有区别之外,还可以通过一些额外的研发设计方案来规避,例如数据组装与视图渲染分离等来解决性能问题,这些具体的优化措施我们将放在搭建实战篇进行更多的细节讲解。

参考

  • The Future Web: Will Canvas Rendering Replace the DOM?
  • www.youtube.com/watch?v=Swp…
  • Google Docs is switching to canvas-based rendering. Here's what that means.

写在最后

如果你有什么疑问或者更好的建议,欢迎在评论区提出。 👏

4 架构:Canvas VS DOM

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/718567.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TiDB(6):数据迁移-TiDB Lightning

1 TiDB Lightning介绍 TiDB Lightning 是一个将全量数据高速导入到 TiDB 集群的工具&#xff0c;目前支持 Mydumper 或 CSV 输出格式的数据源。你可以在以下两种场景下使用 Lightning&#xff1a; 迅速导入大量新数据。 备份恢复所有数据。 TiDB Lightning 主要包含两个部分…

NSS [SWPUCTF 2021 新生赛]jicao

NSS [SWPUCTF 2021 新生赛]jicao 先看题目&#xff0c;要求我们post传参一个id。然后get一个变量叫json&#xff0c;并且通过json_decode()对一串JSON进行解码 payload&#xff1a; GET&#xff1a; ?json{"x":"wllm"} POST&#xff1a;idwllmNB

java中处理异常规范

java处理异常规范 文章目录 java处理异常规范一、尽量不要使用e.printStackTrace(),而是使用log打印,并记录exception二、不要用一个Exception捕捉所有可能的异常三、使用finally关闭流资源或者直接使用try-with-resource四、捕获异常与抛出异常必须是完全匹配&#xff0c;或者…

Spring Boot 中的 Redis 分布式锁

Spring Boot 中的 Redis 分布式锁 在分布式系统中&#xff0c;多个进程同时访问共享资源时&#xff0c;很容易出现并发问题。为了避免这些问题&#xff0c;我们可以使用分布式锁来保证共享资源的独占性。Redis 是一款非常流行的分布式缓存&#xff0c;它也提供了分布式锁的功能…

react - TS

TypeScript TypeScript 简称『TS』&#xff0c;是微软开发的一个开源的编程语言。 一、TS 特点 TS 主要有如下几个特点: 完全兼容 JavaScript&#xff0c;是 JavaScript 的超集 引入类型系统&#xff0c;可以尽早的定位错误位置, 帮助提升开发效率 let obj {a:1,b:2....}o…

四氯化硅铝的活性离子蚀刻

引言 铝膜广泛用于集成电路中的互连线。随着电路的集成规模和密度变得越来越大&#xff0c;有必要将互连线和间隔的宽度减小到几乎薄膜厚度。为了实现这一点&#xff0c;已经开发了具有定向蚀刻能力的平行平面电极型等离子体蚀刻。这被称为反应离子蚀刻&#xff0c;因为它采用…

基于免疫优化算法的物流配送中心选址规划研究(Matlab实现)

目录 1 概述 2 物流配送中心选址规划研究 3 Matlab代码 4 结果 1 概述 影响物流配送中心选址的因素有很多,精确选址优化问题亟待解决。通过充分考虑货物的配送时间,将免疫算法加入其中,介绍了物流配送选址模型的构建以及免疫算法实现的相关步骤,最后利用matlab软件进行分析,提出…

手机端三维人体建模软件-易模,为虚拟现实、游戏开发带来新体验

三维人体建模是一种高级的数字技术&#xff0c;用于将人体的形态、肌肉、骨骼等三维信息转化为数字模型。这项技术涵盖了计算机图像处理、计算机辅助设计等领域&#xff0c;具有广泛的应用价值。通过三维人体建模&#xff0c;可以更好地理解人体的结构和功能&#xff0c;对于医…

弗迪科技携手纷享销客共建CRM系统,数智化升级加速“灯塔工厂”征程

当前&#xff0c;全球新一轮科技革命正和产业升级融合发展&#xff0c;数字化技术成为各行各业升级发展的重要推动力。 自2018年起&#xff0c;世界经济论坛与麦肯锡咨询公司发起“灯塔工厂”项目&#xff0c;全球严选制造业数字化转型典范作为“数字化制造”和“全球化4.0”的…

squid代理服务应用

squid代理服务器 代理的工作机制&#xff1a; 代理服务器的概念及其作用&#xff1a; 其主要作用有&#xff1a; Squid 代理的类型&#xff1a; 安装 Squid 服务 编译安装 Squid 修改 Squid 的配置文件 Squid 的运行控制 创建 Squid 服务脚本 构建传统代理服务器 生产环境…

红黑树:变色旋转规则化抽象逻辑分析

文章目录 一.红黑树的定义红黑树平衡性论证 二.红黑树的节点插入插入新节点后最小违规子结构(抽象分析)最小违规子结构一号的规则化算法分析最小违规子结构二号的规则化算法分析 三.红黑树类代码托管四.红黑树与AVL树的对比 旷世奇才发明的数据结构 一.红黑树的定义 红黑树的节…

【C语言初阶(10)】函数练习题

文章目录 1. 判断素数2. 判断闰年3. 函数实现二分查找4. 记录函数调用次数 1. 判断素数 题目内容 写一个函数可以判断一个数是不是素数。 素数 素数也叫做质数&#xff0c;一个只能被 1 和它本身整除的数字称之为素数。 例如&#xff1a;7 这个数字只能被 1 和 它本身&#x…

赛效:怎么将PPT转为PDF

1&#xff1a;在电脑网页上打开云组件&#xff0c;点击“PPT转换”菜单里的“PPT转PDF”。 2&#xff1a;点击“选择文件”可以将本地PPT文件添加上去。 3&#xff1a;文件添加成功后&#xff0c;点击下方的“开始转换”按钮。 4&#xff1a;文件转换成功后&#xff0c;在预览页…

vue动态修改浏览器标题和logo

问题描述 需要将一个系统&#xff0c;更改一下标题、logo&#xff0c;然后部署成另一个系统&#xff0c;由于不想单独拉出一套代码&#xff08;单独拉出来后维护成本增加&#xff09;&#xff0c;所以想要动态改变系统标题和图标 解决方案 将项目制造一个入口可以修改项目的…

20230703 -- scRNAseq from gastric cancer

文章标题&#xff1a;《Single-cell atlas of lineage states, tumor microenvironment and subtypespecific expression programs in gastric cancer》 DOI: 10.1158/2159-8290.CD-21-0683 数据集组织形式快照&#xff1a; step1 利用Seurat包整合数据 #! conda env R4libra…

Hombrew中AdoptOpenJDK已废弃更换Eclipse Temurin安装最新版JDK,并实现不同JDK版本之间切换

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

Python基础 —— 运算符

每天提升一 。。。。。。 〇、概述 Python 中有很多运算符&#xff0c;大体分为 算数运算符、赋值远算符、比较运算符、逻辑运算符。通过这些运算符能够更好地完成一些列的数据运算。 一、算数运算符 1. 算数运算符 算数运算符 主要用于 数值类型&#xff08;整型、浮点型…

TCP三次和四次握手:

内容来自思学堂&#xff1a; TCP三次握手&#xff1a;确保双方都在线上 TCP四次握手&#xff1a;处理客户端要断开连接的需求

JavaWeb学习路线(11)—— Maven延伸

一、分模块设计 &#xff08;一&#xff09;概念&#xff1a; 将项目按功能拆分出若干个子模块。 &#xff08;二&#xff09;作用&#xff1a; 方便项目管理维护、扩展&#xff0c;也方便模块间相互调用&#xff0c;资源共享。 &#xff08;三&#xff09;具体实现 1、抽取…

深度学习项目实战二: LetNet5网络结构搭建

深度学习项目实战二: LetNet5网络结构搭建 文章目录 深度学习项目实战二: LetNet5网络结构搭建@[TOC](文章目录)一、卷积基本运算公式二、LetNet5网络1. 网络结构![在这里插入图片描述](https://img-blog.csdnimg.cn/0008fe6e5886414eac09eed49556ad99.png)2. 导入相关包3. 代码…