Webview加载H5优化小记

栏目: CSS · 发布时间: 5年前

内容简介:从用户角度,相比Native页面,H5页面的体验问题主要有两点:通过Webview打开H5页面,请求并得到 HTML、CSS 和 JavaScript 等资源并对其进行处理从而渲染出 Web 页面。对H5页面的渲染,主要包括:渲染树构建、布局及绘制,具体可分为:

从用户角度,相比Native页面,H5页面的体验问题主要有两点:

  • 页面打开时间慢 :打开一个 H5 页面需要做一系列处理,会有一段白屏时间,体验糟糕。
  • 响应流畅度较差 :由于 WebKit 的渲染机制,单线程,历史包袱等原因,页面刷新/交互的性能体验不如原生。

这里讨论的是:第一点,怎样减少白屏时间。

二、Webview打开H5

通过Webview打开H5页面,请求并得到 HTML、CSS 和 JavaScript 等资源并对其进行处理从而渲染出 Web 页面。

1、加载流程

  • 初始化Webview -> 请求页面 -> 下载数据 -> 解析HTML -> 请求 js/css 资源 -> DOM 渲染 -> 解析 JS 执行 -> JS 请求数据 -> 解析渲染 -> 下载渲染图片 -> 页面完整展示
Webview加载H5优化小记
  • DOM渲染之前耗时主要在两部分: 初始化Webview数据请求 ,一般Webview首次初始化在400ms这个量级,二次加载能少一个量级。
  • 数据请求依赖网络,网络请求一般经过:DNS查询、TCP 连接、HTTP 请求和响应。数据包括HTML、JS和CSS资源,这些都是在webview在loadRequest:之后做的,这一阶段,用户所见到的都是白屏。(虽然4G已经成为主流,但是4G延迟明显高于Wifi)。

2、H5页面渲染

对H5页面的渲染,主要包括:渲染树构建、布局及绘制,具体可分为:

  • 处理 HTML 标记并构建 DOM 树。

  • 处理 CSS 标记并构建 CSSOM(CSS Object Model) 树。

  • 将 DOM 与 CSSOM 合并成一个渲染树。

  • 根据渲染树来布局,以计算每个节点的几何信息。

  • 将各个节点绘制到屏幕上。

说明:这五个步骤并不一定一次性顺序完成。如果 DOM 或 CSSOM 被修改,以上过程需要重复执行,这样才能计算出哪些像素需要在屏幕上进行重新渲染。实际页面中,CSS 与 JavaScript 往往会多次修改 DOM 和 CSSOM。具体参考: DOM渲染机制与常见性能优化

3、总结

  • 分析Webview打开H5打开的过程,我们发现,在H5优化中,前端重任在肩;
降低请求量:合并资源,减少 HTTP 请求数,minify / gzip 压缩,webP,lazyLoad。
加快请求速度:预解析DNS,减少域名数,并行加载,CDN 分发。
缓存:HTTP 协议缓存请求,离线缓存 manifest,离线数据缓存localStorage。
渲染:JS/CSS优化,加载顺序,服务端渲染,pipeline。
复制代码
  • 但是客户端也很重要,主要优化DOM渲染之前这些事情,可以做有: 减少DNS时间预初始化WebView 以及 HTML、JS、CSS等资源离线下载
  • 列举在某业务中笔者实践过的比较trick的优化方案,然后再引出笔者认为理想的方案。

二、WebView的客户端优化(trick版)

由于是接入第三方的H5页面,接入离线包方案,需要比较繁杂的商务沟通和技术挑战(业务逻辑和代码超级诡异),临时采用如下优化方案

1、预加载资源

  • 将首页面需要的 JS文件CSS文件 等资源放在一个URL地址( 和业务url同域名 );
  • 启动App后,间隔X秒去加载;加载的策略是,检查当前和上一次间隔时间,超时则加载,有效期忽略预加载请求。

2、预初始化Webview

  • 首次初始化Webview,需要初始化浏览器内核,需要的时间在400ms这个量级;二次初始化时间在几十ms这个量级;

  • 根据此特征:选择在APP 启动后X秒,预创建(初始化)一个 Webview 然后释放,这样等使用到 H5 模块,再加载 Webview时,加载时间也少了不少。

  • 结合步骤一中预加载公共资源,也需要Webview,所以选择在加载公共资源包时候,首次初始化Webview,加载资源,然后释放。

3、最终方案(迫不得已)

​ 由于第三方业务H5很多问题,和人力上不足;不得不需要客户端强行配合优化,在产品的要求下,不得不采用如下方案,方案的前提是:业务H5尽可能少修改,甚至不修改,客户端还要保证首屏加载快;

  • 预加载资源
  • 预创建Webview并加载首页H5,驻留在内存中,需要的时候,立刻显示。

4、方案的后遗症

  • 我不建议这种trick做法,因为自从开了这个口子,后续很多H5需求不走之前既定的离线包方案,在内存中预创建多个Webview (最多4个),加载H5时候不用新建Webview,从Webview池中获取;
  • 此种Webview池方案带来诸多隐患:内存压力、诡异的白屏、JS造成的内存泄露,页面的清空等等问题( 填坑填到掉头发 )。

三、离线包方案

1、概述

  • 离线包方案才是业务主流的H5加载优化方案,非常建议在客户端团队和前端团队推广,类似预创建Webview加载H5不应该成为主流。

  • 将每个独立的H5功能模块,相关HTML、Javascript、CSS 等页面内 静态资源 打包到一个压缩包内,客户端可以下载该离线包到本地,然后打开Webview,直接从本地加载离线包,从而最大程度地摆脱网络环境对 H5 页面的影响。

  • 离线包可以 提升用户体验 (页面加载更快),还可以 实现动态更新 (在推出新版本或是紧急发布的时候,可以把修改的资源放入离线包,通过更新配置让应用自动下载更新)

2、方案描述

引用bang的离线包方案,简单描述如下

  • 后端使用构建 工具 把同一个业务模块相关的页面和资源打包成一个文件,同时对文件加密/签名。

  • 客户端根据配置表,在自定义时机去把离线包拉下来,做解压/解密/校验等工作。

  • 根据配置表,打开某个业务时转接到打开离线包的入口页面。

  • 拦截网络请求,对于离线包已经有的文件,直接读取离线包数据返回,否则走 HTTP 协议缓存逻辑。

  • 离线包更新时,根据版本号后台下发两个版本间的 diff 数据,客户端合并,增量更新。

说明:目前WKWebView已经能成为主流,但是WKWebView在实现离线包方案时,拦截网络请求有坑。

3、WKWebView拦截网络请求的坑

  • 虽然NSURLProtocol可以拦截监听每一个 URL Loading System 中发出 request 请求,记住是URL Loading System中那些类发出的请求,也支持AFNetwoking,UIWebView发出的request,NSURLProtocol都可以拦截和监听。
  • 因为WKWebView 在 独立进程里 执行网络请求。一旦注册 http(s) scheme 后,网络请求将从 Network Process 发送到 App Process,这样 NSURLProtocol 才能拦截网络请求。
  • 但是在 WebKit2 的设计里使用 MessageQueue 进行进程之间的通信,Network Process 会将请求 encode 成一个 Message,然后通过 IPC(进程间通信) 发送给 App Process。出于性能的原因,encode 的时候 将HTTPBody 和 HTTPBodyStream 这两个字段丢弃掉( )
  • 因此,如果通过 registerSchemeForCustomProtocol 注册了 http(s) scheme, 那么由 WKWebView 发起的所有 http(s)请求都会通过 IPC 传给主进程 NSURLProtocol 处理, 导致 post 请求 body 被清空
//苹果开源的 WebKit2 源码暴露了私有API:
+ [WKBrowsingContextController registerSchemeForCustomProtocol:]

//通过注册 http(s) scheme 后 WKWebView 将可以使用 NSURLProtocol 拦截 http(s) 请求:
Class cls = NSClassFromString(@"WKBrowsingContextController”); 
SEL sel = NSSelectorFromString(@"registerSchemeForCustomProtocol:"); 
if ([(id)cls respondsToSelector:sel]) { 
   // 注册http(s) scheme, 把 http和https请求交给 NSURLProtocol处理 
   [(id)cls performSelector:sel withObject:@"http"]; 
   [(id)cls performSelector:sel withObject:@"https"]; 
}
复制代码

**说明1:**名目张胆使用私有API,是过不了AppStore审核的,具体使用什么办法,想来你也懂(hun xiao)。

说明2:一旦打开ATS开关: Allow Arbitrary Loads 选项设置为NO ,通过 registerSchemeForCustomProtocol 注册了 http(s) scheme,WKWebView 发起的所有 http(s) 网络请求将被阻塞(即便将 Allow Arbitrary Loads in Web Content 选项设置为YES );

说明3:iOS11之后可以通过 WKURLSchemeHandler 去完成对 WKWebView 的请求拦截,不需要再调用私有API解决上述问题了。

4、WKWebView自定义资源scheme

  • 向WKWebView 注册 customScheme, 比如 dynamic:// , 而不是https或http,避免对https或http请求的影响
  • 保证使用离线包功能的请求,没有post方式,遇到customScheme请求,比如 dynamic://www.dynamicalbumlocalimage.com/ ,通过 NSURLProtocol 拦截这个请求并加载离线数据。
  • iOS 11上, WebKit 提供的WKURLSchemeHandler可实现拦截,需要注意的只允许开发者拦截自定义 Scheme 的请求,不允许拦截 “http”、“https”、“ftp”、“file” 等的请求,否则会crash。

四、其他

1、LocalWebServer

  • 离线包方案中,除了拦截请求加载资源的方式,还有种在项目中搭建local web server,用以获得本地资源。市面有比较完善的框架
CocoaHttpServer (支持iOS、macOS及多种网络场景)
GCDWebServer (基于iOS,不支持 https 及 webSocket)
Telegraph (Swift实现,功能较上面两类更完善)
复制代码

2、WKWebView loadRequest 问题

  • 在 WKWebView 上通过 loadRequest 发起的 post 请求 body 数据会丢失:
//同样是由于进程间通信性能问题,HTTPBody字段被丢弃
[request setHTTPMethod:@"POST"];
[request setHTTPBody:[@"bodyData" dataUsingEncoding:NSUTF8StringEncoding]];
[wkwebview loadRequest: request];
复制代码

解决:假如想通过-[WKWebView loadRequest:]加载 post 请求 (原始请求)request1: h5.nanhua.com/order/list ,可以通过以下步骤实现:

  • 替换请求 scheme,生成新的 post 请求 request2: post://h5.nanhua.com/order/list , 同时将 request1 的 body 字段复制到 request2 的 header 中 (WebKit 不会丢弃 header 字段);
  • 通过-[WKWebView loadRequest:] 加载新的 post 请求 request2;
  • 并且通过 +[WKBrowsingContextController registerSchemeForCustomProtocol:]注册 scheme: post:// ;
  • 注册 NSURLProtocol 拦截请求 post://h5.nanhua.com/order/list ,替换请求 scheme, 生成新的请求 request3: h5.nanhua.com/order/list ,将 request2 header的body 字段复制到 request3 的 body 中 ,并使用 NSURLSession 加载 request3,最后将加载结果返回 WKWebView;

以上所述就是小编给大家介绍的《Webview加载H5优化小记》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

现代信息检索

现代信息检索

(西班牙) Ricardo Baeza-Yates、(巴西)Berthier Ribeiro-Neto / 机械工业出版社 / 2011-3 / 78.00元

本书不仅详细介绍了信息检索的所有主要概念和技术,以及有关信息检索面的所有新变化,而且其组织使读者既可以对现代信息检索有一个全面的了解,又可以获取现代信息检索所有关键主题的详细知识。本书的主要内容由信息检索领域的代表人物Baeza-Yates和Ribeiro-Neto编写,对于那些希望深入研究关键领域的读者,书中还提供了由其他主要研究人员编写的关于特殊主题的发展现状。 与上一版相比,本版在内容......一起来看看 《现代信息检索》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

SHA 加密
SHA 加密

SHA 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具