越过一次,跑。
我们都听过这句经典的宣传语,然后我们都知道,没有什么能真正跑起来,充其量也只能做到。
当我们谈论一次编写多个终端时,显然不可能真正意味着跨所有终端运行。大多数情况下,您不需要在电脑和手环上同时开发功能。
对应我们多样化的跨终端需求,有让百花齐放的跨终端解决方案。
百花齐放的跨终端解决方案
基于Web的H5解决方案
这种解决办法是最直接的。简单来说,就是利用网页来跨端。由于我们大部分终端(甚至是封闭的小程序生态)都支持,所以你只需要开发网页,然后发布到多个终端即可。桌面端对应的解决方案是。
为什么不完全使用网络呢?
从开发成本低、标准统一、生态繁荣来看,H5方案基本上是最佳选择。但这种解决方案无法避免性能和体验上的差距。 Web生态的繁荣来自于其良好的历史兼容性,这也意味着沉重的历史包袱。
-/Weex类解决方案
移动平台上的性能体验,尤其是早期,非常差。前面我们也提到,这种差距主要来自于Web生态系统本身沉重的历史包袱。
像-/Weex这样的解决方案尽可能的取长补短,结合Web的生态和组件,让JS执行代码后可以使用组件进行渲染。由于抛弃了 Web 的历史包袱,这种类型的解决方案可以做出一些巨大的改变。
比如RN,如下图所示,将JS执行、布局(Yoga)和渲染(组件)分成三个流程,避免JS执行复杂任务时出现界面卡顿。通过放弃CSS中的大量标准,只支持部分Flex布局能力,降低了布局和渲染的复杂度。
该解决方案也有一些缺点:
最麻烦的是,这种解决方案意味着非常高的维护和支持成本。
在性能差距逐渐缩小的今天,这种复杂的解决方案是否值得维持ROI,需要根据我们场景的具体需求来考虑。
所要解决的问题与上述解决方案不同。无意继续利用Web生态。从设计之初就没有考虑Web生态。与依赖View渲染的RN相比,它是一个自绘制组件,通过Skia直接绘制到屏幕上。
既然可以充分利用GPU的能力,那就不用兜圈子了。理论上来说,它可以在两端获得更好的性能和一致性,这意味着理论上,基于未来的JS动态解决方案可以支持比WEEX更好的样式。
从前端角度来看,它仍然更像是一个开发解决方案,而不是跨端解决方案(虽然实际上是跨/iOS)。目前的主要问题是,从技术角度来看,Web 距离可用于生产可能还很遥远。另外,动态能力确实会让一些场景变得不适用。
小程序研发框架
小程序是一个被创造出来的问题。出于商业考虑,各个小程序都主动在Web生态的基础上构建了一个相对封闭的生态系统。从而与Web生态不兼容。然而,多端小程序的使用,或者小程序和网页端的同时分发,是很难被接受的。
由于小程序的端部是封闭且不可控的,解决小程序的跨端问题往往只能在研发框架层面完成。
编译时间方案
比较知名的编译时解决方案是Taro。大致原理可以解释为将JSX编译成小程序的WXML/WXSS/JS。这类框架的实现原理并不是真正的一个or类框架,而是一个通过静态编译将JSX模板翻译成小程序自己的模板。
这样做的局限性非常明显,那就是JSX是一种扩展语言(Blog写成to),而小程序中使用的WXML是一种模板语言,表达能力非常有限。我们不可能完成从通用编译型编程语言到模板语言的转变。
为了实现这一点,静态编译类框架采用了限制开发者编写方式的方法。这也是为什么 taro 对 JSX 的写法做了很多限制。这直接导致了无休无止的维护成本和严重损害的开发体验,随后taro/next也转向了运行时解决方案+静态编译优化的组合。
运行时场景
毫不谦虚地说,小程序的运行时解决方案应该是我在写第一个[1]时提出的第一个解决方案。
通过(类似Rax)我们可以让运行在小程序容器中的不直接操作DOM,而是通过传递给小程序的View层将操作数据映射到最终的界面。
Rax 、Taro Next等方案虽然不同,但思路是相似的,都是一定程度上利用小程序模板的动态能力+类框架进行渲染。当然,这种方式相比小程序原生的渲染方式有一定的性能损失。
支付宝终端性能测试
在某些情况下,这种损失是值得的。这些运行时框架还允许您关闭已编译模板、部分静态编译、虚拟列表等中未使用的属性,从而提高性能。
当然,最终嵌入仍然是一个解决方案。
作为业务技术团队,我们应该做什么?
以上是针对具体场景的一些解决方案。但对于业务技术团队来说,跨终端的本质是提高效率。针对新的变化提出新的方案是一回事,更重要的是如何让这种效率提升真正长期稳定,让我们的效率提升不至于成为从一个新方案到另一个新方案的跳跃。
让我们再看一下上面的图片。可以肯定的是,跨端需求和相应的解决方案仍然会频繁变化,并且不会有一个解决所有跨端问题的方案。而相对不变的部分,是值得我们为了长期和平稳定而必须进行的投资的。
& H5
它可能是众多容器中最特别的一个。虽然在某些场景下很难满足性能和体验的极限要求,但这将是最稳定、最长期、最受支持的解决方案。
从开发效率和未来长期维护演进的角度来看,只要能满足性能体验需求,Web方案仍然是重中之重。
同时我们还可以在APP容器上做更多的工作,比如通过容器提供一些内端的能力、基于能力的并行数据加载、页面保活等。
基础设施
无论采用哪种跨端方案,或者使用哪种容器,性能、稳定性、效率都是绕不开的三驾马车。
表现
不同的解决方案往往有不同的性能方案。上面我们也提到,在小程序的运行时解决方案中,会有减少编译模板产生的字段等优化。但实际上,除了这个具体方案的优化之外,大多数优化方式都是类似的:离线缓存、数据预取、快照、SSR、NSR等方案。
对于不同的码头和集装箱,性能问题的衡量和发现也应该是一致的。我们需要对页面在不同终端上的表现有一个清晰的感知和横向比较。
基于不同的端、不同的跨端方案,端侧的性能建设(端能力、针对某一端的性能测量方案、性能管理等)可能需要有所不同。但性能基础设施(首屏标准、数据分析、基础优化能力)跨终端应该相对稳定。
在终端侧能力方面,ICBU在WEEX性能优化初期就引入了并行加载能力,通过协议利用容器的并行加载能力。那么在新的容器(浏览器)中,虽然底层能力不同,但是仍然识别相同的协议。
在数据采集和分析方面,我们统一跨端基础库,使得不同端的不同技术方案可以在同一标准下进行分析、衡量和比较。
稳定建设
在无线方面,我们经常将性能和稳定性称为“高可用性”。稳定性主要涵盖灰度能力、业务监控、报警、错误监控、白屏检测等。
这些能力对特定终端和跨终端解决方案的依赖性较小。除了终端侧的数据采集逻辑略有不同外,其他构建部分都比较稳定。针对这些场景,集团也有一些跨端的解决方案,比如等。
工程基础设施
对于不同场景的跨端场景,虽然解决方案有一定的差异,但是我们的工程基础设施可以保持统一。
这样,当新的容器或者解决方案出现时,我们只需要根据相应的能力进行对齐,这样我们的上层业务代码和开发经验就可以保持一个相对稳定的状态。
业务逻辑跨端
相对而言,我们会发现,在各种跨端解决方案的演进中,如何渲染、如何布局等UI层面的变化远远大于业务逻辑层面的变化。即使对于小程序、小程序来说,它们的总体开发范式也没有发生太大的变化。例如,开发范式与声明式 UI 的开发范式非常相似,这也是存在的。
考虑到SEO和性能等问题以及基于Skia的渲染模式本身,for Web可能不会在很长一段时间内成为适用于生产环境的解决方案。
统一业务逻辑代码的组织后,我们可以使用for ALL的方案与Web客户端共享一段业务逻辑代码。
有时你并不需要真正跑步。提高性能并保持一致性足以实现您的目标。
视图层
目前,视图层的跨端依然充满变数。当我们的业务逻辑层跨端充分原子化后,可能我们的一些交互逻辑在视图层上并不是特别重,可以通过DX绑定原子化逻辑+数据+参数的方式覆盖更多跨端的场景。从而同时满足性能和效率的需求。
但对于一般场景下的视图交叉,目前还没有什么灵丹妙药。
总结
一般来说,跨终端长期处于并将处于多种解决方案并存且不断变化的状态。除了针对新变化、新场景选择或创建合适的解决方案外,我们还必须做好在这种动态变化中保持长期稳定的工作:
原文链接