关于react-native:????深入解析跨端框架的核心技术到底是什么

本文是我在学习多个平台 UI 框架后的一些感触,受精力和技术水平所限,文中定有不足之处,请各位大佬多多指教

如果你感觉我的文章对你有帮忙,在珍藏的过程中,肯定要记得点赞点在看哦,谢谢你,这对我真的很重要????!

一、前端三板斧

正式探讨「跨端开发」这个概念前,咱们能够先思考一个问题:对大部分前端工作来说,前端次要干些啥?

我集体认为,无论环境怎么变,前端基本上就是做三件事件:

  • fetch data(数据获取)
  • manage state(状态治理)
  • render page(页面渲染)

没了。

兴许有人感觉我说的太全面,其实咱们能够理一理。往近了说,当初常识付费搞的热火朝天,动不动就搞个「XXX 源码解析」,剖析一下这些课程的主题和目录,你就会发现根本都是围绕着这三个方向开展讲的;往远了说,咱们能够剖析一下 Web 前端的倒退历程:

  • 1995 年左右,用 HTTP/1.0 拉取数据,用第一版的 JavaScript 治理几个前端状态,用袒露的 HTML 标签展现页面
  • 2005 年左右,用 HTTP/1.1 和 AJAX 拉取数据,用 JavaScript 做做表单画画特效,用 CSS 丑化页面
  • 2010 年左右,用 HTTP/1.1 和 AJAX 拉取数据,用 jQuery 操作 DOM 解决前端逻辑,用 CSS 丑化页面
  • 2015 年左右,随着 HTML5 规范的推广和浏览器性能的晋升,前端开始进入「学不动了」的时代:

    • 在 fetch data 层面,除了 HTTP/1.1 和 AJAX,HTTPS 来了,HTTP/2 来了,WebSocket 也来了
    • 在 manage state 层面,Angular、React 和 Vue 先后呈现,从当初看,React 的状态驱动视图的理念间接影响了 Flutter 和 SwiftUI 的设计
    • 在 render page 层面,除了传统的 HTML + CSS,还退出了 CSS3、Canvas 等概念,音视频性能也失去增强
  • 最近几年,网络协议趋于稳定,几年内也不会有啥大的变动;国内 React 和 Vue 的位置根本巩固,一堆前端盯着 GitHub 进度条等版本更新;render 层出了不少幺蛾子,好不容易解脱了 IE6,又来了各种小程序,同一套业务逻辑写好几遍不经济也不事实,这时候各种跨端计划就整进去了

通过一番剖析,这个三板斧实践看上去曾经有些情理了,咱们顺着这个方向再向底层思考:这三大性能是怎么实现的?

  • fetch data 方向,最初要靠网络协议栈把数据收回去,然而让一个前端间接搞套接字编程是十分不事实的,所以咱们须要把网络操作封装为库,让应用层调用
  • render page 方向,最初是把相干图元信息通过各种图形 API(OpenGL/Metal/Vulkan/DirectX)发给 GPU 进行渲染,很多前端的图形学途程最终都止于一个三角形,用这套技术栈去画 UI 也极其不事实,更不要说排版系统这种工程量盛大的工作,所以这些活儿都让相干的渲染引擎做了
  • manage state 方向,你能够用全局变量治理状态,最初的终局肯定被共事打爆,当初支流计划都是采纳各种框架和 runtime 进行状态治理,而这个 runtime 的宿主环境,往往就是某个语言的虚拟机,同时,fetch data 的终点,也是同一个虚拟机

通过下面的剖析咱们能够看出,前端的次要技术外围就两个:虚拟机渲染引擎,这也意味着,如果咱们想要搞跨端开发,就必须得对立虚拟机和渲染引擎

二、虚拟机和渲染引擎

1.网页:JS Engine + WebKit

因为谷歌的 Blink 引擎 fork 自苹果的 WebKit,后文为了形容不便,对立用 WebKit 代替浏览器渲染引擎

网页是老本最低上手最快的跨端计划了。得益于互联网开放式理念,网页天生就是跨端的,无论什么渲染框架,WebView 都是必不可少的外围组件。

开发人员的接入老本也极低,次要技术就是 Web 开发那一套,前端次要头疼的是各个渲染引擎的适配问题性能问题

当初支流的 JS Engine 是苹果的 JavaScriptCore 和谷歌的 V8,支流的渲染引擎是苹果的 Webkit 和谷歌的 Blink。尽管 W3C 的标准就摆在那里,各个浏览器厂商再依据标准实现浏览器,这也是网页跨端的根底。问题在于浏览器内核实现总有轻微差距,局部实现不合标准,局部实现自身就有 Bug,这也是前端解脱不了适配需要的实质起因。

另一个是性能问题。其实 WebKit 自身的渲染速度还是很快的,然而受限于一些浏览器个性,比如说极其简单极其动静的 CSS 属性,DOM 树和 CSSOM 的合并,主线程必须挂起期待 JS 的执行,这些都会大大降低性能,前端搞性能优化,个别得根据这些浏览器个性进行减枝解决,然而再怎么优化,在页面性能和交互体验上,和 Native 还是有很大的间隔。

2.网页 PLUS:JS Engine + WebKit + Native 能力

间接拿个 URL 扔到 WebView 里是最简略的,其实这样也能解决大部分问题,毕竟前端 90% 的工作都是画 UI 写业务逻辑,然而还有 10% 的性能做不到,比如说要和 Native 同步状态,调用一些零碎性能。

要实现客户端和网页双向通信的话,个别都是借助 JSBridge 进行通信,《JSBridge 的原理》这篇文章总结的不错,感兴趣的同学能够看一下。

JSBridge 只是解决了 Native 和 Web 的相互调用问题,如果我想借助 Native 增强 Web 怎么办?这时候就有了一些摸索:

  • 预热:提前创立和初始化 WebView,甚至实现 WebView 容器池,缩小 WebView 的启动工夫
  • 缓存:把罕用的 Web 资源事后存在 Native 本地,而后拦挡浏览器网络申请重定向到本地,这样就能够放慢 Web 的资源加载速度(也叫“离线包”计划);
  • 劫持:比如说 Web 对网络加载的控制力比拟弱,局部有能力的厂商会把所有的网络申请都劫持下来交给 Native 去做,这样做能够更灵便的治理 Web 申请
  • 替换:替换个别指替换 Web 的 Img 标签和 Video 标签,这个最常见的中央就是各大新闻类客户端。因为新闻的动态性和实时性,新闻都是由各个编辑/自媒体通过后盾编辑下发的,这时候要利用 Web 弱小的排版性能去显示文本内容;然而为了加载速度和观看体验,图片和视频都是 Native 组件替换的

通过下面几步,网页的速度根本能够达到秒开的级别,这外面最典型的就是几大新闻客户端,大家能够上手体验一下。

3.小程序:JS Engine + WebKit

小程序,国内的特色架构,实质上是微信成为流量黑洞后,想成为流量散发市场治理和散发本人的流量,所以这是个商业滋味很重的框架。

小程序在技术上没什么特地的翻新点,实质上就是阉割版的网页,所以微信小程序进去后各个流量寡头都推出了本人的小程序,正如有人吐槽的,小程序的实现形式有 9 种,底层实现多样化,各个厂实现还没有对立的规范,最初就是给开发者喂屎,我也没啥好介绍的,就这样吧。

4.React Native:JS Engine + Native RenderPipeLine

React 2013 年公布,两年后 React Native 就公布了,前几种跨段计划根本都是基于浏览器技术的,RN 这个跨段计划的创新性在于它保留了 JS Engine,在渲染引擎这条路上,他没有本人造轮子,而是复用了现有的 Native 渲染管线。

这样做的益处在于,保留 JS Engine,能够最大水平的复用 Web 生态,毕竟 GitHub 上轮子最多的语言就是 JavaScript 了;复用 Native RenderPipeLine,益处在于脱离 WebKit 的历史包袱,相对来说渲染管线更短,性能自然而然就下来了。

那么问题来了,RN 是如何做到跨端的?这个其实全副凭仗于 React 的 vdom。

vdom

前端社区上有些文章探讨 vdom,总会从性能和开发便捷性上切入解说,从纯 Web 前端的角度看,这些确实是 vdom 的特点,然而这不是 vdom 真正火起来的起因。vdom 更大的价值在于,人们从 vdom 身上看到跨端开发的心愿,所以在 React 呈现后 React Native 紧跟着呈现是一件十分天然的事件。为什么这么说?这个就要先溯源一下 UI 开发的范式。

UI 开发次要有两大范式:Immediate Mode GUI(立刻模式))Retained Mode GUI(保留模式)

简略来说,IMGUI 每帧都是全量刷新,次要用在实时性很高的畛域(游戏 CAD 等);RMGUI 是最宽泛的 UI 范式,每个组件都被封装到一个对象里,便于状态治理和简单的嵌套布局。无论是网页、iOS、Android 还是 Qt 等桌面开发畛域,都是基于 RMGUI 的。这两者的具体细节差别,能够看这篇知乎答复和这个 Youtube 视频。

咱们再回到 React Native 中,既然 iOS Android 的原生渲染管线都是 RMGUI 范式,那么总是有类似点的,比如说 UI 都是树状嵌套布局,都有事件回调等等。这时候 vdom 的作用就进去了:

vdom 作为一个纯对象,能够清晰的提炼出出布局的嵌套构造,而且这个形象形容是平台无关的,那么咱们就能够利用 JS 生成 vdom,而后将 vdom 映射到 Native 的布局构造上,最终让 Native 渲染视图,以达到跨平台开发的目标。

到这里如果你有些编译原理的常识,你就会发现 vdom 和 IR 有些相似,同样都是形象于平台的两头态,vdom 上接 React 下接 Native RenderPipeLine,IR 上接编译器前端下接编译器后端,咱们只有关怀前半段的逻辑解决,脏活累活都让后半局部做。

Hermes

2019 年 Facebook 为了优化 React Native 的性能,间接推出了新的 JS Engine——Hermes,FB 官网博文介绍了很多的长处,我集体认为最大的亮点是退出 AOT,传统的 JS 加工加载流程是这样的:

Babel 语法转换Minify 代码压缩install 下载代码Parse 转为 ASTCompile 编译Execute 执行

Hermes 退出 AOT 后,BabelMinifyParseCompile 这些流程全副都在开发者电脑上实现,间接下发字节码让 Hermes 运行就行。

这样做的益处在于,能够大大缩短 JS 的编译工夫,不信的话大家能够用 Chrome 剖析几个大型网站,JS 的解析加载工夫根本占时都是 50% 以上,局部重型网站可能占时 90%,这对桌面利用来说还好,对于电量和 CPU 都要弱上一线的挪动平台来说,这些都是妥妥的性能杀手,Hermes 的退出能够大大改善这一状况。

目前 React Native 0.64 也反对 Hermes 了,如果有做 RN 业务的同学能够玩一玩,看看在 iOS 上的性能晋升有多大。

5.Flutter: Dart VM + Flutter RnderPipeLine

Flutter 是最近比拟火的一个跨端计划,也有不少人认为这是最终的跨端计划,毕竟桌面软件时代,最终胜出跨端计划就是 Qt,他们的独特特点就是自带了一套渲染引擎,能够抹平终端差别。

Flutter 的发明还是很有意思的,这里有个 Eric 的访谈,视频中说 Eric 差不多有十几年的 Web 渲染畛域工作教训,有一次在 Chrome 外部他们做了个试验,把一些乌七八糟的 Web 标准去掉后,一些基准测试甚至能快 20 倍,因而 Google 外部开始立项,Flutter 的呈现了。至于 Flutter 抉择 Dart 的理由,坊间始终传说 Flutter 开发组隔壁就是 Dart 开发组,离得近就好 PY 交易,反正 Dart 也没人用,没啥历史包袱,能够很好的相应 Flutter 的需要。

Flutter 的架构也是比拟清晰的:

  • 虚拟机用的 Dart VM,Dart 同时反对 JIT 和 AOT,能够同时保障开发效率和运行效率
  • 渲染引擎先把 Dart 构建的视图数据传递给 Skia,而后 Skia 加工数据交给 OpenGL/Metal 这两个图形 API,最终交给 GPU 渲染,整体上比 WebKit 的渲染流水线清晰不少

从纯正水平上看,Flutter 是做的最彻底的,虚拟机和渲染引擎都没有用业内的成熟计划,而是自造了一套,益处就是没啥适配压力,害处就是太新了,业务开发时往往会遇到无轮子可用的难堪状态,如果谷歌大力推广,国内大厂继续跟进,前景还是很光明的。

6.其它方向的摸索:JS Engine + Flutter RnderPipeLine?

社区里有一种声音,认为 Flutter 最大的败笔就是不能用 JavaScript 开发。这时候就会有人想,如果咱们把 Web 技术和 Flutter 技术联合起来,用 JS Engine 对接世界上最大最沉闷的 JS 社区,用 Flutter 渲染引擎对接高性能渲染体验,国安民乐,岂不美哉?

目前来说一些大厂还是做了一些摸索,我看了一些剖析和我的项目架构,感觉就是做了个低配版的 React Native,React Native 的现有架构有一个性能瓶颈就是跨语言调用老本比拟高,而这些大厂的调用链路多达 4 步:JS -> C++ -> Dart -> C++,更加丧心病狂,目前看无论是上手和推广都是没有间接用 RN or Flutter 不便。

三、各跨端计划的不足之处

跨端计划不可能只有益处的,各个计划的害处也是很显著的,我上面简略列一下:

  • 网页:性能是个过来不的坎儿,而且 Apple 明确指出不欢送 WebView 套壳 APP,有拒审危险
  • 网页 PLUS:技术投入很高,根本只能大厂玩转
  • 小程序:对开发者不敌对,技术半衰期极短
  • React Native:根本只能画 UI,一旦做深了,只会 JS 基本解决不了问题,Java OC 都得学,对开发者要求比拟高
  • Flutter:Android 反对很好,但 iOS 平台的交互割裂感还是很强的,而且和 RN 问题一样,一旦做深了,必须学习客户端开发常识,对开发者要求比拟高

总的来说,在就义肯定用户体验的前提下,跨端计划能够进步开发者的开发效率和公司的运行效率,我集体认为,只有某个计划的 ROI 比拟高,其实是还是能够投入到生产的。

四、总结

本文到此就完结了,我把各个跨端技术提炼为为虚拟机和渲染引擎技术,而后以这两个核心技术的角度去拆解各个跨端计划。一旦概念理清,在面对性能调优等技术场景时,就能抓住主要矛盾,更快更好的发现问题,解决问题。


如果你感觉我的文章对你有帮忙,在珍藏的过程中,肯定要记得点赞点在看哦,谢谢你,这对我真的很重要????!

最初举荐一波我的微信公众号:卤蛋实验室和我的集体博客:supercodepower.com, 目前专一前端技术,对图形学也有一些渺小钻研,欢送大家来撩~

五、举荐浏览

【答疑解惑】为什么你的 Charles 会抓包失败?

webpack 中那些最易混同的 5 个知识点

【全网最全】React Native 性能优化指南

【独家】React Native 版本升级指南

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理