转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,为开发者赋能。表格作为一种基本的数据呈现方式,在各种软件系统中扮演着重要的角色。在移动互联网时代,即使是复杂的数据,也可以通过“表格”的排列清晰呈现给用户,用户可以从多维度进行查看、筛选和修改。无论是处理文档、报表、凭证还是票据,表格都可以额外存储更多的样式信息,尤其是对于离散数据的存储更高效。如今,企业纷纷开始尝试信息化转型。前端、后端、中台、云等概念逐渐家喻户晓。在几乎所有的B端产品中,表格作为交互组件受到广泛欢迎。但即便如此,由于样式复杂、操作繁琐等因素,表格在用户使用时往往会造成很多体验问题。尤其是在web项目中,表格技术往往受限于前端性能的限制。那么,有没有办法帮助开发者突破前端表格技术的困境,实现关键技术的落地呢?2020年6月30日,作为全球领先的软件开发技术提供商,葡萄城举办“赋能智变”线上品牌战略发布会。在本次会议上,葡萄城正式发布了“赋能开发者”的商业使命,并分享了前端表格开发等技术话题。前端表格给开发者带来的困扰在C/S架构的应用中,表格组件可以获得更多的资源支持,内存控制更直接。但是,当企业进行B/S转型时,前端表面临着诸多挑战。例如,多浏览器差异、浏览器沙箱机制、内存访问受限、客户端性能低等。在异构、参差不齐的前端开发环境中,这些问题会导致我们在开发应用时耗费大量时间和重复编码,而不是专注于核心业务。不仅费时费力,而且增加了软件开发的成本,更有可能因为外部环境的变化而影响系统的稳定性,造成后期维护成本飙升。综上所述,开发前端表格主要存在三大技术难点:性能、内存消耗、可靠性。为了应对这些技术难点,葡萄城结合多年的表格开发技术经验,推出了一款可以提高系统性能、可靠性、降低内存消耗的纯前端表格控件——SpreadJS。葡萄城SpreadJS表格控制技术针对前端表格开发的三大技术难点:性能、内存消耗和可靠性,SpreadJS提出了对策:基于双缓冲canvas绘图引擎,SpreadJS实现了基于行模式的极高处理性能基于稀疏矩阵存储策略,SpreadJS可以大大节省内存消耗。基于计算引擎技术,SpreadJS可以实现稳定可靠的应用系统。表单作为数据载体,经常出现“尖刺”、卡顿、UI界面“假死”、界面操作不流畅等问题。这些问题的症结在于浏览器渲染引擎的基本原理:当界面元素较多时,浏览器的渲染时间会明显增加,内存消耗也会增加。例如,现代应用为了追求更好的用户体验,需要反复优化UI界面,频繁修改界面的UI元素会导致浏览器多次重绘。在这个过程中,UI元素的创建和修改都会激活内部的垃圾回收机制,影响数据处理的效率。此外,前端开发环境的多样化,各种高DPI设备、手机、平板、4K显示屏、企业大屏等都增加了企业应用系统的处理负担。对于经常用于表示大量数据的表格,性能至关重要。也就是说,任何基于表格开发的应用系统都必须满足最小资源消耗的要求,才能实现高速渲染和刷新。为此,SpreadJS纯前端表格控件引入了Canvas绘图模型和双缓冲画布技术,具体实现方法如下。Canvas绘制模型由于传统表格组件使用DOM来显示表格数据,复杂的UI需要大量的DOM渲染,无论是在table还是div中。因此,在进行更新、滚动等操作时,需要不断地销毁和创建DOM,无形中增加了很多无效计算。为了解决这个问题,前端框架React和Vue3都采用了虚拟DOM的方式,而SpreadJS采用了更高级的方式——HTML5Canvas绘图。使用Canvas进行绘制,SpreadJS不仅不需要重复创建和销毁DOM元素,而且在canvas的绘制过程中打破了DOM元素在UI上渲染的诸多限制。SpreadJS可以绘制更丰富多样的UI元素,如线形、特殊图形等,通过绘制逻辑,还可以实现更精准的UI界面渲染,解决了浏览器差异带来的样式错误。但是如果只用一张canvas来渲染,那么每次绘制的时候,不管是主层还是装饰层,都需要通过绘制逻辑把所有的元素都绘制出来,显然效率很低。双缓存canvas技术为此,SpreadJS引入了双缓存canvas机制,在缓存的canvas中绘制不易改变的主体层。当渲染发生时,只需要将缓存画布中的主体层直接通过图像克隆的方式在主画布上绘制,另外绘制装饰层元素,可以大大优化整体绘制性能。SpreadJS双缓冲画布的技术特点:类似油画的分层绘制SpreadJS的绘图引擎是基于油画的绘图原理,分为主层和装饰层。主层渲染持久化且不易变化的元素,如背景、单元格、表格线条等,装饰层渲染常量可变元素,如选择框、拖动框、悬停效果等动态时使用缓存画布绘制发生,比如表格滚动,SpreadJS会清空主画布,根据行为上下文从缓存的画布中偏移画布,并将偏移层直接绘制在主画布上,然后在主画布上绘制剩余部分top让整个表格的滚动过程更加流畅。2、基于行模式的稀疏矩阵存储策略,可以大大节省内存消耗。虽然没有明确的规定,但是在业界的普遍理解中,浏览器都会对单线程的内存进行限制,比如64位的chrome,每个标签页的内存消耗不允许超过4G,而这个限制在手持设备,比如iPhone6s是1G,iPhone7是2G。这个限制在十多年前单页应用还不成熟的时候还不是问题。因为,那时候大家关心的是如何提高后端的处理性能,而前端只是一种静态的网页表达方式。随着前端工程的快速发展,各种前端工程脚手架日趋成熟,WebComponent标准提上日程,企业开始从C/S应用向B/S应用转型。这就需要前端开发人员去面对单线程处理复杂业务数据的挑战。这里的复杂不仅仅是数据量大,还有数据状态的处理。如何高效解决数据的前后端交互,如何快速响应数据变更和数据回滚?为此,SpreadJS提出了一个有效的解决方案——稀疏矩阵。对于表,常规的存储方式是数组,比如二维数组或者对象数组。在类似Excel的电子表格中,单元格内容是零散的,这意味着Sheet中会存在大量的空单元格,这些空单元格也会占用内存空间。针对电子表格这种松散的文档结构,SpreadJS采用稀疏矩阵存储模型(SparseArray)来保存数据。与传统的链式存储或数组存储相比,稀疏矩阵存储是基于行索引构建数据字典。在松散布局的表格数据中,稀疏矩阵只存储非空数据,不需要开辟空数据。额外的内存空间。这种特殊的存储策略不仅节省了内存消耗,也使得数据分片更容易。使用SpreadJS,可以随时在整个数据层中对一条数据进行帧化或反序列化。借助这一特性,开发者甚至可以随时更换或恢复整个存储结构中的任何一级节点,实现高效的数据回滚和数据恢复。3、支持复杂逻辑运算,实现应用系统公式稳定可靠的计算引擎,是类Excel电子表格的重要功能,广泛应用于科学、金融、金融、制造等领域。SpreadJS支持超过450种公式函数,还提供自定义公式和异步公式函数。看似简单的Excel公式,却具备高级编程语言的语法分析、解析、计算、执行等所有功能,当用户将公式设置到表中时,计算引擎会将其解析为中缀表达式,比如公式“SUM(A1:B1,3/E1,C1)+2*(D1-1)”,当计算由引擎解析后,会以树形结构存储在内存中,即称为表达式树。表达式树的生成是后续构建计算依赖链的关键。当公式被解析为表达式树时,计算引擎会根据计算上下文为其构建计算依赖链。计算依赖链的目的是按需计算。当表的内容发生变化时,只会计算受影响的表达式树,计算的基础是依赖链。如上图所示,这是SpreadJS计算引擎构建计算依赖链的简单流程图。表达式树从计算存储模型中找到对应的根节点和根节点ID,然后遍历整棵表达式树,找出其他依赖,建立依赖。当整个依赖链中的任何一个节点发生变化时,SpreadJS都会搜索依赖节点,并沿着依赖链重新计算。在这个过程中,不在依赖链中的节点不会被重新计算,也就是我们所说的脏值操作。利用这样的机制,SpreadJS大大提高了整个表的计算速度,给用户更好的用户体验和更准确的计算结果。除了绘图引擎、存储策略、计算引擎,SpreadJS还实现了更多的技术细节,比如触控支持、富文本支持、前端Excel导入导出、JSON存储等,这些技术点都承载了葡萄城好几年了。掌握开发技术和长期服务开发者的经验。SpreadJS广泛应用于各行业的企业信息系统开发。目前,SpreadJS已被广泛应用于各行业的信息系统开发中。满足表单文档协同编辑、数据填报、类Excel报表设计等业务场景,帮助华为、苏宁易购天弘基金、远光软件等各领域龙头企业搭建了软件系统其功能和布局与Excel高度相似,以加快此类信息系统的交付。以华为勘测设计平台的系统建设为例:基于SpreadJS开发的勘测设计平台承载了华为全球业务(基站)的规划、勘测设计任务。模板设计方式升级为在线填写,解决了模板不一致、素材数据不一致、文件管理难等问题。它还保留了Excel的数据计算能力,使所有模板和数据都可以在服务器上存储和管理。请访问葡萄城官网,了解更多葡萄城部分合作客户关于SpreadJS的产品介绍和应用案例。总结自1980年成立以来,葡萄城一直专注于开发技术领域,深入了解开发者的需求,将产品细节追求到极致。经过几十年的打磨,推出了一款高度复制Excel功能和用户体验的纯前端表格控件。SpreadJS可以完美匹配在线办公场景和前端表单系统的开发需求。未来,葡萄城将继续秉承“赋能开发者”的使命,支持和赋能所有创新的开发者,激发开发者的潜能,支持客户的成功,共同创造新的未来。
