当前位置: 首页 > Web前端 > HTML

语雀桌面技术架构实践

时间:2023-03-28 19:44:03 HTML

作者:易志林(魏君)语雀桌面作为语雀为用户提供的生产力工具,自上线两年多来一直保持着高频迭代和业务健康增长。本次主要介绍我们在桌面工作时的一些技术架构思考和实践,也会分享一些通用的桌面应用解决方案和积累的经验。文章将分为四个部分。首先简单介绍语雀桌面,然后介绍语雀桌面目前的应用架构和重点,再介绍架构中的几个架构重点,最后进行总结。语雀桌面介绍语雀是蚂蚁体验技术部孵化出来的一款笔记文档知识库工具。两年前,我们根据语雀用户的特点和后续的发展策略推出了语雀桌面客户端,旨在为创作者提供更好的创作体验。与现有浏览器提供的产品和服务相比,我们提供的桌面产品主要考虑以下几点:无干扰:给用户身临其境的创作体验,不像浏览器有其他窗口和标签可以干扰,用户的心意是准备好的去。系统级常驻:打开速度更快,可一键启动或通过各种快捷工具调用。集成更多操作系统能力:多窗口、系统菜单和快捷键,提高创作效率,读写文件,与系统软件集成。离线:期望能够在离线或网络较弱的情况下毫无障碍地进行创作。桌面架构研发测试概览左图主要分为三层。底层是语雀的基础设施,依赖于语雀后台提供或封装的大量云服务,以及底层依赖的安全能力和存储模块。中间层是一些更偏向于应用架构的能力封装。上层是代码层面使用的辅助能力,以及主要的流程模块,然后是应用的一些管理能力和一些UI相关的功能模块。顶层是基于底层架构的业务应用。包括桌面应用的几个核心模块,以及子应用(后面会详细介绍子应用的概念)所承担的一些业务模块。同时最右边还有很多辅助研发依赖,完成语雀桌面的发布,质量稳定管理。架构概述-要点与普通Web应用相比,我们认为桌面端的以下能力更为重要:包括安全、软件升级、桌面常用基础能力:架构概述-安全安全是生产力工具软件的生命线语雀,尤其是作为知识管理工具,语雀非常重视安全性。基础安全下载安装包时,需要有安全管理机制,避免下载过程中被恶意替换;升级到最新的Electron版本(语雀目前是跟随正式版,也会参考微软的头部应用(vscode),避免没有考虑到的场景;同时,用户离线下载的文件到本地,包括图片,附件等,也需要加密启动安全杀毒软件:启动安全主要是启动软件时的一些安全问题,比如二进制模块是否有签名,避免由于无法启动杀毒软件,也可以联系安全厂商加白名单,也可以提高启动速度禁止调试:因为软件代码会下载到客户端,所以可以禁止软件在客户端运行浏览器调试数据库密钥管理:即使本地数据库文件被恶意获取,也要保证里面的内容不能被查看,我们生成一个内存安全ty级方案,保证非当前电脑的其他语雀软件即使获取了数据库文件也无法打开,应用安全渲染容器设置白名单,控制恶意页面的引入;渲染进程关闭Node功能,开启隔离模式,避免渲染进程权限过大;Electron本身是web开发模型,所以web遇到Electron遇到的安全问题在Electron中同样可以遇到,可以统一处理。架构概览-软件升级客户端软件相比web还有一个很大不同之处。有功能更新,就有升级过程。和网页一样,直接刷新页面即可。语雀桌面作为一款快速迭代的产品,在升级过程中踩了不少坑。语雀桌面由两部分组成:包括Electron、Node.jsPackage+等基础模块的软件和自己的业务代码。MacOS:Mac下的升级过程比较简单。软件下载完成后,使用hdiutil模拟用户手动安装过程,用户重启即可完成安装。Windows:由于Windows下环境特殊,需要下载安装包后,通过主进程自动打开安装界面,逐步引导用户手动安装。其实这个方案对于我们早期的功能迭代是非常好的,但是随着使用量的增加,也遇到了很多问题。举个例子:每次升级都会消耗巨大的带宽:每安装一个UV,就有将近100M的下载量。每推送一个版本,都会遇到OSS流量告警,对应成本;安装体验差:在Windows下,因为每次升级几乎都是全新的安装过程,所以体验比较差,经常有用户抱怨。因此,我们研究了一种增量更新解决方案。一个Electron程序包括Electron核心包和业务代码。实际上每次只是更改了业务代码,所以理论上每次更新只需要增量更新业务代码即可。增量代码直接下载到Mac下的增量代码后,就可以替换了。Windows下比较复杂,主要遇到两个问题:文件占用问题:由于Windows系统的特点,如果一个文件正在使用,是不能删除的。所以如果要替换的话,一定要关闭程序,然后删除再重新启动。所以我们写了一个.exe可执行文件来关闭程序,更新文件,启动麻雀。UAB权限控制:文件写入还有一个问题就是C盘的文件一般都需要授权才能操作。我们的软件是没有办法在启动软件的时候得到这么高的权限的。但是,Windows7及更高版本中添加了新的PowerShell函数。通过该功能,可以引导用户进行授权,获得更高级的权限。当然,过程中遇到的细节问题还有很多,比如替换过程中的中英文路径问题,自定义环境变量的位置问题等。业务解耦组件:多窗口管理:在为用户提供更方便的多窗口编辑能力时,如何管理这些窗口的打开、关闭、性能监控等;Webview:不同的编辑器和子应用都是通过Webview来进行托管的,需要有一个通用的模块来维护系统中使用的各个webview的生命周期等;offlineandonline:电脑离线和在线状态获取,虽然浏览器提供了这种状态获取和事件监控,但是Windows并没有太准确。我们封装了一个更通用的模块。桌面端架构的重点从架构上看,比起技术有多酷,更重要的是研发交付效率高不高,性能如何,稳定性高不高。我们认为以下三点是判断一个架构好坏的重要标准。架构重点——交付效率在桌面功能方面,包括编辑器在内,60%以上的功能模块都与web保持一致,所以一开始就采用了同构的方案。同构过程中的一些心得:CommoncodemovedtoCommondirectory:语雀代码仓库是monorepo模式,如果没有明确的目录划分,很容易造成跨终端兼容问题。有了这个协议,业务研发的同学会注意到,这个会在移动端或者桌面端使用,通过webpack别名来适配多终端:这种方式比较常见,比如每个终端都有不同的网络请求库,adapter/request。当webpack构建时,适配器映射到不同的最终实现。定义多端代码开发规范:梳理不同端之间的一些差异,避免在开发过程中挖坑。交付效率(同构问题)虽然同构模型可以解决我们当时遇到的一些问题,但是随着业务规模和功能的增加,一些问题也陆续暴露出来:迁移到Common目录,各种依赖问题:功能多在桌面终端上线之前,将一些复杂的组件迁移到Common上需要花费大量的时间。缺乏动态能力,迭代滞后(web端和桌面端功能不一致):组件在web端发布后,需要发布桌面端支持,所以我们经常会遇到web端和桌面端功能不一致的抱怨。容易出现多端兼容问题(环境依赖等):虽然我们定义了一些规范,但很难完全避免环境依赖问题。缺少独立的沙盒很容易影响主应用(内存泄漏,样式):web可能会跑完可以刷新等,所以不容易遇到问题,但是因为桌面是常驻的,如果一些内存泄漏或者样式污染如果出现问题,直接影响整体的可用性。交付效率(子应用)基于以上原因,我们将代码复用架构升级为子应用模式,使用桌面容器嵌套一个html在线或离线页面。简单来说,子应用模式可以理解为支付宝九宫格进入的各个小程序模块。快速迭代:提供独立发布迭代能力,无需跟随桌面整体发布。而且商科生直接跟进整个交付过程,无需桌面生参与,提高了交付效率。拥有终端相关的能力:每个子应用都可以使用桌面端默认提供的JSBridge能力,自然可以实现与桌面端模块相同的能力。独立沙箱:独立于桌面上的主窗口,使用桌面上的容器完成渲染,因此可以完全隔离进程层面,彼此之间的内存开销一目了然,更好的控制,确保整体应用稳定性。加载初始化:除了上面的一些优点之外,也会有一些问题,比如加载速度慢等,我们通过webview预热和缓存在一定程度上解决了这个问题。架构重点——性能性能是桌面软件必须面对的问题,需要从不同角度不断优化,主要包括这几个方面:启动速度优化:启动速度是用户的第一印象,我们主要使用main的缓存流程代码,尽快显示loading,避免白屏。主窗口和渲染进程的一些任务同时执行,达到并发的效果;主进程优化:主进程和渲染进程同步执行。如果主进程做的任务太多,会导致用户卡顿甚至崩溃。所以尽量减少主进程做的事情;网页优化:同时也可以利用之前在网页上做的很多优化。比如懒加载、合并模块等(合并多个模块也有开销);webview优化:比如预热webview,采取一些性能控制措施,避免失控。性能(持久性任务)性能优化并不是说你完成一些任务就可以彻底解决问题,而是一个长期的过程。可能后面我们添加新功能的时候,代码中出现了内存泄漏问题,很容易导致性能下降。因此,我们也建立了一些持续的机制:主要包括:日常观察:在开发模式中,建立对绩效指标的观察能力,做到知其然;自动化任务:日常生活中也会有自动化任务,模拟真实用户长时间使用,及时发现内存泄露等问题;性能仪表盘:对于线上的性能水平,可以有一个全面的感知能力,在灰度发布过程中可以重点关注。架构重点——稳定性与web端相比,桌面端的稳定性要求也更高。从研发流程来看,我们主要有两个任务:单元测试和集成测试:用代码测试辅助整体稳定性UIA:通过模拟用户行为提高稳定性UIA自动化测试回归,及时发现异常。注:UIA是语雀工程师开发的自动化解决方案。详情参见:MacacaMacOS还建立了稳定性仪表板和实时警报来感知在线性能。为了保证每个版本的稳定性,降低回归成本,我们采用每周预览版的敏捷研发模式,分解大版本带来的集成风险。总结当前业务量和团队经验,选择合适的技术架构;现在肯定有比Electron更新的桌面架构,比如flutter、tauri等,综合看比如团队积累和稳定性,是否有成熟的商业化产品等;性能和稳定性优化是一个持续的过程,首先要建立测量和感知;交付效率和交付质量最容易被忽略,但它们是架构解决方案的重要考虑因素;架构的判断标准必须由业务效果决定,交付效率和交付质量是衡量业务效果的手段之一。