一、前言
对于经常使用APP且技术性敏感的用户,在操作APP过程中,对于一个页面是native App
还是hybird App
实现,往往一眼就能识别出来谁是网页质感,谁是原生质感,
在实际想法开发过程中,项目组在制定产品研发策略时,考虑到开发成本(时间、金钱)和上手难度,Hybrid App
成为技术框架首选。因为 Hybrid App
只需要编写一套代码,便可以同步生成 Android
和 IOS
两个平台的APP,甚至能够部分兼容微信公众号和小程序。这样节省的不仅仅是写代码的时间,更重要的是节省了多个技术团队之间跨知识结构协同的问题,同时也节省了APP与服务器端调试的时间成本。
一般,我们对Hybrid App
的定义是:
Hybrid App
(混合模式移动应用)是指介于web-app
、native-app
这两者之间的app,兼具“Native App
良好用户交互体验的优势”和“Web App跨平台开发的优势”。
简单来说, Hybrid App
就是套壳 App,整个 App 还是原生的,也需要下载安装到手机,但是 App 里面打开的页面既可以是 Web 的,又可以是原生的。H5 页面会跑在 Native 的一个叫做 WebView
的容器里面,只要有 WebView,一套代码可以很容易跨iOS、安卓、Web、小程序、快应用多个平台。可以简单理解为在 App 里面打开了一个 Chrome 浏览器,在这个浏览器里面打开一个 Tab 去加载线上或者本地的 H5 页面,这样还可以实现打开多 WebView
来加载多个页面。
以上只是描述了Hybrid App
开发的优势所在,会误导很多初级开发者想当然的认为 Hybrid App
必定优于 Native App
,从而忽略或轻视了 Hybrid App
开发过程中存在的痛点及潜在问题。
受制于 Web 性能,Hybrid App
具有加载速度比较慢、页面渲染问题,包括页面渲染性能差、页面卡顿、白屏等问题层出不穷。
如何打造一款优秀的Hybrid App
,使其体验上更像客户端,运行更高效是一个值得探索的课题。
二、Hybrid App 技术选型
Native app
开发技术一般比较固定,大厂背景下,很难出现百家争鸣百花齐花的现象。原生开发技术实现如下:
-
IOS
:基于XCode开发工具,使用Swift
或者OC
开发语言,来进行原生态的IOS应用的开发。 -
Android
:基于Eclipse或者Android Studio开发工具,使用Java
或者Kotlin
开发语言,来进行原生态的Android
应用的开发。
Hybrid App
采用H5技术实现,技术选型就比较广泛了。目前主流的移动端跨平台技术方案大体可以分为三类,
- 使用原生内置浏览器加载
HTML5
的Hybrid技术方案,采用此种方案的主要有Cordova
、Ionic
和微信小程序; - 使用
JavaScript
语言进行开发,然后使用原生组件进行渲染,采用此方案的主要有React Native
、Weex
和轻快应用; - 使用自带的渲染引擎和自带的原生组件来实现跨平台,采用此种方案的主要是
Flutter
。
对于其他的跨平台开发方案,基本可以抛弃了,相比较React Native
和 Flutter
,React Native
和Flutter
在应用开发上,效率差不多。
Tips⚠️:
-
React Native
: 由Facebook
于2015年发布的开源、跨平台的应用开发框架。其基于React.JS
实现,利用JavaScript
为Android
和iOS
用户提供真正原生的应用外观和体验。另外,该框架还支持开发者使用Java
、Objective-C
或SWIFT
编写部分原生模块来处理复杂操作,如视频播放或图像编辑。 -
Flutter
: 由Google
于2018年开源的构建用户界面(UI)工具包,其基于Dart编译器和Flutter拥有基于DART
编写的“UI-as-a-code
”小部件,它的性能比任何其他跨平台移动开发框架都要好,能更快、更直接地与平台直接通信,而不需要JavaScript
桥(Reaction Native
就是通过JavaScript
桥进行通信)。此外,Flutter
不依赖于某一组原生组件,而是利用可视化、结构化、平台性和交互式小部件进行UI设计,所有这些实现都由框架图形引擎负责完成。
除此之外,国产跨平台开发框架uni-app
近几年也逐渐在支持国产的潮流中异军突起,uni-app
支持 webview渲染
和 weex原生渲染
这2种引擎渲染方式。
-
webview渲染方式:架构和微信小程序一样。
-
原生渲染方式:DCloud 基于 weex引擎进行了改造,在原生渲染引擎上实现了
uni-app
的组件和API。
uni-app
作为国产跨平台开发框架,只能说是站在巨人的肩膀上成就了自己,要说其没有创新性也不完全正确,说其是剽窃,也谈不上。鲁迅先生曾经说过:“读书人偷书不算偷” 。
三、uni-app 如何打造优秀的跨平台APP
考虑到目前项目组应用 uni-app
作为跨平台开发框架,故本节讨论应用 uni-app
如何打造一款优秀的跨平台APP。
下面主要从页面渲染,问题排查等方面介绍APP开发、纠错经验。
3.1 页面渲染
如何让uni-app 开发的 hybrid App
看起来更像原生APP?这是在开发Hybrid App
时不得不面对的一个犀利问题。
首先,要清楚H5页面在APP端渲染的方式,相比原生少了很多页面渲染效果。
-
提升H5加载速度 APP运行过程中,字体文件过大导致APP端通过
webview
方式引用H5内容会出现加载慢的用户体验问题。针对此问题,需要对字体文件进行筛选、压缩处理,同时开启服务器端gzip压缩。
-
使用自定义组件模式 使用自定义组件模式,在
manifest.json
配置文件中配置自定义组件模式(HBuilderX1.9起新建项目默认即为自定义组件模式)。在复杂页面中,页面中嵌套大量组件,如果是非自定义组件模式,更新一个组件会导致整个页面数据更新。而自定义组件模式则可以单独更新一个组件的数据。
在App端,除了上述好处,自定义组件模式还新增了一个独立的js引擎,加快启动速度、减少js阻塞。
-
避免使用大图 页面中若大量使用大图资源,会造成页面切换卡顿,导致系统内存升高,甚至白屏崩溃。
尤其是不要把多张大图缩小后显示在一个屏幕内,比如上传图片前选了数张几M照片,然后缩小在一个屏幕中展示多张几M的大图,非常容易白屏崩溃。
可以考虑使用图片压缩、拼接方式优化以上问题。
-
图片样式处理 当页面结构复杂,css样式太多的情况,使用
<image>
可能导致样式生效较慢,出现 “闪一下” 的情况,此时全局设置image{will-change: transform}
可优化APP页面闪烁问题。 -
图片懒加载 骨架屏和懒加载的实现效果类似。骨架屏和懒加载的区别是什么?骨架屏是连图带文字全都要做骨架,懒加载只是图片做即可,效果类似,都是灰色的底色。关于懒加载方案,uniapp的
<image>
的lazy-load
属性支持APP(不支持H5),所以APP可以用。 -
优化数据更新 在 uni-app 中,定义在 data 里面的数据每次变化时都会通知视图层重新渲染页面。 所以如果不是视图所需要的变量,可以不定义在 data 中,可在外部定义变量或直接挂载在vue实例上,以避免造成资源浪费。
-
减少一次性渲染的节点数量 页面初始化时,逻辑层如果一次性向视图层传递很大的数据,使视图层一次性渲染大量节点,可能造成通讯变慢、页面切换卡顿,所以建议以局部更新页面的方式渲染页面。
如:服务端返回100条数据,可进行分批加载,一次加载50条,500ms 后进行下一次加载。
-
减少节点嵌套层级 深层嵌套的节点在页面初始化构建时往往需要更多的内存占用,并且在遍历节点时也会更慢些,所以建议减少深层的节点嵌套。
-
骨骼屏应用 由于APP的容器是默认撑起高度的,而H5页面容器可能在打开的瞬间是无高度的,因为没内容,等请求到内容后才忽然撑起高度。就会导致界面闪、晃动等用户体验问题。
可以考虑应用骨架屏做到提前撑起容器高度。
-
接口设计 减小接口响应报文体,响应体内容过多会导致页面渲染数据量过大,导致页面渲染慢。可以考虑将接口设计为图片、文字接口,可以优先渲染页面文字,然后再渲染页面图片。
3.2 问题排查
APP问题排查方面,目前可借助的调试工具并不多,尤其对于页面白屏、APP闪退的分析工具更是很少。
3.2.1 vConsole
vConsole
是由腾讯出品的 Web 调试面板,相信不少前端工程师都使用过。vConsole
会在网页中加一个悬浮的小按钮,可以点击它来打开关闭调试面板,并查看 DOM
、Console
、Network
和 本地存储 等信息。基本可以满足普通前端开发的使用需求。
vConsole
使用方法也很简单,通过npm
安装或者直接在需要的页面引入 js文件 ,然后 new VConsole()
就可以了。不熟悉的童鞋可以直接去官方的 GitHub 查看 README。但是当系统 bug 严重到一定程度,例如一进页面就报错,脆弱的 javascript
直接原地爆炸,页面一片空白,此时vConsole
就会显得苍白无力了。
与vConsole
类似的另一款调试工具是eruda。
3.2.2 weinre
weinre 是一款很不错的网页检查工具,可以通过在本地启动一个 weinre
服务,并向手机网页嵌入一段 js 脚本来实现和电脑的通信,已达到类似浏览器开发工具那样的的调试效果,它的操作界面和 vConsole
差不多,主要包括查看 DOM
、Console
、Network
等,只不过这一切是在电脑上操作,而不是在手机上。
3.2.3 Charles
Charles 是一款强大的应用层抓包工具,可以截取包括 https
在内的各种网络请求并方便的查看具体信息。有 Mac、Windows 和 Linux多版本,通过配置 WIFI 代理,可以拦截手机发出的请求。毕竟前端相当一部分报错是网络错误或数据不符合预期导致的。所以通过拦截 http(s) 请求,查看具体的请求信息和数据,能获取很多有用的信息,可以在一定程度上帮助 debug。但是该软件是付费软件,而且它定位不了 js 报错,所以也是只能作为一个辅助工具。
与Charles
类似的另一款应用层抓包工具是 Fiddler。
3.2.4 Wireshark
Charles
和 Fiddler
可以帮助捕获和分析 HTTP 层面(即应用层)的问题,如果问题发生在 TCP/IP
(即网络层)层面,则需要 TCP 报文的捕获和分析工具。
Wireshark(支持 Mac/Windows 平台)、Network Monitor
(Windows 平台)和 TCPDUMP
是常用的三种网络层抓包工具。比较常见的网络层问题包括 SSL 握手失败 和 TCP 链接中断、重发等。
总结:以上工具只是起到辅助排查问题的作用,等真正遇到问题的时候还是需要前端工程师根据问题现象并借助排错工具快速定位问题根源。
大部分hybrid app 开发工程师是由web 开发工程师转过来的,在项目中引用三方插件时可能会要求原生方式引入,因此引入质量就很难保证。而且在项目调优过程中就会存在由于不清楚原生底层工作机制导致调优效果甚微。因此,建议从事hybrid app开发的童鞋还是需要补充原生app开发技能。
四、拓展阅读
- 《Angular.js官网》
- 《Vue.js官网》
- 《React官网》
- 《React Native官网》
- 《React Native GitHub》
- 《uni-app官网》
- 《Flutter中文网》
- 《Flutter GitHub》
- 《Android官网》
- 《IOS官网》
- 《vConsole GitHub》
- 《Charles 官网》
- 《Fiddler 官网》
- 《Wireshark 官网》