文档章节

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

筱飞
 筱飞
发布于 2016/06/28 14:03
字数 1777
阅读 67
收藏 4
点赞 1
评论 0

 

引言

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

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

方案选择

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

1.将资源包在app打包阶段直接植入

2.在运行时动态下载资源包

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

但是从长远的角度来说,我们要做到尽可能的动态化,动态化是客户端的热点,我们要做到尽量不依赖于版本更新来实现动态化。对于iOS来说,更新机制本身就非常缓慢,要通过app store的审核有时候还需要靠人品,更何况用户也不一定买账,他们不一定会更新我们的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,则下发新的configclient,并且发送从database里拿到的资源包(为了加快速度,可以部署到CDN)。

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

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

拦截并加载本地资源包

那么有了资源包后,怎么能让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能拦截所有当前app下的网络请求,并且能自定义地进行处理。

代码如下

这里只介绍与我们需求相关的NSURLProtocol方法。

搞了这么多,其实最核心的就是前四个方法:

+ (BOOL)canInitWithRequest:(NSURLRequest *)request

这个方法的作用是判断当前protocol是否要对这个request进行处理(所有的网络请求都会走到这里,所以我们只需要对我们产生的request进行处理即可)。

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request

这个方法其实很强大,它可以对request进行预处理,比如对header加一些东西什么的,我们这里没什么要改的,所以直接返回request就好了。

- (void)startLoading

重点是这个方法,我们这里需要做一件事,就是自己拼装httpResponse,并且返回给url load system,然后到了webview那一层,会收到response,对于webview而言,加载本地和走网络拿到的response是完全一样的。所以上述代码展示了如何拼装一个httpResponse,当组装完成后,需要调用self.client将数据传出去。

何为self.client,这个东西其实就是protocol与url load system交互的一个对象,系统提供给我们的,这样理解就够了。

需要注意的是,细心的读者会看到else里会有一段代码:

[NSURLProtocol setProperty:@YES forKey:WDHybridResourceProtocolHandledKey inRequest:newRequest];

这个是干什么用的?else的作用是当本地不存在这个文件时,则主动重新发请求,此时又会调用canInitWithRequest,如果不设置flag,则会无限递归了。所以你懂得。

当然,重新发请求自然要实现NSURLConnectionDelegate

总结

至此,如何快速加载H5已经全部介绍完毕。

附上前后加载速度对比:

 

© 著作权归作者所有

共有 人打赏支持
筱飞
粉丝 13
博文 108
码字总数 22146
作品 0
虹口
前端工程师
01、RN 系列之 什么是 ReactNative

版权声明:本文为博主原创文章,未经博主允许不得转载。 PS:转载请注明出处 作者: TigerChain 地址: www.jianshu.com/p/717ccdd7c… 本文出自 TigerChain 简书 ReactNative 系列 教程简介 1、...

TigerChain ⋅ 2017/12/15 ⋅ 0

WeX5开源前端/WeX5

WeX5跨端移动开发框架开源项目简介 一、WeX5是什么 WeX5是H5 App开发工具,开源免费,极速秒开;只需一次开发,即可发布、运行于各种前端平台上;支持iOS ipa、android apk、微信服务号/企业...

WeX5开源前端 ⋅ 2015/01/14 ⋅ 0

Hybrid App混合开发的成本和趋势

  Hybrid App在过去的两年中已经成为移动界的核心话题,但是作为一名Web开发者来说要如何站在移动互联网的浪潮之巅呢?是选择学习原生开发,研究Java、Object-C、C#等语言,还是选择继续使...

H5混合APP开发 ⋅ 2016/08/14 ⋅ 0

别闯进Hybrid App的误区

【引言】Hybrid App,一种开发模式,兼顾Web和Native的一种开发模式。有人说它把Web App扼杀在摇篮里,有人说它把Native App引向一个新阶段。我说,它是一把双刃剑,千万别闯进它的误区。本文...

mickelfeng ⋅ 2015/10/14 ⋅ 0

oschina唯一托管并首发跨端开发大杀器,看不看由你!!!

上周在OSChina上唯一托管并首发的大杀器,强烈推荐。 能力比市场上同类收费工具强很多,技术很优雅很开放,采用Apache v2.0许可证开源模式,诚意打满分! 一、X5是什么 X5是跨端移动快速开发...

就在刹那间 ⋅ 2015/01/20 ⋅ 30

X5跨端移动开发框架开源项目简介[oschina首发托管]

一、X5是什么 X5是跨端移动快速开发框架;只需一次开发,即可发布、运行于各种前端平台上;支持iOS ipa、android apk、微信服务号/企业号应用、web app和其他轻应用的快速开发。 二、X5采用的...

WeX5移动开发云 ⋅ 2015/01/15 ⋅ 7

移动版的三种开发模式(web app,hybrid app,native app)大型公司是如何安排的?

首先,祝大家新年快乐,猴年心想事成,万事如意! 如果开发一个类似去哪儿这样的旅游电商平台,包括PC版和移动版,数据分析的结果为:只用电脑和只用手机的几乎是各占一半。如果安排先开发...

女码农 ⋅ 2016/02/10 ⋅ 2

AppCan赵庆华: Hybrid 混合开发正当时

  巨大的市场对于App开发服务提供商来说是绝佳的机遇。AppCan作为国内混合开发的领导品牌,同时服务开发者B2D和企业级B2B市场,提供移动应用开发平台和企业移动整体解决方案。多年来,App...

梅朵 ⋅ 2015/10/10 ⋅ 0

聊聊Web App、Hybrid App与Native App的设计差异

目前主流应用程序大体分为三类:Web App、Hybrid App、 Native App。 一、Web App、Hybrid App、Native App 纵向对比 首先,我们来看看什么是 Web App、Hybrid App、 Native App。 1. Web A...

SomaLihq ⋅ 2017/01/12 ⋅ 0

聊聊Web App、Hybrid App与Native App的设计差异

目前主流应用程序大体分为三类:Web App、Hybrid App、 Native App。 一、Web App、Hybrid App、Native App 纵向对比 首先,我们来看看什么是 Web App、Hybrid App、 Native App。 1. Web A...

看看这天 ⋅ 2015/04/21 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

BS与CS的联系与区别【简】

C/S是Client/Server的缩写。服务器通常采用高性能的PC、工作站或小型机,并采用大型数据库系统,如Oracle、Sybase、InFORMix或 SQL Server。客户端需要安装专用的客户端软件。 B/S是Brower/...

anlve ⋅ 43分钟前 ⋅ 0

发生了什么?Linus 又发怒了?

在一个 Linux 内核 4.18-rc1 的 Pull Request 中,开发者 Andy Shevchenko 表示其在对设备属性框架进行更新时,移除了 union 别名,这引发了 Linus 的暴怒。 这一次 Linus Torvalds 发怒的原...

问题终结者 ⋅ 今天 ⋅ 0

在树莓派上搭建一个maven仓库

在树莓派上搭建一个maven仓库 20180618 lambo init 项目说明 家里有台树莓派性能太慢。想搭建一个maven私服, 使用nexus或者 jfrog-artifactory 运行的够呛。怎么办呢,手写一个吧.所在这个...

林小宝 ⋅ 今天 ⋅ 0

Spring发展历程总结

转自与 https://www.cnblogs.com/RunForLove/p/4641672.html 目前很多公司的架构,从Struts2迁移到了SpringMVC。你有想过为什么不使用Servlet+JSP来构建Java web项目,而是采用SpringMVC呢?...

onedotdot ⋅ 今天 ⋅ 0

Python模块/包/库安装(6种方法)

Python模块/包/库安装(6种方法) 冰颖机器人 2016-11-29 21:33:26 一、方法1: 单文件模块 直接把文件拷贝到 $python_dir/Lib 二、方法2: 多文件模块,带setup.py 下载模块包(压缩文件zip...

cswangyx ⋅ 今天 ⋅ 0

零基础学习大数据人工智能,学习路线篇!系统规划大数据之路?

大数据处理技术怎么学习呢?首先我们要学习Python语言和Linux操作系统,这两个是学习大数据的基础,学习的顺序不分前后。 Python:Python 的排名从去年开始就借助人工智能持续上升,现在它已经...

董黎明 ⋅ 今天 ⋅ 0

openJdk和sun jdk的区别

使用过LINUX的人都应该知道,在大多数LINUX发行版本里,内置或者通过软件源安装JDK的话,都是安装的OpenJDK, 那么到底什么是OpenJDK,它与SUN JDK有什么关系和区别呢? 历史上的原因是,Ope...

jason_kiss ⋅ 今天 ⋅ 0

梳理

Redux 是 JavaScript 状态容器,提供可预测化的状态管理。 它是JS的状态容器,是一种解决问题的方式,所以即可以用于 react 也可以用于 vue。 需要理解其思想及实现方式。 应用中所有的 stat...

分秒 ⋅ 今天 ⋅ 0

Java 后台判断是否为ajax请求

/** * 是否是Ajax请求 * @param request * @return */public static boolean isAjax(ServletRequest request){return "XMLHttpRequest".equalsIgnoreCase(((HttpServletReques......

JavaSon712 ⋅ 今天 ⋅ 0

Redis 单线程 为何却需要事务处理并发问题

Redis是单线程处理,也就是命令会顺序执行。那么为什么会存在并发问题呢? 个人理解是,虽然redis是单线程,但是可以同时有多个客户端访问,每个客户端会有 一个线程。客户端访问之间存在竞争...

码代码的小司机 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部