【uni-app&微信小程序&React Native】跨端原理初探

文章内容

  1. 以官方文档为基础,对uni-app的基础框架(逻辑层、渲染层)、组件、API进行简单地分析
  2. 以官方文档为基础,对微信小程序框架(逻辑层、视图层)、运行时进行简单地分析
  3. 以官方文档为基础,对React Native旧架构和新架构进行简单地分析

1. uni-app编译

  • 在web平台,将.vue文件编译为js代码。与普通的vue cli项目类似
  • 在微信小程序平台,编译器将.vue文件拆分生成wxml、wxss、js等代码
  • 在app平台,将.vue文件编译为js代码。进一步,如果涉及uts代码:

    • 在Android平台,将.uts文件编译为kotlin代码
    • 在iOS平台,将.uts文件编译为swift代码

编译器分vue2版和vue3版

  • vue2版:基于webpack实现
  • vue3版:基于Vite实现,性能更快

编译器支持条件编译,即可以指定某部分代码只编译到特定的终端平台。从而将公用和个性化融合在一个工程中。

2. uni-app运行时runtime

2.1 基础框架

  • 在web和小程序上,不需要uni-app提供js引擎和排版引擎,直接使用浏览器和小程序的即可。但app上需要uni-app提供
  • App的js引擎:App-Android上,uni-app的js引擎是v8,App-iOS是jscore
  • App的渲染引擎:同时提供了2套渲染引擎,.vue页面文件由webview渲染,原理与小程序相同;.nvue页面文件由原生渲染,原理与react native相同。开发者可以根据需要自主选择渲染引擎。

uni-app App 端内置了一个基于 weex 改进的原生渲染引擎,提供了原生渲染能力

  • 在 App 端,如果使用 vue 页面,则使用 webview 渲染
  • 如果使用 nvue 页面(native vue 的缩写),则使用原生渲染
  • 一个 App 中可以同时使用两种页面,比如首页使用 nvue,二级页使用 vue 页面,hello uni-app 示例就是如此

虽然 nvue 也可以多端编译,输出 H5 和小程序,但 nvue 的 css 写法受限,所以如果你不开发 App,那么不需要使用 nvue。

2.1.1 逻辑层和渲染层分离

在web平台,逻辑层(js)和渲染层(html、css),都运行在统一的webview里。
但在小程序和app端,逻辑层和渲染层被分离了。

分离的核心原因是性能。过去很多开发者吐槽基于webview的app性能不佳,很大原因是js运算和界面渲染抢资源导致的卡顿。


不管小程序还是app,逻辑层都独立为了单独的js引擎,渲染层仍然是webview

app上也支持纯原生渲染,使用.nvue文件

2.1.2 逻辑层详解

逻辑层是运行在一个独立的jscore里的,它不依赖于本机的webview,所以一方面它没有浏览器兼容问题,可以在Android4.4上跑es6代码,另一方面,它无法运行window、document、navigator、localstorage等浏览器专用的js API。

jscore就是一个标准js引擎,标准js是可以正常运行的,比如if、for、各种字符串、日期处理等。js和浏览器的区别要注意区分开来。

【uni-app&微信小程序&React Native】跨端原理初探_第1张图片

  • 所谓浏览器的js引擎,就是jscore或v8的基础上新增了一批浏览器专用API,比如dom;
  • node.js引擎,则是v8基础上补充一些电脑专用API,比如本地io;
  • 那么uni-app的App端和小程序端的js引擎,其实是在jscore上补充了一批手机端常用的JS API,比如扫码。

2.1.3 渲染层详解

h5和小程序平台,以及app-vue,视图层是webview,即.vue文件都会被渲染为WebView

app-nvue的视图层是基于weex改造的原生渲染视图,即.nvue文件会被改造为APP原生组件

兼容性

在iOS上,只能使用iOS提供的Webview(默认是WKWebview)。它有一定的浏览器兼容问题,iOS版本不同,它的表现有细微差异(一般可忽略)。

在Android上,小程序大多自带了一个几十M的chromium webview,而App端没办法带这么大体积的三方包,因此uni-app默认使用了Android system webview,这个系统webview跟随手机不同而有差异

在Android上,App端也支持使用腾讯X5引擎,这样就统一版本,尽可能减少兼容性问题

2.1.4 逻辑层和渲染层小结

逻辑层: js基本没有不同手机的兼容问题(因为js引擎自带了)

渲染层: 在app-vue上使用系统webview时会有手机浏览器的css兼容问题。此时或者不要用太新的css语法,或者集成腾讯x5引擎。

2.1.5 逻辑层和渲染层分离的利与弊

逻辑层和视图层分离,好处是js运算不卡渲染,最简单直接的感受就是:窗体动画稳。

如果开发者使用过App,应该有概念,webview新窗体一边做进入动画,一边自身渲染,很容易卡动画。而uni-app则无需写预载代码,新窗体渲染快且动画稳定。

但是两层分离也带来一个坏处,这两层互相通信,其实是有损耗的。

iOS还好,但Android低端机上,每次通信都要耗时几十毫秒。平时看不出来影响,但有几个场景表现明显:

  1. 连续高帧率绘制canvas动画,会发现还不如webview内部绘制流畅
  2. 视图层滚动、跟手操作,不停反馈给逻辑层,js再处理逻辑并通知视图层做对应更新。此时会发现交互不跟手或卡顿

不管小程序还是app,不管app-vue还是app-nvue,都有这个两层通信损耗的问题。

2.1.6 逻辑层和渲染层分离后进行的性能提升方法

在webview中,提供了一种运行于视图层的专属js,微信叫做wxs。uni-app支持把wxs编译到微信小程序、App和H5中,而且在wxs的基础上进行增强:

  • 微信里对wxs限制较多,只能实现有限的功能。
  • app端提供了更强大的renderjs,并兼容到H5平台,比如canvas动画,微信的canvas无法通过wxs操作,js不停绘制canvas动画因通信折损而无法流畅。uni-app的app-vue里的canvas对象设计在webview视图层的,通过renderjs可以在视图层直接操作canvas动画,将不再有通信折损,实现更流畅的效果

在原生渲染的视图层(app-nvue),逻辑层和视图层的折损一样存在。包括react native也有这个问题,weex提供了一套bindingx机制,可以在js里一次性传一个表达式给原生层,由原生层解析后根据指令操作原生的视图层,避免反复跨层通信。这个技术在uni-app里也可以使用。

bindingx作为一种表达式,它的功能不及js强大,但手势监听、动画还是可以实现的,比如uni ui的swiperAction组件在app-nvue下运行时会自动启用bindingx,以实现流畅跟手。

2.2 组件

为了降低开发者的学习成本,uni-app的内置基础组件命名规范与小程序基本相同。

runtime中包括的组件只有基础组件,如

你可能感兴趣的:(【uni-app&微信小程序&React Native】跨端原理初探)