<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>潘锦的空间 &#187; 跨端</title>
	<atom:link href="https://www.phppan.com/tag/%e8%b7%a8%e7%ab%af/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.phppan.com</link>
	<description>SaaS SaaS架构 团队管理 技术管理 技术架构 PHP 内核 扩展 项目管理</description>
	<lastBuildDate>Sun, 12 Apr 2026 03:47:23 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=3.9.40</generator>
	<item>
		<title>跨端架构的技术选型 2022</title>
		<link>https://www.phppan.com/2022/10/kd2022/</link>
		<comments>https://www.phppan.com/2022/10/kd2022/#comments</comments>
		<pubDate>Sat, 01 Oct 2022 03:03:55 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
		
		<guid isPermaLink="false">http://www.phppan.com/?p=2075</guid>
		<description><![CDATA[1. 跨端架构的意义 在《The Pragmatic Programmer》（中文翻译为《程序员修炼之道》）中 [&#8230;]]]></description>
				<content:encoded><![CDATA[<div>
<h1 data-id="heading-0">1. 跨端架构的意义</h1>
<p>在《The Pragmatic Programmer》（中文翻译为《程序员修炼之道》）中，作者提了一个 DRY(Don&#8217;t Repeat Yourself)原则，主要指在程序设计以及计算中避免重复代码，因为这样会降低灵活性、简洁性。 把一切重复的代码抽象出来复用，当需要修改的时候只需要修改一次。 这里的复用有如下一些级别：函数级复用、对象级复用、模块级复用、类库级复用、框架级复用。 咱们今天聊的跨端是更高层面的复用，是端的复用。</p>
<p>现实中我们常见的工作方式是安卓的同学写安卓，iOS 的同学写 iOS，前端写 Web，小程序，H5 等等。 随着整体技术的进步，前端技术的发展，大前端的兴起，跨端实现越来多了，一些跨端的框架层出不穷。最终想要实现的跨端架构希望能做到：<strong>一次编写，多端运行</strong></p>
<p>这里的端包括如下：</p>
<ul>
<li>PC 端(苹果，Windows、Linux)</li>
<li>移动端（安卓、iOS)</li>
<li>Web 应用、插件</li>
<li>小程序（微信小程序，企业微信小程序、钉钉小程序、快手小程序）</li>
<li>H5</li>
</ul>
<p>以上跨端的逻辑分为三个层面</p>
<ol>
<li><strong>硬件形态</strong>，或者说是设备，如 PC 电脑，移动设备、物联网设备</li>
<li><strong>相同硬件形态下的不同平台</strong>，或者说是跨操作系统，如 PC 下的 Mac、Windows</li>
<li><strong>相同平台下不同的应用或应用中的衍生应用</strong>，如 iOS 平台下浏览器应用（H5），微信小程序，支付宝小程序等</li>
</ol>
<p>应用运行在某个操作系统之上，操作系统位于硬件设备与用户之间，是两者沟通的桥梁。不同的硬件有不同的架构和指令集，其对应也会有不同的操作系统。不同的操作系统其对应的执行程序结构不同，如 Windwos 下的 exe 结尾的程序不能在 Mac 下执行。这就是所谓的平台。</p>
<p>那么如何跨平台？</p>
<p>跨平台也是跨端的一部分，我们常见的跨平台应用，如浏览器，它所实现的跨平台是指运行在浏览器中的网页是跨平台的，而浏览器本身并不会跨平台，浏览器的生产厂商根据不同的平台，不同的操作系统分别实现了对应的版本，在应用层面抹平了平台和操作系统的差异，实现了跨端的目的。</p>
<p>浏览器在实现过程中会提供一个容器给到开发者，屏蔽平台差异，提供统一的 API 接口，让一份代码可以在不同的平台运行。 与浏览器类似的还有 Docker、JVM、Node 等。</p>
<p>在浏览器跨端的基础上，Electron 整合 Chromium 的渲染引擎、NodeJS 和用于调用系统本地功能的 API，使用 JavaScript，HTML 和 CSS 构建跨平台的桌面应用程序，其可构建出兼容 Mac、Windows 和 Linux 三个平台的应用程序。</p>
<p>在跨平台之外，我们还需要跨应用，如在不同的小程序、H5 之间，既然是应用，那就一定会包含界面，业务逻辑，如何只写一次业务逻辑，在不同的应用中执行，在代码重复层面追求更极致的体验，遵从 DRY 原则，让代码一次编写，多端运行。</p>
<p>我们在追求跨端的同时，也希望跨端的体验能趋近于原生的体验。</p>
<h1 data-id="heading-1">2. 跨端架构的本质</h1>
<p>跨端架构的本质用稍微文艺一点的话来说就是：「<strong>世上本没有什么岁月静好，只不过是有人替你负重前行</strong>」</p>
<p>一个跨端的架构至少包含渲染、逻辑和原生能力支撑、端的构建方式。一般会通过实现自己的容器来抹平（或者兼容）端的差异。</p>
<p>这个容器一般会提供两个能力：一个是渲染，另一个逻辑和原生能力支撑。 看我们常见的几种方案：</p>
<h2 data-id="heading-2">2.1 H5 hybrid 方案</h2>
<p>浏览器自带跨端属性，通过各平台都有的浏览器，我们可以直接实现跨端，除了浏览器应用，我们也会把浏览器引擎嵌入到 APP 中，部分或全部使用浏览器渲染引擎，常见的如 Webkit、Blink 等。我们通过 Javascript 实现逻辑并且通过 JSBridge 调用 Native 的 API，透出的 API 需要应用在内部定制。我们一般用原生来实现要求高的界面，对于一些比较通用型，展示型的页面完全用 web 来实现，达到跨平台效果，各家的区别在于对于这块的定制和优化到了什么程度。</p>
<p><strong>组成：渲染：WebView，逻辑：JS Engine，底层能力：JSBridge + 原生能力</strong></p>
<p><strong>优点：</strong></p>
<ol>
<li>接入成本极低，基本可以复用前端的技术栈和生态；</li>
<li>效率平衡性较好；</li>
<li>支持热更新，发版效率高；</li>
</ol>
<p><strong>缺点：</strong></p>
<ol>
<li>受限于 webview 等原因，动画复杂、无限流类的页面性能较差；</li>
<li>首开等对时间要求高的场景不能很好地做到极致；</li>
</ol>
<p>如：网易云音乐，腾讯 QQ 中的大部分运营功能</p>
<h2 data-id="heading-3">2.2 框架 + 原生渲染</h2>
<p>以 React Native 和 Weex 为代表的方案，通过结合 Web 的生态和 Native 的组件，尽可能地取长补短，让 JS 执行代码后用 Native 的组件进行渲染，实现了远超 webview 的效果。以 React Native 为例</p>
<p><strong>组成：渲染：原生组件；逻辑：JS Engine + JSI；底层能力：原生组件；</strong></p>
<p><strong>优点：</strong></p>
<ol>
<li>开发成本均衡，大于 hybrid 模式，但是小于原生开发模式，一次开发，多端可用；</li>
<li>学习成本低，前端同学可以较快上手，上手速度快；</li>
<li>复用了前端生态，生态成熟，遇到问题，较容易解决；</li>
<li>有 Facebook 背书，发展相对靠谱；</li>
</ol>
<p><strong>缺点：</strong></p>
<ol>
<li>对于不同的平台特性的内容，需要有一些兼容的写法，甚至各平台各写一套；</li>
<li>交互复杂时，可能存在性能问题，新的架构已经大部分缓解了这个问题；</li>
<li>使用各端的原生组件渲染，相同代码渲染效果可能不一致性，已在尝试统一渲染。</li>
</ol>
<p>使用 RN 的 APP: Facebook、youtube、discord、QQ、百度等等 使用 Weex 的 APP: 淘宝、天猫、饿了么等</p>
<h2 data-id="heading-4">2.3 框架 + 自渲染引擎</h2>
<p>以 Flutter 为代表，Flutter 将代码编译成原生代码，并且直接在各个平台中使用高效渲染引擎 Skia 进行渲染，没有桥接，不调用平台相关控件。Flutter 没有直接借用原生能力去渲染组件，而是利用了更底层的渲染能力，自己去渲染组件。这种方式的链路会比 RN 的链路跟短，性能也会更好，同时在保证多端渲染一致性上效果更优。</p>
<p><strong>组成：渲染：Skia；逻辑：Dart VM；底层能力：原生组件</strong></p>
<p><strong>优点：</strong></p>
<ol>
<li>性能好，更接近原生；</li>
<li>跨平台体验优秀，跨多种平台，减少开发成本；</li>
<li>UI 跨平台稳定;</li>
<li>同时支持 JIT 和 AOT 两种编译方式的特性，在不同场景下可以使用不同的编译方式。</li>
</ol>
<p><strong>缺点：</strong></p>
<ol>
<li>UI 跨平台，但原生能力没有，脱离不开原生，开发人员需要具备原生（Android、iOS）基础开发能力，兼容适配性较差；</li>
<li>稳定性、可能会因为引入了 flutter 而导致线上的 crash 率增加；</li>
<li>代码可读性较差，Widget 的类型难以选择；</li>
<li>生态中的 SDK，各种第三方包鱼龙混杂，没有一个官方的标准</li>
</ol>
<p>除了最开始的 Android 和 iOS 跨平台支持，最新已经开始支持 Web 和 MacOS，未来还会继续支持 Win 和 Linux 平台的。在 Web 场景下，目前 Flutter 只能说可以用，但是还有挺多需要优化的空间，比如编译后 Web 文件大小，特定场景下的性能以及不同浏览器内核的兼容等等。</p>
<p>使用 Flutter 的应用：如钉钉（定制了较多的功能）、美团外卖、马蜂窝等</p>
<h2 data-id="heading-5">2.4 DSL 编译 + 混合渲染</h2>
<p>该方案提供自定义 DSL 静态编译转化成目标源代码，包括 iOS、Android，H5 以及中国特色的各小程序平台。主要包括 uni-app、taro、Chameleon、Rax 等等。但各家实现不同，支持的平台类型也不一致，以 uni-app 为例：</p>
<p><strong>组成：渲染：混合渲染、weex原生渲染、webview渲染，小程序和 app-vue 页面属于混合渲染，app-nvue 页面全部是 weex 原生渲染，H5 全部为 webview 渲染；逻辑：JS Engine + VUE; 底层能力：原生组件、原生插件；</strong></p>
<p><strong>优点：</strong></p>
<ol>
<li>支持多种小程序，多端；</li>
<li>开发成本低、学习成本小，本质上就是在写前端；</li>
<li>插件多，但是以个人开发者居多，质量参差不齐，没有保证；</li>
</ol>
<p><strong>缺点：</strong></p>
<ol>
<li>什么都想要，而什么都没有到极致，如果只是做一个能用的应用，是合适的，如果对于性能要求高，或者有比较复杂的交互，需要谨慎调研考虑一下；</li>
<li>兼容性问题依然有很多小细节问题，存在多端同时上线，某一端存在 bug 的情况；</li>
<li>原生功能依赖于 nvue ，对于没有提供的原生功能，需要对应的原生开发同学来开发；</li>
</ol>
<p>我们要做到应用的跨端，在 PC 端相对好确定一些，以前端为主，客户端辅助实现部分前端薄弱的部分，如安装过程和一些和操作系统打交道或对性能要求比较高的部分。我们常用的 PC 端架构可以基于 Electron 、Tauri，在多平台客户端和 Web 端实现跨端。</p>
<p>在移动端，则更复杂一些，不仅要跨 iOS 和安卓这种操作系统级，还要跨微信小程序、支付宝小程序这种应用的衍生应用。下面我们聊聊一些有人在用的方案。</p>
<h1 data-id="heading-6">3. 实际落地的几种方案</h1>
<p>在考虑实际落地之前需要明确一下是在什么层面的跨端，最理想的是跨全端，即跨硬件平台，在 PC、移动端设备，另一种是分两种，大屏和小屏，大屏主要是针对 PC 端、小屏主要是针对移动端。</p>
<p>如果是跨全端，不仅仅要考虑技术实现，从产品、到设计都要考虑，产品要考虑针对不同的端的应用场景，设计要考虑不同的屏大小下的体验效果和交互方式。这里我们只考虑移动端的情况。</p>
<h2 data-id="heading-7">3.1 Qunar 的 React Native 优先的多端统一化方案</h2>
<p>Qunar 方案的主要逻辑是基于 Qunar 已有的 RN 技术栈，已经解决了 iOS 和 Android 的跨端问题，在此条件下，其问题变成了如何将 RN 转换为 H5 和各小程序。业内没有现成的方案，只能曲线救国，分别处理：</p>
<ul>
<li><strong>对于 RN 到 H5</strong>，选择使用 Twitter 开源的 react-native-web，将 RN 代码运行在 H5 上，这个把 RN 的组件和 API 都用 H5 实现适配一遍，适配其行为和默认样式，在打包的时候使用 webpack 的别名机制将用到的组件替换成 react-native-web 里的对应组件。react-native-web 对原项目没有侵入性，无需改动原来的代码，只需在项目中加入一些 webpack 构建配置即可构建出运行出和 React Native 应用一致效果的 Web 应用。</li>
<li><strong>对于 RN 到 小程序</strong>，选择使用 Remax 组件实现一套 RN 的组件库，借用 remax 来适配到多端。Remax 的运行时本质是一个通过 react-reconciler 实现的一个小程序端的渲染器。Remax 通过 react-reconciler 生成一份自定义的 VNode Tree，再遍历 Tree 递归模版（微信小程序模板不支持递归，Remax 会为微信小程序生成一个 20 层的模板调用）渲染出对应的小程序页面。在生成之前 Remax会 为每个组件生成一份模版,然后把这份模版写入每个 page 页面里。由于小程序本身 View 与 JS 分离，因此在拿到 Vnode 时，需要通过小程序自身的 setData 触发小程序渲染。</li>
</ul>
<h2 data-id="heading-8">3.2 Flutter 全平台方案</h2>
<p>Flutter 可以理解为使用 Dart 语言定义了一套和原生一样的图形系统，其底层使用和 Android 原生一样的 Skia 引擎，安卓下直接用系统引擎，苹果生态下用自带的 SKia，这样就完全避免了 RN 中 JS Core 和原生模块通信造成的各种开销。</p>
<p>Flutter 这种自实现的引擎能带来目前体验最好的两端一致性，同一套代码，在 Android 和 iOS 上执行，从业务逻辑到页面布局再到最终渲染，都是在 Flutter 内部完成，通过 Flutter 实现的功能，在不同系统手机上的呈现效果是高度一致的。</p>
<p>Flutter 在 Android 和 iOS 上对跨端的支持较好，现在也有较多的业务在用 Flutter 完成这两端的跨端。对于 H5 而言，2019 年 2 月 Flutter1.2 版本和后面 5 月发布的 1.5 版本都主要支持了 Web ，但是到现在为止，Flutter 在 Web 端目前只支持 Dart–&gt;JS 的转换，以及 UI 层的对齐，在工程化和性能优化方面做的工作并不多。Google 官方对 Flutter Web 性能优化所做的事项还比较少，编译输出的页面存在较大的性能问题，主要体现在以下两方面：</p>
<ul>
<li><strong>首屏渲染时间长</strong>。即使使用了 FutureBuilder 把业务代码拆分成 xxx.part.js 之后，main.dart.js 体积依然维持在 1.1M。单一文件加载、解析时间过长，且静态资源缺少 CDN 化的支持，势必会影响首屏的渲染时间。</li>
<li><strong>滚动性能较差</strong>。 Flutter Web 自身实现了一套页面滚动机制，在页面滚动过程中，会频繁的创建 Canvas，最终导致滚动性能问题，甚至引起页面 Crash。</li>
</ul>
<p>在阿里钉钉，基于 Flutter 构建的跨四端研发框架 Dutter，自己解决了数据通信问题、实现了自己的组件库，目前核心组件可以做到四端兼容，具体可以见：<a title="https://www.51cto.com/article/708672.html" href="https://link.juejin.cn?target=https%3A%2F%2Fwww.51cto.com%2Farticle%2F708672.html" target="_blank" rel="nofollow noopener noreferrer">钉钉 Flutter 跨四端方案设计与技术实践</a></p>
<h2 data-id="heading-9">3.3 Hybrid 方案</h2>
<p>这种反而在大厂是更常用的方案，其主要原因是大厂一般会有自己的框架团队，能够做比较多的定制，甚至有些把 Flutter 改吧改吧，自己实现一套，或者以容器化的方式实现自己的 Hybrid 方案。具体实现就不介绍了，这里主要介绍一下常用的一些性能优化的点，Hybrid 方案的性能优化的关键点就六个字：更早，更近、更快。</p>
<ul>
<li><strong>更早</strong>：提前创建或初始化一些基础组件，如 WebView，减少用户体验层面等待的时间，让用户感觉更快了，也就是我们常说的预加载；</li>
<li><strong>更近</strong>：把资源提前缓存在本地，这里的资源可以是 Web 的资源，也可以是常用的配置数据等等，本地可以是客户端，也可以是移动端，如我们常见的「离线包」，特别是一些大流量的应用，一些资源的提前下发可以解决 CDN 等的突发流量等问题；</li>
<li><strong>更快</strong>：通过 Native 的方式替换一些跨端方案中的薄弱点，如一些网络控制的能力，一些视频播放或加载速度的优化等等</li>
</ul>
<h1 data-id="heading-10">4. 小结</h1>
<p>为什么标题中带一个 2022 呢？ 因为<strong>技术是不断演进的，是不断发展的</strong>，今年的方案不一定适用于明年，期望有更好的方案出现。</p>
<p>写了这么多，把跨端的问题粗略的过了一遍，给自己温习一下，也分享一下。</p>
<p>任何跨端都是有成本的，当你选择跨端的时候，需要想的第一件事情，是否有必要这么做？ROI 如何？</p>
<p>跨端的问题很多最终都需要回归到当前端来解决，特别是一些对性能，对底层要求比较高的问题往往要在端来解决。</p>
<p>整体来看，跨端技术选型需要考虑如下 4 个问题：</p>
<ol>
<li><strong>战略和业务的问题</strong>，从公司产品战略和业务产品的角度探讨是否有必要跨端，如你的业务是否有强依赖的多端需求，各端的用户体量是否值得有如此投入？还是只要一端强就可以了？</li>
<li><strong>人和组织的问题</strong>，在确认有跨端的强需求后，再看是否有合适的人和人才梯队来构建你想要的跨端架构，并且在确定跨端架构后考虑关于分工的问题，如一部分同学（如原移动端的同学）负责框架和能力，一部分的同学（如前端的同学）负责业务。在考虑现有人和组织的问题的时候，考虑一下后续人才招聘和团队人才密度的情况；</li>
<li><strong>生态的问题</strong>，生态的问题会决定研发效率，是否有成熟的生态，是否有前从把坑都踩过了，当遇到某个场景是否有现成的解决方案或者类似的解决方案等等；</li>
<li><strong>性能和体验的问题</strong>，随着业务的复杂，交互，场景也会越发的复杂，当遇到因复杂交互，或者复杂业务场景引起的性能问题时，是否有成熟的解决方案，或者退一步，是否可以解决？在多端一致性的问题上，是否能满足需求，或者兼容处理的成本有多高？</li>
</ol>
<p>最后，祝大家国庆节快乐~</p>
<p>参考文档：</p>
<ul>
<li><a title="https://zhuanlan.zhihu.com/p/401795558" href="https://link.juejin.cn?target=https%3A%2F%2Fzhuanlan.zhihu.com%2Fp%2F401795558" target="_blank" rel="nofollow noopener noreferrer">React Native 优先的多端统一化方案</a></li>
<li><a title="https://zhuanlan.zhihu.com/p/300680122" href="https://link.juejin.cn?target=https%3A%2F%2Fzhuanlan.zhihu.com%2Fp%2F300680122" target="_blank" rel="nofollow noopener noreferrer">前端开发：如何正确地跨端？</a></li>
<li><a title="https://tech.meituan.com/2021/03/18/flutterweb-in-meituanwaimai.html" href="https://link.juejin.cn?target=https%3A%2F%2Ftech.meituan.com%2F2021%2F03%2F18%2Fflutterweb-in-meituanwaimai.html" target="_blank" rel="nofollow noopener noreferrer">FlutterWeb在美团外卖的实践</a></li>
<li><a title="https://www.cnblogs.com/skychx/p/cross-platform-tech.html" href="https://link.juejin.cn?target=https%3A%2F%2Fwww.cnblogs.com%2Fskychx%2Fp%2Fcross-platform-tech.html" target="_blank" rel="nofollow noopener noreferrer">【深入解析】跨端框架的核心技术到底是什么？</a></li>
<li><a title="https://tzxhy.github.io/2020/02/19/%E5%85%B3%E4%BA%8E%E8%B7%A8%E7%AB%AF%E6%96%B9%E6%A1%88%E7%9A%84%E8%B0%83%E7%A0%94/" href="https://link.juejin.cn?target=https%3A%2F%2Ftzxhy.github.io%2F2020%2F02%2F19%2F%25E5%2585%25B3%25E4%25BA%258E%25E8%25B7%25A8%25E7%25AB%25AF%25E6%2596%25B9%25E6%25A1%2588%25E7%259A%2584%25E8%25B0%2583%25E7%25A0%2594%2F" target="_blank" rel="nofollow noopener noreferrer">关于跨端方案的调研</a></li>
<li><a title="https://juejin.cn/post/6966626823912308772" href="https://juejin.cn/post/6966626823912308772" target="_blank">写给前端的跨平台方案、跨端引擎的本质</a></li>
<li><a title="https://www.51cto.com/article/702495.html" href="https://link.juejin.cn?target=https%3A%2F%2Fwww.51cto.com%2Farticle%2F702495.html" target="_blank" rel="nofollow noopener noreferrer">聊聊跨端技术的本质与现状</a></li>
<li><a title="https://juejin.cn/post/7063738658913779743" href="https://juejin.cn/post/7063738658913779743" target="_blank">2022 年 React Native 的全新架构更新</a></li>
<li><a title="https://www.51cto.com/article/708672.html" href="https://link.juejin.cn?target=https%3A%2F%2Fwww.51cto.com%2Farticle%2F708672.html" target="_blank" rel="nofollow noopener noreferrer">钉钉 Flutter 跨四端方案设计与技术实践</a></li>
<li><a title="https://www.fly63.com/article/detial/3042" href="https://link.juejin.cn?target=https%3A%2F%2Fwww.fly63.com%2Farticle%2Fdetial%2F3042" target="_blank" rel="nofollow noopener noreferrer">几种常见的APP开发模式的优缺点</a></li>
<li><a title="https://ask.dcloud.net.cn/article/39626" href="https://link.juejin.cn?target=https%3A%2F%2Fask.dcloud.net.cn%2Farticle%2F39626" target="_blank" rel="nofollow noopener noreferrer">APP开发为什么选择uni-app，目前主流的APP开发方式总结和对比</a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2022/10/kd2022/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
