一个Android原生开发对于跨平台和大前端的一些探索

前言

从 2017 年开始,GMTC“移动技术大会”就更名为“大前端技术大会”。从现在看来,前端开发和 Native 开发并没有谁取代谁,而是正在融合,融合之后的产物就是所谓的“大前端”。为了顺应这种趋势,很多大公司的组织架构也做了相应的调整,把前端团队和 iOS、Android 一起合并为大前端团队。

1.web

基于 WebView 的 H5 跨平台方案,优点确实非常明显,甚至之前还有H5App的概念,但是但是性能是它目前最大的问题,主要表现在以下两个方面:

  • 启动白屏时间。WebView 是一个非常重量级的控件,无论是 WebView 的初始化,还是整个渲染流程都非常耗时。这导致界面启动的时候会出现一段白屏时间,体验非常糟糕。
  • 响应流畅度。由于单线程、历史包袱等原因,页面的渲染和 JavaScript 的执行效率都不如原生。在一些重交互或者动画复杂的场景,H5 的性能还无法满足诉求。

所以在移动端 H5 主要应用在一些交互不太复杂的场景,一般来说即使帧率不如原生,但也基本符合要求。从用户角度来看,H5 当前最大的问题在于启动的白屏时间。
一个 Web 页面是由 HTML + CSS + JavaScript 组成,通过浏览器内核执行并渲染成开发者预期的界面。浏览器内核主要包括两大块功能,它们分别是:

  • 浏览器引擎。浏览器引擎负责处理 HTML 和 CSS,遵照的是 W3C 标准。
  • JavaScript引擎。JS 引擎负责处理 JS,遵照的是 ECMAScript 标准。

它们两者互相独立但又有非常紧密的结合,而且在不同浏览器内核中的实现也是不太一样的。但随着微软的 Edge 宣布将内核切换成 Chromium,目前这个战场主要就剩下苹果和 Google 两个玩家。
虽然Chromium是开源的,但是因为它的复杂性,国内对它有深入研究的人非常少,而拥有定制修改能力的人更是少之又少。因此这块需要投入大量的人力物力,国内比较有名的是 UC 浏览器的 U4 内核以及腾讯浏览器的 X5 内核。
浏览器内核渲染的流程,其实可以把整个过程拆成三个部分:

  • Native 时间。主要是 Activity、WebView 创建以及 WebView 初始化的时间。虽然首次创建 WebView 的时间会长一些,但总体 Native 时间是可控的。
  • 网络时间。这里包括 DNS、TCP、SSL 的建连时间和下载主文档的时间。当解析主文档的时候,也需要同步去下载主文档依赖的 CSS 和 JS 资源,以及必要的数据。
  • 渲染时间。浏览器内核构建 Render Tree、Layout 并渲染到屏幕的时间。

对于 Android 界面启动的过程,我们在窗口动画还没结束的时候,大部分时候就已经完成了页面的渲染。启动一个 Activity 界面,我们一般要求在 300 毫秒以内。而上述三个部分相加的时间完成后用户才能看到完整的页面。
即使花费大量的时间去优化掉这个白屏等待时长,但是JS交互的流畅度也不尽人意。

2.React Native 和 Weex

Facebook 在 2015 年开源了React Native,它抛弃了 WebView,利用 JavaScriptCore 来做桥接,将 JavaScript 调用转为 Native 调用。也就是说,React Native 最终会生成对应的自定义原生控件,走的是系统原生的渲染流程。

而阿里在 2016 年也开源了Weex,它的思路跟 React Native 很像,但是上层 DSL 使用的是 Vue

但是没有十全十美的方案,React Native/Weex 方案为了能达到接近原生开发的性能和交互体验,必然要在跨平台和动态性上面做出了牺牲。

React Native 和 Weex 向上对接了前端生态,向下对接了原生渲染,看起来是非常完美的方案。但是前端和客户端,客户端中的 Android 和 iOS,它们的差异并不那么容易抹平,强行融合就会遇到各种各样的坑。
为了解决这个问题,React Native 的使用者需要引入一层非常重的中间层(此处重点),期望在这个中间层中帮助我们去抹平这些差异。例如京东的JDReact、携程的Ctrip React Native。

既然 React Native 和 Weex 在跨平台上面做了牺牲,那它的性能和交互是不是能直接对齐 Native 开发呢?非常遗憾, 目前它们的性能主要还有两个瓶颈。

  • JS 的执行时间。React Native 和 Weex 使用的JavaScriptCore引擎,虽然它每年都在进步,但是 JS 是解释性的动态语言,它的执行效率相比 AOT 编译后的 Java,性能依然会在几倍以上的差距。
  • 跨语言的通信成本。既然要对接前端和原生两个生态,就无法避免 JS -> C++ -> Java/Objective-C 之间频繁的通信和转换,所以这里面会涉及各种序列化,对性能的影响比较大。

虽然相比 H5 方案在性能方面有了很大的提升,但是 React Native 和 Weex 也要面对启动时间慢、帧率不如原生的性能问题。它属于一种比较中庸的方案,当然也会有自己的应用场景。例如一些二级页面(例如淘宝的分会场),它们的业务也比较重要,但是交互不会特别复杂,同时希望保持一定的动态化能力。

当然,Facebook 已经意识到 React Native 的种种性能问题,目前正在疯狂重构中,希望让 React Native 更加轻量化、更适应混合开发,接近甚至达到原生的体验。但是,开发者好像已经放弃了对他的耐心,转向新的解决方案flutter。

3.flutter

性能、跨平台、动态性这个“铁三角”中,我们不能同时将三个都做到最优。如果 Flutter 在性能、跨平台和动态性都比浏览器更好,那就不会出现 Flutter 这个框架了,而是成为 Chromium 的一个跨时代版本。浏览器选择的是跨平台和动态性,而 Flutter 选择的就是性能和跨平台。是一个性能和效率至上,但是动态化能力非常有限的框架。

flutter无疑是当下跨平台非常热门的一种方案,但是对于非常看重动态性的用户比如我们来说,是不会去选择的。

4.小程序

2017 年初,张小龙宣布微信小程序诞生。如今小程序已经走过了四年,在这四年间,小程序的生态也在健康的发展。

每一个应用都有成为超级 App 的梦想,各个大厂纷纷推出自己的小程序框架:微信、厂商、支付宝、今日头条、百度、淘宝、Google Play,小程序这个战场已然是“七国大乱战”。

其实小程序一开始并不属于一种跨平台开发方案,大家更看重的是它的渠道优势。

但是随着诸如uniapp,mpaas等平台相继推出,将原生app变成像支付宝那样的小程序平台已经变成很简单的事情!(而且现在mpass还有专门的技术问题解答钉钉群,真的有专家大佬替你解决问题那种,免费的!)

这也是我们最后选定的方案,小程序相对来说上手比较简单,性能可通过更换内核进行提升,而且稍微修改就可以移植到其他平台进行发布。

后记

此处为垃圾话,并无卵用。只是发泄下。

在2020年受到众所周知的原因影响下,楼主换了个坑,当时正好是20年3月中旬,上家公司在收割完最后一个需求后及其BYL的向5某8某同城公司(真的对这公司及其产品一生黑)学习了停工停薪待岗的呵呵行为,祸不单行,相恋N年的异地也因为底线问题结束了。
那段时间,整个人感觉跌倒了谷底,每天就喝酒 躺着 发呆 出去买酒 失眠 继续喝酒,差不多过了一周,扔了很多东西,开始准备和投简历,那段时间不是很好找,很多公司死了,很多公司在努力撑着,不过还好,4月中旬入职了一家比较满意的公司,每天上班下班恍惚间已经21年了,博客也好久没写了,现在疫情又严重了起来,希望明天能更好吧!

你可能感兴趣的:(一个Android原生开发对于跨平台和大前端的一些探索)