文:元芳
移动端加载网页介绍
当我们加载一个网页时,并不是发送一个url请求所有的内容都下载下来了,而是除了主URL请求外,还有其他很多的请求,比如JS、CSS、图片等文件,每一个都是独立的请求,部分请求还是串行的,需要将这些资源文件下载完成后才能渲染 。
移动端使用WebVeiw加载现状
移动端使用WebView影响用户体验,主要就是加载时间过长(发的请求比较多),造成显示空白页面过久,这就反应到下面webview加载的过程中-加载时间久长,主要包括以下三步:
- WebView的初始化
- 下载HTML并解析 c
- css、js资源的下载和渲染
如何减少这三大步骤中的耗时,成为了研究的重点。
WebView加载过程
以社区咨询页面为例在4G网络条件较好的情况下,随机取五组数据,得下图,html请求时间平均506ms,请求js、css 的时间783ms,这个不包括图片请求的时间。
请求例子:比如我使用WebView加载了一个请求 https://h5plus.dewu.com/post?...
从chales抓包的请求瀑布流可以看到加载WebView的url时,先请求到html以后,通过解析,才去加载css、jss等一些资源,同时也可以看到加载一个WebView页面,除了一个主HTML的URL以外,css、js的请求发送了7个请求,这还是一个不太复杂的webview页面,如果过于复杂,可想而知请求的数量。如何减少css、js请求也是H5端优化的方式之一。而对于客户端而言,同样通过提前把js、css一些资源放在本地,也可以优化WebView的加载速度。
WebView加载HTML方式
通过服务器,以url的形式返回
这种也是传统的加载方式,弊端就是网络不好的情况下,会出现较长时间的白屏,用户体验不好 。加载本地的html模板,通过本地注入内容的方式这种方式,是大多数公司研究的重点,可以实现WebView秒开,比如头条的新闻详情页,适用于不太关注实时变化的页面,几乎感受不到白屏,能达到原生的体验,原理就是提前把所需的js、css、html模板下载到本地,提前渲染好WebView,只需打开时,客户端注入内容数据即可,极大的提高了WebView的加载速度,这个也是本文研究的重点。 直接加载带标签的字符串(以富文本的方式加载) 这中方案适用于简单、纯展示的UI界面,实现比价简单,功能比较单一。
得物社区咨询页面现状
目前社区咨询专栏页面,页面上半部分使用的是WebView,下半部分是原生的评论页面,加载WebView的方式也是传统的通过url加载的方式,用户体验不是很好,平均打开一个页面需要2s左右,为了提升用户体验,减少WebView的加载耗时,对WebView的优化做了调研。
最终通过调研和方案对比,客户端选用了调研了加载本地的html模板,通过注入内容的方式加载WebView页面。
由于在社区咨询页面加载列表的时候,都已经拿到了渲染webview的内容数据,因此点击进入咨询详情页的时候,其实内容数据也在本地了,相当于减少WebView发送请求的个数,把 js、css的数据以及html模板提前放到本地,通过file协议,提前加载,当打开WebView时,直接把内容注入本地HTML模板,极大节省了WebView请求和加载的时间。
最终的WebView加载请求示意图如上图所示,省去了中间html、css、js 请求的时间,通过加载离线本地的方式,大大提高了速度,本地加载html、css、js的时间可以忽略不计。
离线包下载逻辑:
无法复制加载中的内容
获取注入的内容数据的方式:
- 如果列表已经有了内容数据,进入WebView无需再发送请求,可以直接把内容数据注入本地的html模板
- 如果列表没有内容数据,进入WebView根据不同的内容,请求不同的URL获取内容数据,然后注入本地的html模板
最终以demo的形式使用chales模拟4G网络条件优化前后的对比效果如下:
优化前
📎4G优化前咨询专栏.mp4
优化后
📎4G优化后咨询专栏.mp4
优化前后的数据对比,就demo而言;
WebView加载到渲染结束的时间对比如下
由上图数据可以明显的看到,WebView从加载到渲染结束,提高幅度达到了98%左右,优化效果还是很明显的。
接下来咱们再细化分WebView各个阶段的请求时间:
css、js资源网络请求的时间
html网络请求时间
由于css、js还有html模板都可以以离线资源的形式,提前放在本地,所以请求资源的时间都可以省了,这样的话,就会大大减少WebView加载过程中的时间。
并且图片的加载时间也有明显的提升,相关数据如下,这个提高幅度也是非常客观的。
对于技术而言,优化无止境,一直在路上,目前还处于demo阶段,下阶段我们会按照方案实施,优先优化社区的咨询专栏详情页,具体效果如何,大家拭目以待吧。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。