如何打造一个高性能Hybrid App?

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
查看查看222 回复回复2 收藏收藏 分享淘帖 转播转播 分享分享 微信
查看: 222|回复: 2
收起左侧

如何打造一个高性能Hybrid App?

[复制链接]
apper 发表于 2016-7-25 18:04:14 | 显示全部楼层 |阅读模式
快来登录
获取优质的苹果资讯内容
收藏热门的iOS等技术干货
拷贝下载Swift Demo源代码
订阅梳理好了的知识点专辑

0、引言

在多元化的今天,一个热门的移动app,或多或少都会有内在H5在其中。而对于一个有很多运营场景的app来说,这种情况更常见了。试想一下,如果在一个公司,存在很多native和H5同时需要开发的页面,为了节省开发成本,此时如果只开发H5,就需要考虑native的体验了,而这就是本文的目的,如何让native端拥有像加载本地页面一样的速度去加载H5。


在app内加载H5速度慢一直是客户端开发的痛点,抛开H5的体验本身与native就有差距不说,如果加载速度还很慢,这将会对用户体验造成巨大影响。那么像做到像native页面一样瞬间加载完H5,思路就会变得比较清晰了——提前在本地存储远程资源包




1、方案选择

从这个点出发,我们需要考虑,以怎样的形式来提前拿到资源包(css,js,html,通用的图片等),减少这些静态资源的网络请求,增加加载速度。无非就是一下两点:

  • 将资源包在app打包阶段直接植入
  • 在运行时动态下载资源包


单纯从业务层来说,如果你的业务够简单,其实第一种方式已经完全满足,每次需要新增页面就重新发版嘛,虽然显得有点愚笨,但是还是能满足的。

但是从长远的角度来说,我们要做到尽可能的动态化,动态化是客户端的热点,我们要做到尽量不依赖于版本更新来实现动态化。对于iOS来说,更新机制本身就非常缓慢,要通过app store的审核有时候还需要靠人品,更何况用户也不一定买账,他们不一定会更新我们的app。在这样的情况下,第二种方案就会显得更加友好。




2、设计加载流程

那么,该怎么设计一套完整的解决方案来满足运行时动态下载资源包呢。

抽出细节,大体上可以归结为下图所示的结构图:

如何打造一个高性能Hybrid App? 1

如何打造一个高性能Hybrid App? - 敏捷大拇指 - 如何打造一个高性能Hybrid App? 1

app与服务端交互

我来解释下这个图,我是建立在客户端已经实现socket层协议,所以能与server保持长连接以至于server能主动push数据的情况,实现这种协议蛮复杂的。实际上如果没有这个协议,那就需要client找时机主动去server请求(app启动时请求一次?或者是每隔一段时间请求一次,取决于你),本文以后者为例。

下面我来演示下一个完整的下载新资源包的过程:

1.运营小妹觉得某节日要到了,需要发布一个新的页面,然后在运营后台生成资源包,运营后台会自动更新config,其中包括资源包的version,是否强制关闭加载本地资源包(降级策略,防止这个组件本身有BUG),还有一些hotpatch脚本。并且将资源包根据里面的内容部署到remote database。

2.在合适的时机,client发起http请求向server查询是否有新版本的资源包,并带上本地的config。

3.server根据config里的选项,比对从client拿到的config,发现客户端是旧版本的config,OK,则下发新的config给client,并且发送从database里拿到的资源包(为了加快速度,可以部署到CDN)。

4.client拿到最新的资源包后,在本地进行解密,解压等操作,并映射成对应ULR相对于本地的local file url。比如:http://www.swifthumb.com这个网址下的静态资源文件在本地的的file://dsalkfjsldfjalsd/目录下。

至此,已经完成资源包的下载。




3、拦截并加载本地资源包

那么有了资源包后,怎么能让app像native页面的速度去加载H5呢。

其实原理就是对H5请求进行拦截,如果本地已经有对应的静态资源文件,则直接加载,这样就能达到“秒开”webview的效果。

对于iOS而言,这就需要用到NSURLProtocol这个神器了。接下来,分析下它到底是什么东西,我们怎么利用它达到上述效果。

NSURLProtocol能够让你去重新定义苹果的URL加载系统(URL Loading System)的行为,URL Loading System里有许多类用于处理URL请求,比如NSURL,NSURLRequest,NSURLConnection和NSURLSession等。当URL Loading System使用NSURLRequest去获取资源的时候,它会创建一个NSURLProtocol子类的实例,你不应该直接实例化一个NSURLProtocol,NSURLProtocol看起来像是一个协议,但其实这是一个类,而且必须使用该类的子类,并且需要被注册。                                       

——从网上拷贝的


换句话说,NSURLProtocol能拦截