大前端的感性认知

2,292 阅读12分钟

Hybrid就是Native、H5混合开发技术 Android有 webview 、iOS 有 UIWebview和 WKWebview

前置知识: app的分类:1.web-app;2.native-app;3.hybrid-app

1.web-app

本质上就是手机上的pc端,他所有的功能都是通过js开发,不涉及到本地功能(图片、扫码)等,全是在手机浏览器中展示。他严格意义上不能称为app,因为用户不需要安装app,只是在手机浏览器上展示的pc。缺点: 1.无法获取系统级别的通知,提醒,动效等等。
2.用户留存率低 设计受限制诸多 体验较差。

2.native-app

native-app就是我们通常说的原生app,分为Android开发和IOS开发。Android基于Java语言,底层调用Goolge提供的API,IOS基于Objective c或Swift,底层调用Apple官方提供的Api。他的优势在于,和手机系统的交互更好,可实现功能强大。 缺点:跨平台能力差;更新周期慢(具体表现在每次更新发布都需要等待审核,没有webview远端获取灵活,不用审核)

3.hybrid-app

hybrid就是目前主流的混合应用开发,就是将上述两者结合起来。或者说:将原生app中相对来说灵活变动的内容&UI对应的地方让出来,交给webview去加载html展示给用户。这样既保证了功能的强大性,有具有了相对的灵活性。缺点:虽然弥补了一定的灵活性,但是相比原生性能上有很大的损耗,因此不适用于交互性较强的App。

0.背景

hybrid混合开发是针对移动端开发的一种开发模式:历史的移动端开发是专门的安卓、ios开发,使用的开发功能都是在app安装包中构建好的,安装在移动端的,如果要更改功能或者UI的话,需要提示用户应用软件升级,这就显得非常的麻烦。如果可以将移动端中的功能更新也像pc端中的网页那样,需要向远端请求更新就行,而不用更新整个软件安装包,那就好了。但是有些全部改成纯网页又不能完全覆盖移动端工功能。因此两个各取其长,对于那些展示的或者可以替代本地功能的使用html & js开发,通过webview展示,其他的还是使用native开发。这种开发模式就是hybrid开发。
那么使用hybrid开发真的是没有任何缺点的嘛? 拥有了灵活性的同时,性能降低。这里的性能是针对谁的性能,对应的性能指标是什么?
概括性来讲:通常所说的webview的性能问题,就是针对从打开webview页面,到可以和用户交互的这段用户等待时间,作为衡量的指标,而这也是影响用户留存率的重要因素。
分析webivew性能,要想分析webview为什么慢?我们就得知道webview加载渲染的流程是什么,以及是在哪个流程慢,我们可以在哪几个流程优化。 不同于pc端浏览器,我们打开app加载页面这期间的用户等待时间,还要额外加上启动webview的时间,因为打开app的时候不会打开并初始化webview的,因此,在移动端中的首屏时间需要计入初始化webview的时间。 www.zhihu.com/question/45…

一、移动端开发的定义

通常我们指的移动端可以分为广义和狭义上的移动端,广义上的移动指的是移动设备上的软件应用都属于移动端,而狭义上的移动端按照技术方案可以分为以下三类:原生app开发、跨平台框架、WebView模式。

image.png

(1) 原生app开发:即常说的针对iOS/安卓的开发工程师,这种系统依赖性比较强,表现在同一个app需要开发两套代码分别适用于ios系统/安卓系统才行。

(2) 跨平台框架:跨平台框架就是为了解决两个系统两套代码的问题。因此facebook提出来一套应用app代码适用于两个系统,于是开发出了跨平台框架React-Native,在这个框架上开发前端应用可以适用于不同的系统(忽略了系统差异的影响)。
(3) WebView模式:就是在Native上开一个“浏览器”。主要是为了解决移动端每次发布新代码时候都需要进行发版&审核,整个发布周期较长。因此通过开一个WebView,不需要审核发版,直接通过浏览器远程加载新代码,让用户看到新页面/布局,极大了缩减了“更新周期”。

参考文章:www.infoq.cn/article/t3y…

二、为什么需要跨平台开发框架

跨平台开发一直是个老生常谈的问题,为了能够跨平台开发,推出来一系列跨平台开发框架:react-native、weex、flutter。那么我们为什么要致力于搞跨平台呢?首先不同的平台开发存在一些差异,如果不抹平这些差异,我们对每个平台一一对应开发,那么就不能实现代码的复用,极大的影响力开发效率和业务专注度。因此我们需要一套跨平台开发的框架。目前市场上的跨平台框架如下: image.png

  • react nativeweex均使用JavaScript作为编程语言,目前JavaScript在跨平台开发中,可谓占据半壁江山,大有“一统天下”的趋势。
  • kotlin-native开始支持 iOS 和 Web 开发,(kotlin已经成为android的一级语言)也想尝试“一统天下”。
  • flutter是Google跨平台移动UI框架,Dart作为谷歌的亲儿子,毫无疑问Dart成为flutter的编程语言,如下图,作为巨头新生儿,在flutter官网也可以看出,flutter同样“心怀天下”。

2.1 React Native

Facebook团队基于react框架的设计模式开发出跨端框架RN,这样就可以实现只学习一套react开发规则,既可以在pc端通过react框架开发,也可以在通过react-native在移动端开发(开发者的学习成本就是react即可)。但是同样是react,但是在pc和移动端还是有区别的:
1.pc端是通过浏览器实现UI渲染,请求发送,移动端则是js运行的原生端提供的UI渲染、请求发送功能。(这些宫功能都不是react能提供的)
2.react native功能比pc端多,比如可以通过rn来调用原生端控件,例如拍照控件、导航控件等。 总结:RN的底层原理就是通过 js 使用「中间层」调用原生端的各种「功能控件」。

那么,我们都知道,js的运行需要一定的运行容器,例如在浏览器中js是运行在浏览器提供的js引擎中,那么在移动端如果存在web-view的话也可以运行js代码,那如果原生中不采用H5开发(不提供webview容器),那么纯原生开发react-native是在哪里运行js代码的呢?-- JavaScriptCore(在IOS上直接使用内置的javascriptcore, 在Android 则使用webkit.org官方开源的jsc.so)。

2.1.1 JS层、C++中介层、原生层

image.png 从上图可以看出,使用RN对原生APP开发的结构有三层,其中javasrcipt-native、c++、java,其中前端需要关注的是javasrcipt-native和c++。最上层:纯js业务开发(不涉及原生功能调用),中间层:当我们需要使用手机原生功能的时候,我们就需要使用中间映射中介层,来调用第三层的原生功能。

可以看出,跨平台的关键在于C++层,开发人员大部分时候,只专注于JS 端的代码实现。 在原生端提供的各种 Native Module 模块(如网络请求,ViewGroup控件),和 JS 端提供的各种 JS Module(如JS EventEmiter模块),都会在C++实现的so中保存起来,双方的通讯通过C++中的保存的映射,最终实现两端的交互。

2.2 WEEX

weex与react native类似,react native是基于react设计模式开发的跨端框架,而 weex 是基于vue的设计模式(阿里巴巴),来实现web、ios、安卓三端的无差别代码运行。

在 weex 中,主要包括三大部分:JS BridgeRenderDom, 分别对应WXBridgeManager、WXRenderManager、WXDomManager,三部分通过WXSDKManager统一管理。其中 JS BridgeDom 都运行在独立的 HandlerThread 中,而 Render 运行在 UI 线程。JS Bridge 主要用来和 JS 端实现进行双向通信,比如把 JS 端的 dom 结构传递给 Dom 线程。Dom 主要是用于负责 dom 的解析、映射、添加等等的操作,最后通知UI线程更新。而 Render 负责在UI线程中对 dom 实现渲染。

weex 中文件默认为 .vue ,而 vue 文件是被无法直接运行的,所以 vue 会被编译成 .js 格式的文件,Weex SDK会负责加载渲染这个js文件。Weex可以做到跨三端的原理在于:在开发过程中,代码模式、编译过程、模板组件、数据绑定、生命周期等上层语法是一致的。不同的是在 JS Framework 层的最后,web 平台和 Native 平台,对 Virtual DOM 执行的解析方法是有区别的。

2.3 Flutter

Google 出品,Dart语言,Flutter Engine引擎,响应式设计模式,原生渲染

2.4 框架对比

image.png

参考文章:juejin.cn/post/684490…

三、 H5 和 小程序架构设计

移动端开发实现方案主要有如下两种
1.原生开发方案(典型代表:React-Native);
2.webView开发模式也是常见的使用方案(典型代表:小程序 / H5)

3.1 Native 和 WebView的区别

RN 是通过 Native 渲染的,而 H5和小程序则是通过 WebView 渲染,两者渲染容器是不同的。

WebView渲染

1.本质上移动端(Native)的一个功能组件。可以认为把浏览器那一套变成一个功能组件搬到了移动端。
2.开关 && 大小控制。Native需要对WebView进行新建&初始化。此外,WebView 渲染视图窗口可以由 Native 来控制,所以 Native 可以利用设置 WebView 宽高来实现局部动态化,也可以让 WebView 布满全屏来实现 H5 页面。
3.WebView加载URL。webview加载的链接可以是线上资源,这种就和pc端浏览器一样。也可以是本地的js、HTML资源,这个时候没有网络的通信加载更快,通常来说小程序会预先加载资源,或者加载之后有缓存。因此小程序总体用户体验比H5更好。

Native渲染

Native 渲染就比较简单了,在 iOS 和 Android 系统上分别用 Native 模式渲染。而我们今天要讲的 RN ,也是用 Native 渲染的,Native 渲染的用户体验会更好,还能直接调用系统接口。

注意点1:关于JSBridge和C++层的认知
JSBridge是实现WebView和Native通信的中介,进而实现通过调用Native来调用原生功能API。那么Native开发中Js是如何调用原生功能API呢?通过C++层作为中介。

注意点2: Native和React Native的区别

Native 开发代码要打包在客户端包中,用户下载的时候是连着开发的资源包一起下载的,下载的资源很多。且区分ios和安卓,对应两套开发代码。

React Native 是采用运行 React 的 JS 作为开发平台,这样可以让 Web 开发者也能够参与到 Native 开发中来。而且,RN 让一套代码可以运行在两端,大大减少了开发和维护成本。
最重要的就是 RN 是动态化的方案,也就是 RN 打出来的应用包,并不是和 Native 包绑定在一起发布的,而是在运行 Native 的时候拉下 RN 的包。这样做,一是减少了 Native 包体积,二是 RN 包可以随时发布,提高了迭代效率,也让一些线上问题能够快速解决。

3.2 H5 和 小程序的区别

这里我们暂时先不讨论原生开发的react-native,我们重点看一下另一种 「webview 开发模式」,这种开发模式的落地方案主要有两种:小程序 和 嵌入H5的混合 App。

虽然都是基于 WebView 开发模式,但是两者在渲染流程和通信流程上是有一定区别的。

区别运行容器初始化渲染流程通信流程
H5WebView需要借助 Native 先打开WebViewH5渲染流程同pc端浏览器渲染流程同浏览器相同,存在对应的DOM事件,然后vue/react数据驱动响应事件,更新UI视图
小程序WebView需要借助 Native 先打开WebView小程序采用双线程架构,分为逻辑层渲染层触发的事件流程:首先需要传递给 Native,再传递给逻辑层,逻辑层处理事件,再把处理好的数据传递给 Native,最后 Native 传递给渲染层,由渲染层负责渲染。

补充区别

pc和小程序的区别浏览器小程序
DOM和BOM API提供方面浏览器提供了JS调用渲染节点的接口:DOM和BOM为了数据安全将渲染线程和逻辑层分开,没有提供逻辑层调用渲染层的接口,故没有DOM-API
渲染和逻辑线程互斥方面普通网页开发渲染线程和脚本线程是互斥的,这也是为什么长时间的脚本运行可能会导致页面失去响应,而在小程序中,二者是分开的,分别运行在不同的线程中。
项目开发&调试方面- 网页开发者在开发网页的时候,只需要使用到浏览器,并且搭配上一些辅助工具或者编辑器即可。小程序的开发则有所不同,需要经过申请小程序帐号、安装小程序开发者工具、配置项目等等过程方可完成。

3.2.1 小程序的运行环境:

image.png

参考文章: juejin.cn/book/719872…
小程序运行环境: xie.infoq.cn/article/4cb…
webview加载过程
juejin.cn/post/703877…
bbs.huaweicloud.com/blogs/33139…