<?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%e6%9e%b6%e6%9e%84/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>跨端架构落地过程中的 5 点思考</title>
		<link>https://www.phppan.com/2024/03/5-thoughts-on-the-implementation-of-cross-end-architecture/</link>
		<comments>https://www.phppan.com/2024/03/5-thoughts-on-the-implementation-of-cross-end-architecture/#comments</comments>
		<pubDate>Sat, 02 Mar 2024 02:51:58 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[架构和远方]]></category>
		<category><![CDATA[跨端架构]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=2172</guid>
		<description><![CDATA[离上次聊跨端已经过去一年多了，想再聊一下跨端架构这件事，因为在实际工作中落地遇到了很多问题，以总结。 先回顾一 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="color: #000000;" data-tool="mdnice编辑器">离上次聊跨端已经过去一年多了，想再聊一下跨端架构这件事，因为在实际工作中落地遇到了很多问题，以总结。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">先回顾一下上次聊的内容，上次主要聊了跨端架构的重要性、核心概念以及实际应用的几种策略。我们将跨端架构分解为三个层面：硬件形态、相同硬件形态下的不同平台和相同平台下不同的应用或应用中的衍生应用。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">还详述了几种常见的跨端架构方案，包括 H5 hybrid 方案、框架 + 原生渲染、框架 + 自渲染引擎和 DSL 编译 + 混合渲染。并深入探讨了如 Qunar 的 React Native 优先的多端统一化方案、Flutter 全平台方案和 Hybrid 方案等实际落地的策略。这些方案各有优缺点，需要根据特定的业务需求和场景来选择最适合的跨端架构方案。更多细节可以见：</p>
<p style="color: #000000;" data-tool="mdnice编辑器"><a style="color: var(--weui-link);" href="http://mp.weixin.qq.com/s?__biz=MzIzNDU2NDA0NA==&amp;mid=2247483786&amp;idx=1&amp;sn=80782a16158c6571e31154e22b3eb75d&amp;chksm=e8f53129df82b83f327d83d31f6be3028d4edbd451afd9ec3c93716c6ebc1c1b5b02b05989b4&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2">跨端架构的技术选型 2022</a></p>
<p style="color: #000000;" data-tool="mdnice编辑器">而今，在此基础上，我想再聊聊关于跨端架构落地过程中因为遇到一些问题而产生的思考。</p>
<h1 style="color: #000000;" data-tool="mdnice编辑器"><span style="font-weight: bold; color: #0e8aeb;">1 平衡</span></h1>
<p style="color: #000000;" data-tool="mdnice编辑器">在实现「<strong style="color: #0e88eb;">一次编写，多端运行</strong>」的愿景下，我们的核心关注点是<strong style="color: #0e88eb;">成本和体验</strong>。这其中，复用代表了我们在成本方面的考量，我们希望通过复用代码来降低开发和维护的成本。而提升用户体验则代表了我们在体验方面的追求，我们希望无论在哪个平台上，用户都能得到最好的原生体验。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">然而，这两个目标之间存在着一种天然的张力。在实践中，我们常常需要在代码复用（降低成本）和优化用户体验（提升体验）之间寻找一个平衡。这就需要我们不断地试错、调整，找到适合自己的最佳策略。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">当我们从跨端的角度出发，面对的主要挑战是解决界面渲染和能力复用的问题。使用跨端开发框架，如React Native、Flutter 等，帮助我们实现代码的复用，以及在不同平台上进行统一的界面渲染。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">再看到具体的界面，我们需要高效地解决屏幕适配的问题，这意味着我们的应用需要能够在不同大小、分辨率的屏幕上都能提供良好的用户体验。这可能需要我们使用响应式设计，或者针对不同平台进行特定的界面设计。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">在这些个过程中，虽然我们是想「<strong style="color: #0e88eb;">一次编写，多端运行</strong>」，这只是一个结果，这个结果的背后是<strong style="color: #0e88eb;">复用和提升用户体验</strong>，更深一个层次是<strong style="color: #0e88eb;">成本和体验</strong>，成本和体验是我们的核心关注点。在过程中，找到一个平衡。</p>
<h1 style="color: #000000;" data-tool="mdnice编辑器"><span style="font-weight: bold; color: #0e8aeb;">2 区分大小屏</span></h1>
<p style="color: #000000;" data-tool="mdnice编辑器">理想状态下，我们希望能够实现「一次编写，多端运行」，即不管在哪个平台，都只有一份代码。这样可以极大地提高开发效率，降低维护成本，并保证应用在各个平台上的一致性。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">然而在实际的开发过程中，我们往往会发现，由于大屏和小屏设备的使用场景、用户行为习惯以及界面布局等方面存在着显著的差异，简单地复用一份代码并不能提供最佳的用户体验。因此，一个比较实际且合理的做法是，对大屏和小屏设备使用不同的代码。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">对于大屏设备（如桌面应用和 WEB 版本），我们可以利用更大的屏幕空间来展示更多的信息，提供更丰富的交互方式。而对于小屏设备（如手机），我们则需要更注重信息的精简和易用性，以适应用户在移动环境下的使用需求。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">虽然区分了大小屏，但并不意味着不能实现代码的复用。我们可以通过抽象和封装共享的逻辑和组件，来实现在不同代码库之间的复用。这样，我们既能保证在各个平台上提供最佳的用户体验，又能充分利用代码复用来降低开发和维护的成本。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">这个区分的逻辑往往由<strong style="color: #0e88eb;">实际的业务、产品逻辑以及组织分工</strong>来决定的，各家不同。比如要考虑小屏上的定位，如果手机浏览器访问只是一个移动流量入口，并不作为业务功能的，那么基于运营逻辑的复用和代码的复用，可以把大屏 WEB 做移动端适配。</p>
<h1 style="color: #000000;" data-tool="mdnice编辑器"><span style="font-weight: bold; color: #0e8aeb;">3 选择合适的技术栈</span></h1>
<p style="color: #000000;" data-tool="mdnice编辑器">评估和选择技术栈对于跨端架构落地来说一件非常重要的事情，我们不仅仅要考虑性能、开发效率、可维护性、扩展性以及成本（包括熟悉成本、部署成本等），还要考虑这个技术栈所在的社区，成熟度，以及现有团队对技术栈的承受力。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">没有一种技术栈是适用于所有情况的。每种技术栈都有其优点和缺点，选择哪种最合适，取决于我们的项目需求、团队能力和期望的结果。如果选择新的、未经验证的技术，可能会导致技术债务，甚至会在项目的后期阶段导致大量的时间和资源消耗，最后让事情尾大不掉。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">在实际的评估和选择过程中，<strong style="color: #0e88eb;">跨端项目的负责人对此负主要责任</strong>。从团队的技能和经验是选择技术栈的关键因素。选择一种团队成员已经熟悉的技术栈，可能会比选择一种可能更适合项目但需要学习的技术栈更为实际。但是我们此时又需要考虑到是否当下的技术栈已经过时，或者引入新的技术栈能触发团队成员的学习热情，从而变成另一种激励呢？</p>
<p style="color: #000000;" data-tool="mdnice编辑器">进一步思考，我们必须认识到<strong style="color: #0e88eb;">技术的选择并非一成不变</strong>。随着项目的演进和业务需求的变化，我们可能需要对技术栈进行迭代和调整。当我们在选择技术栈时，应该考虑到这种可能性，并选择那些具有一定的灵活性和可适应性的技术。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">从技术栈的社区和生态系统，一个健康的社区和丰富的生态系统可以为我们的项目提供强大的支持，包括开源库、教程、工具和问题解答等等。选择一个有活跃社区和丰富生态系统的技术栈，可以大大提高我们的开发效率和项目的成功概率。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">我们必须清醒的认识到：<strong style="color: #0e88eb;">「人」是项目成功的关键</strong>。技术栈的选择应基于团队的能力和需求，而不仅仅是技术本身的优点。我们需要基于团队已有的人员配置，与团队成员进行深入的沟通，理解他们的需求和期望，然后做出最佳的选择。如果必要，我们还可以为团队成员提供培训和学习资源，帮助他们掌握新的技术。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">在实际选择技术栈的时候，其考量点主要是三个：<strong style="color: #0e88eb;">复用性、性能和多端一致性。</strong></p>
<ul class="list-paddingleft-1" style="color: #000000;" data-tool="mdnice编辑器">
<li>
<section style="color: #010101;"><strong style="color: #0e88eb;">复用性</strong>：成本角度，研发效率（包括开发效率和发版效率）</section>
</li>
<li>
<section style="color: #010101;"><strong style="color: #0e88eb;">性能</strong>：用户体验角度</section>
</li>
<li>
<section style="color: #010101;"><strong style="color: #0e88eb;">多端一致性</strong>：用户体验的统一</section>
</li>
</ul>
<p style="color: #000000;" data-tool="mdnice编辑器">在复用性方面主要是渲染层的事情，关注点是业务差异性，及是否有复用的必要，复用对于原有架构是否会产生更多的影响。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">在性能方面主要考虑响应速度、流畅度、稳定性等方面，主打一个顺滑和愉悦的用户体验。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">多端一致性主要是用户体验的统一和体感一致。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">以性能为例，可能需要考虑页面的复杂度，或者对性能的要求，比如长页面，多级嵌套页面，如iOS 上可能因为触发内存上限，系统优先清理 WebView，导致 WebView 白屏，或者页面的整体表现稳定性，不存在卡顿等等</p>
<p style="color: #000000;" data-tool="mdnice编辑器">那么，基于以上的考量点，大概要回答如下的判断基准问题：</p>
<ul class="list-paddingleft-1" style="color: #000000;" data-tool="mdnice编辑器">
<li>
<section style="color: #010101;">复用度有多少？复用和不复用的人力差有多少？</section>
</li>
<li>
<section style="color: #010101;">复用对现有架构有哪些影响？</section>
</li>
<li>
<section style="color: #010101;">是否存在多层嵌套、长页面的场景，对于性能的要求指标是什么？需要测试一下现有 web 方案是否会触发白屏、卡顿等情况</section>
</li>
<li>
<section style="color: #010101;">当前页面是否关键页面，如果出现页面级的不可用，如何处理？</section>
</li>
<li>
<section style="color: #010101;">是否存在多端一致性的要求，一致性要求有多少？</section>
</li>
</ul>
<p style="color: #000000;" data-tool="mdnice编辑器">在技术方案选择时，需要考虑当前产品所处的阶段，比如创始阶段，可能纯 WEB 方案就行，当发展到一定程度，可能在入口级页面需要有更好的用户体验，则可以把入口页面改为原生或者 Flutter 页面。</p>
<h1 style="color: #000000;" data-tool="mdnice编辑器"><span style="font-weight: bold; color: #0e8aeb;">4 渐进式开发</span></h1>
<p style="color: #000000;" data-tool="mdnice编辑器"><strong style="color: #0e88eb;">渐进式开发是一种实施新技术或变革的策略</strong>，它的主要目的是<strong style="color: #0e88eb;">降低风险、提高效率和保证稳定性</strong>。不会一下子太猛，导致项目挂了，或者风险不可控。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">通过逐步引入新技术或变革，我们可以控制每个阶段的风险，避免一次性全面改变带来的巨大风险。如果在某个阶段发现问题，我们可以及时调整或回滚，而不会影响到整个项目。</p>
<p style="color: #000000;" data-tool="mdnice编辑器"><strong style="color: #0e88eb;">渐进式开发也是一个持续学习的过程</strong>。团队成员可以通过实际操作和反馈，逐步深入理解新技术，提升自己的技能和知识，这通常比纯理论学习更有效。同时，每个阶段的成功实施都会增强团队的信心和动力，提高开发效率。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">市场和技术环境总是在快速变化，渐进式开发使得我们能更好地适应这些变化。我们可以根据新的需求和情况，逐步引入新技术或进行优化，使项目始终保持在最佳状态。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">渐进式开发在实施过程中有以下几种方式：</p>
<p style="color: #000000;" data-tool="mdnice编辑器"><strong style="color: #0e88eb;">低风险模块试点</strong>：选择非核心的，风险较低的模块进行新技术架构的试点实施。在低风险的环境中尝试和学习新技术，为后续的全面实施打下基础。在过程中需要注意选择的模块应具有一定的代表性，以便能够有效地验证新技术栈。同时，要做好版本控制和回滚计划，以防新技术栈出现问题。</p>
<p style="color: #000000;" data-tool="mdnice编辑器"><strong style="color: #0e88eb;">技术底层实施</strong>：从与业务逻辑关联较小，更侧重于技术实现的底层模块开始实施新技术。这种落地方式可以避免新技术栈对业务逻辑造成影响。同进，通过底层模块的实施，可以更深入地理解和掌握新技术栈。但是在具体实施过程中要特别注意到其广泛的影响，以及需要进行充分的测试，确保底层模块的稳定性和性能。</p>
<p style="color: #000000;" data-tool="mdnice编辑器"><strong style="color: #0e88eb;">并行式开发</strong>：在维持旧技术栈的同时，建立新的团队在新的技术栈上开发新的功能或模块。这可以避免影响现有的业务，并且可以并行推进新技术栈的实施。但是要注意要做好新旧技术栈的集成和切换计划，以及要确保有足够的资源来支持并行开发。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">在跨端架构的落地过程中，全方位的考虑和准备是关键，这包括<strong style="color: #0e88eb;">团队的认知，项目的方向，以及有效的沟通</strong>。每个参与者，无论是发起人、负责人还是核心成员，都需要明确自己在过程中的角色并发挥其特有的责任和职能。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">发起人提供方向和资源，负责人为项目负总责，制定详细的实施计划并监视进程，而核心成员则负责掌握新架构，实现功能需求并密切合作以解决问题。这是一个团队协作的过程，每个角色都扮演着关键的部分，以确保新架构的成功落地和最大化的效果。</p>
<h1 style="color: #000000;" data-tool="mdnice编辑器"><span style="font-weight: bold; color: #0e8aeb;">5 规范的系统化</span></h1>
<p style="color: #000000;" data-tool="mdnice编辑器">跨端是一个系统化的过程，规范在落地过程中逐步建立起来，整个规范系统化的过程包括协议管理，SDK 的生成和管理，文档统一，以及防劣化等等。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">协议是我们交互和通信的基础，我们设立了统一的接口定义标准，每个接口都需经过严格的审核流程，确保数据的一致性和接口的稳定性。同时，我们引入了版本控制机制，确保 API 的演进不会破坏现有系统的稳定性，同时也方便了新功能的迭代。</p>
<p style="color: #000000;" data-tool="mdnice编辑器"><strong style="color: #0e88eb;">SDK 的生成和管理</strong>是跨端架构中的关键环节。我们开发了一套自动化工具链，用于生成和管理 SDK，这不仅提高了开发效率，还确保了 SDK 的一致性和安全性。通过对 SDK 的严格版本控制和定期更新，我们能够及时修复已知问题，同时引入新的特性，以支持不断变化的业务需求。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">在<strong style="color: #0e88eb;">文档的统一</strong>方面，良好的文档是跨端协作的桥梁。我们建立了一套文档规范，确保所有开发者都能够轻松理解系统架构、API 使用和 SDK 集成。我们采用了 Markdown 格式来编写文档，并通过内部 Wiki 进行管理，这样不仅便于团队成员访问，也方便了新成员的快速上手。</p>
<p style="color: #000000;" data-tool="mdnice编辑器"><strong style="color: #0e88eb;">防劣化</strong>是跨端架构中容易被忽视的一个方面。我们通过组织、系统、知识库三个层面来做到防劣化，组织层面，有一个跨端架构小组，系统层面实施代码审查、自动化测试、全局代码检测和性能监控等措施来确保系统的质量和性能，知识库层面通过前面的文档统一、SDK 管理及脚手架构等。这些措施帮助我们及时发现并修复潜在的问题，避免了系统劣化对用户体验的影响。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">跨端不仅仅是技术层面的整合，更是对业务流程、用户体验和团队协作方式的一次革新。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">在跨端落地过程中，我们会遇到多种问题，团队的问题，人员的问题，技术栈选择的问题等等，这些问题都是在过程中不断思考、决策和调整，以确保我们的架构能够适应快速变化的环境，同时也能够支持团队的高效工作。</p>
<p style="color: #000000;" data-tool="mdnice编辑器">希望通过这些努力，我们的跨端架构能够为公司带来长期的竞争优势。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2024/03/5-thoughts-on-the-implementation-of-cross-end-architecture/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>
				<category><![CDATA[架构和远方]]></category>
		<category><![CDATA[Flutter]]></category>
		<category><![CDATA[React Native]]></category>
		<category><![CDATA[uni-app]]></category>
		<category><![CDATA[技术管理]]></category>
		<category><![CDATA[跨端]]></category>
		<category><![CDATA[跨端架构]]></category>

		<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>
