苹果供给的WKWebView运用简单方便,普通需求甚至只需寥寥数行代码便可完结中心功用,为开发者带来了便当。但是在WKWebView的功能改善中,我认为开发者还有许多工作可做。假如你也有这方面的爱好,无妨来听听我的看法~
1.背景
用户体验
网页的敞开速度是用户最直观的体验之一。但网页相关于原生的发动相应速度还是略有差距,所以需求咱们开发者持续努力,给到用户更好的体验。
理解问题的实质才干更好的处理问题。所以需求剖析WKWebView的发动究竟在做什么工作?
2. 剖析
我将webView发动分为三个阶段:wkwebView初始化阶段,浏览器网络资源恳求阶段,浏览器烘托阶段。接下来我会逐一进行剖析。
2.1 WKWebView初始化阶段
从代码上来看,WKWebView的运用是非常简单的:
WKWebView *wkWebView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:configuration];
初一看的确貌似没什么问题,但是细想却又有点奇怪,为什么会觉得怪?
那便是alloc初始化之后,是否意味着WKWebView现已初始化完结了呢?
我经过以下三点进行了考虑:
- WKWebView是在另外一个进程上运转的。
- WKWebView是NSObject的子类,经过alloc办法创立之后,实际上便是在咱们APP的进程内存中创立了一个WKWebView的结构体罢了。
- 初始化完结状况应该可用状况,结合第一点考虑,那应该也要初始化一个WKWebView进程。
经过上面三点剖析,能够得出结论alloc之后,并不意味着初始化完结。
那阅历init办法后,是否意味着WKWebView现已初始化完结了呢?
init构造办法的确还不太好从理论上剖析,谁也不知道构造办法里边写入了什么内容,好在WebKit开源,那么就直接从源码上面剖析吧!
经过源码剖析函数走向为: initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration -> _initializeWithConfiguration:(WKWebViewConfiguration *)configuration;
中心流程在第二个函数中。直接看看部分代码吧~
从代码上来看,首要做了如下几件工作:
- 设置WKProcessPool
- 设置装备信息
- 初始化WKContentView并绑定
- 生成WebPageProxy并赋值到configuration
- 设置窗口大小与展现形式
- 添加一些告知
- 添加一些代理
总的来看,都是对WKWebView这个对象进行操作,并未提及到进程初始化。所以能够得出结论,init办法之后,也不意味着初始化完结。
那关于WKWebView操作还有两个办法:loadRequest:和addSubView:。首先扫除addSubView:,直接剖析loadRequest:
剖析loadRequest:办法。 经过符号断点抓取函数栈,先看看函数栈。
源码剖析WebPageProxy::loadRequest这个办法究竟做了什么?
看1368和1369两行代码,从字面意思描绘的比较清楚了。先判别有没有进程,假如没有进程的话,就初始化一个进程~
那先剖析hasRunningProcess里边做了什么工作:
首要便是经过一个m_hasRunningProcess的标识位,来判别当前的WKWebView有没有敞开WKWebView的进程。
接下来看看初始化进程lauchProcess办法里边做了什么吧~
首要操作如下:
- 查看器重置。
- 843行-844行。WKWebView进程(后边统称WK进程)移除相关的WKWebView与IPC通讯。这一步其实很迷惑,既然是WKWebView中没有WK进程的话,那初始化进程的时候为什么会有移除相关的操作?这里就引伸出来另一个概念:WK进程复用。也便是当咱们APP关闭一个WKWebView之后,WK进程并没有马上完毕,而是会在后台坚持一段时刻。这其实也很好的说明晰一个现象:第二次敞开WKWebView要比第一次敞开WKWebView初始化耗时更少。
- 安全发动WK进程。
- WK进程绑定当前的WKWebView以及树立IPC通讯。
- 注入一些信息。
走到这里也能够盖棺事定了,loadRequest:办法之后,才算初始化完结。那总结下WKWebView初始化都阅历了那些工作吧,以一张图来展现。
2.2 浏览器网络资源恳求及烘托阶段
一个网页需求完好的在浏览器展现需求用到三种资源:
- HTML/SVG/XHTML,HTML字符串描绘了一个页面的结构,浏览器会把HTML结构字符串解析转换DOM树形结构。
- CSS,解析CSS会产生CSS规则树,它和DOM结构比较像。
- Javascript脚本,等到Javascript 脚本文件加载后, 经过 DOM API 和 CSSOM API 来操作 DOM Tree 和 CSS Rule Tree。
而这些资源都是经过网络恳求,或许从本地缓存中读取,只要拿到这些资源后,浏览器才干开端进行烘托的操作。简而言之,获取资源的速度决议了WKWebView发动的速度。
那在什么时机才意味着网络资源恳求悉数完结呢?
所以咱们需求剖析浏览器下载资源流程,首要流程为四步:
- 浏览器下载HTML,先从本地缓存进行查找,假如本地缓存没有,则建议网络恳求。
- 获取HTML后,浏览器解析HTML,然后一边构建DOM,一边下载解析到的CSS,JS资源,也会先从本地缓存进行查找,假如本地缓存没有,则建议网络恳求。
- 结合DOM与CSS生成的CSSOM,出产Render Tree。这一步是和第2步并发执行。
- 浏览器依据Render Tree进行烘托。这一步也是并发执行。
用一张图来表示:
在HTML解析完结,并下载悉数的CSS,JS之后,才干够生成彻底的Render Tree,此刻的浏览器才干完好的烘托出网页内存。那么在此刻,咱们才认为网络资源恳求现已完结。
3. 解决计划
3.1 四个原则与三个方向
剖析完流程,接下来的优化也就比较好解决了,解决计划按照下面四个方向进行就好:
- 那些工作能够提早做
- 那些工作能够一同做
- 那些工作能够不用做
- 那些工作能够削减做
我会经过三个方向进行调优:
- WKWebView初始化阶段
- 浏览器资源恳求阶段
- 浏览器烘托阶段
3.2 webView初始化阶段调优
- 预初始化一个WKWebView(提早做)
- WKWebView复用池 (削减做)
流程图如下:
需求留意的点:
- WKWebView入池后,需求loadRequest一个空页面,此刻才干能算真实发动初始化流程。
- WKWebView出池时,只要完结didFinish回调后,才干顺畅入池。防止因为delegate而引起其他反常。
- 复用的WKWebView的需求铲除backForwardList。
3.3 浏览器资源恳求阶调优
- 网络资源缓存池构建 (削减做)
- 资源预下载 (提早做)
需求做到上叙四点,需求解决一个壁垒。WKWebView的网络阻拦以及WKWebView的资源管理。之前的文章我现已进行了共享,这个计划的特色是:能够完好的阻拦到WKWebView建议的网络恳求,并且阻拦时机是在访问浏览器缓存之前。经过这两个特色,就能很好的对WKWebView网络阶段进行操控和管理。
3.3.1 网络资源缓存池构建
缓存分为两级:
- 强缓存:不会向服务器建议恳求,直接从缓存中读取缓存。
- 协商缓存:当强缓存失败后,携带缓存标识字段向服务器建议恳求,由服务器依据缓存标识字段来决议是否运用缓存。
流程图如下:
3.3.2 资源预下载
经过浏览器网络资源恳求的剖析,能够得到一个结论:要想知道HTML里边的资源,就得先下载HTML并解析。那除掉这种计划,那还有其他办法能够知道HTML里边的资源呢?答案是:前端同学知道。那让前端同学在适宜的时机以适宜的方法告知咱们就好了。
适宜的时机:APP发动60秒之后拉取,以及每10分钟轮询一次。
适宜的方法:网页资源表。
资源表结构如下:
资源分为三个等级:高等级:资源存在资源列表中,且PromptlyDown = 1。高等级资源会在拉取到资源表且为WIFI环境,则马上下载资源。
中等级:资源存在资源列表中,且PromptlyDown = 0。中等级资源会在拉取到资源表且为WIFI环境且客户端网络有空闲时,则马上下载资源。
低等级:资源只存在网页列表中。低等级资源只会在翻开对应网页时,才会下载资源。
流程图如下:
3.4 浏览器烘托阶段调优
- HTML预解析 (提早做)
- WebView发动流程调优:并发进行webView初始化,HTML下载,资源表CSS,JS下载 (一同做)
3.4.1 HTML预解析
经过原理剖析,咱们现已知道HTML解析首要包括:生成DOM树,以及加载CSS,JS资源。
那么在将要翻开网页时,能够经过资源表中的信息,搜寻到HTML所需的CSS,JS资源。此刻能够将所需资源从磁盘加载到内存,亦或是建议网络恳求,如此即可模拟HTML解析作用。
流程图如下:
3.4.2 WebView发动流程调优
在webView的全体发动流程中,webView初始化、HTML下载,CSS,JS下载三者是一个串行联系。由于HTML,CSS,JS的下载都不是UI操作,所以可在子线程中进行,那么关于这种串行的流程实际上没有彻底利用手机功能,造成了功能浪费。经过上叙的优化后,咱们能够对webView初始化,以及网络恳求进行操控。那么咱们就能够将webView初始化、HTML下载,CSS,JS下载三者调整为并发进行,使得功能尽可能的彻底运用。
先来看看浏览器原本的资源加载流程:
改为并发之后为:
4.总结
4.1 全体流程
4.2 计划总结
本文从背景开端叙述,扼要说明晰WKWebView发动优化的理由。
随后剖析了WKWebView初始化原理,浏览器获取资源以及烘托原理,正所谓了解问题的实质才干提出最佳计划。
最后结合四个原则:提早做,一同做,削减做,不要做。以及三个方向:WKWebView初始化,浏览器资源恳求,浏览器烘托。逐一给出阶段性的解决计划,大家能够学习参考,有更好的主意也欢迎沟通交流。
经过此次需求,我总结了如下心得:
- 总结了四个原则。当遇到速度类优化问题时,无妨先想想这四个原则。
- 了解问题的实质。充分了解实质,整理全体流程,方能给出合理计划。
- 阶段性优化。方针太远时,无妨分割成多个优化阶段。不要梦想一口吃成大胖子。
- 善用缓存。以空间换时刻,充分调动设备功能,以此获取更好体验。
- 资源表的妙用。除了能够优化发动速度,还能够动态的对资源进行增修改的操作。
相关文章
深化剖析WebKit
浅显易懂浏览器烘托原理
深化理解浏览器的缓存机制
从URL输入到页面展现究竟发生什么?