网站内容更新不及时(一下H5在iOS移动端表现时使用缓存并及时更新方案)
优采云 发布时间: 2021-10-04 20:22网站内容更新不及时(一下H5在iOS移动端表现时使用缓存并及时更新方案)
最近在研究H5在iOS移动端性能上的缓存使用和及时更新。总结如下:
一、使用Webview自带的缓存机制
我们在使用webview加载html资源的时候,本质上就是一个http请求过程,向服务器请求资源。如果此时我们设置了http请求的缓存策略,那么资源文件可以存放在内存空间和本地沙箱文件(iOS)中;我们下次加载的时候,如果加载了同一个http请求地址,如果此时有本地缓存,则直接返回本地资源;如果没有本地缓存,则发送到服务器请求地址;大致流程如下
具体流程及相关设置如下:
1.在IOS端加载html页面内容。这里我使用了NSURLRequestReturnCacheDataElseLoad的缓存策略,即有缓存时使用缓存,无缓存时直接请求服务器;
NSURL *url = [NSURL URLWithString:self.url];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:20];
[webView loadRequest:request];
2.html5端:不需要设置如下代码。经过测试发现,如果在上述iOS端设置http加载缓存策略,则IOS端设置的缓存策略为优先,即ios已经设置了缓存策略,html5设置没有缓存,那么结果还是会被缓存;
3.iOS端不需要设置清除缓存的代码。在iOS webview加载时序和缓存问题总结中,写了不使用缓存的removeCache的iOS代码;
加载和使用缓存的结果如下:
1. 这时候缓存的文件会保存在ios app的沙盒文件中。如果此时不退出应用,缓存的内容也会保存在内存中;如下图所示(此处为 UIWebView ):
2.这时候可以看到在Caches文件中,Paul.H5下多了一个Cache.db数据库。打开数据库,可以看到以下内容;注意此时的图片资源也存放在 Paul.H5 文件中;
2.1 请求的连接地址表:
2.2缓存的资源文件
3. 以上测试均为 UIWebView 测试。使用WKWebView测试的时候,打开cache.db时,没有内容,但是加载的时候,还有缓存文件,但是WKWebView的缓存在不同的文件夹中,如下:
3.1 在WKWebView中,cache.db中没有缓存文件
3.2 下面有更多的WebKit文件夹,后面还有几个二级文件,存放WKWebVieW下的缓存文件(包括JS/CSS/pictures);
4. 至此,所有的资源文件都已经缓存完毕。下次用 WebView 加载时,可以顺利使用缓存的文件。即使没有网络,您也可以使用缓存的文件。, 类似于下面介绍的应用缓存离线缓存功能;
如何即时更新html5的内容
在这里,我使用在http连接中添加版本号的方法。在iOS webview加载时序和缓存问题总结中已经有描述,例如:index1.html?v=1.1.0 index.js?v=1.@ >0.0 index.css?v=1.0.0 如果修改html端的内容,可以直接在相反的版本号上加一个,当然也可以还使用时间戳或随机数方法;这时候版本号更新后,http请求会忽略之前的缓存文件(因为不是同一个连接地址),从服务端拉取最新的数据内容,然后渲染到界面上是最多的最近的内容;
使用webview缓存及注意事项
1.使用NSURLRequestReturnCacheDataElseLoad时,如果加载的html5文件是多页内容,在UIWebView中加载时,点击html5主页的index.html时,没有internet时不会使用缓存. 好的index2.html文件,就是不能跳转,但是WKWebView加载的时候,可以顺利跳转使用缓存的index2.html资源文件,不知道有没有我的测试有问题,或者它本身就是一个错误;
2. 使用这种类型的缓存时,如果缓存的html JS收录其他http网络请求(比如需要先请求数据,然后在模板引擎中渲染界面);那么在没有网络的情况下,建议对网络的接口进行处理,否则接口可能会很乱。有点啰嗦,见谅!!!
3. 关于缓存时间的问题,因为每次加载新的html内容,都会缓存新的html内容,比如index.html?v=1.1.0 缓存内容v1.1.0 中的 html。这样下去,缓存的内容会越来越多。建议在IOS端做一个定时清理缓存的代码。可以参考《iOS开发网篇-数据缓存》一文;
二、使用html Application Cache Api
使用html5的应用缓存离线缓存文件的策略也是一个不错的选择,但是这里不推荐也不推荐。看来问题不少;
应用缓存的使用
0.Manifest文件加载原理流程图:
1.看手机兼容性
可以看出,移动兼容性还是非常高的。只是说在Android4.4上退出app时,会出现缓存丢失的问题;
2.应用缓存的使用
2.1 创建一个.manifest文件,如下图
manifest文件首先要以CACHE MANIFEST开头,然后收录三部分: CACHE:NETWORK:FALLBACK:三部分,上面的介绍不再赘述;
2.2 清单文件的使用;
只需在html中添加manifest数据,写上相反的.manifest的地址即可;完成以上步骤后,应用缓存的所有进程都已经完成
2.3 manifest离线缓存加载过程:
2.3.1 第一次加载时:
2.3.2 如果.manifest文件没有更新;
3.应用缓存常用api
window.applicationCache.update() //update方法调用时,页面会主动与服务器通信,检查页面当前的缓存是否为最新的,如不是,则下载更新后的资源
window.applicationCache.swapCache() //updateready后,更新到最新的应用缓存
通常我们可以通过结合以上两种方法和对应的属性来手动触发文件的更新(前提是manifest文件发生了变化)。
var appCache = window.applicationCache;
appCache.update(); //检查更新
if (appCache.status == window.applicationCache.UPDATEREADY) {
//如果存在更新,并且已经下载ok,则替换浏览器缓存
appCache.swapCache();
}
不过此时页面上还不能使用最新的文件,而是浏览器的缓存发生了变化,网页的实际内容还是原来的内容。您还需要手动重新加载以更新文件。
window.addEventListener('load', function(e) {
window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
if (confirm('文件有更新,手否重新加载文件')) {
window.location.reload();
}
} else {
//如果,拒绝则不刷新网页
}
}, false);
}, false);
4.如何及时更新html js等文件
在这里,我使用与 webView 缓存更新相同的方法。通过添加版本号,这些文件的内容每更新一次,就在原来的版本号上加一个;您可以查看上面的 .manifest 文件。以供参考; (注意html中的js css版本号要和.manifest中的文件一致)这里特别说明一下,manifest更新的过程;如果manifest文件更新了,.manifest中所有缓存的资源文件都会再次到服务器上 如果请求的文件更新了,下载最新的文件。如果没有更新,则返回http代码304;最重要的是第一次刷新时不会更新最新的文件;这是第一次刷新过程只下载最新的文件并保存在缓存中。只有在下次刷新时,再次从缓存中拉取最新数据,更新界面;并特别注意 index1.html。会被缓存,就好像应用缓存机制是这样设置的;
5.移动端加载后应用缓存的位置
在iOS webView中使用application Cache加载html文件,此时缓存文件存放在如下目录。. 在下面OffineWebApplicationCache文件下的ApplicationCache.db的数据中;
查看数据库中的资源文件:
6.关于应用缓存使用过程中的坑和不推荐的地方(转自知乎等地方,我没有测试过):
6.1 更新机制:一旦使用了manifest,就无法清除这些缓存,只能更新缓存,否则必须自己清除缓存。用 manifest 本身标记的 html 也被缓存,无法清除;这里一旦更新了错误的页面,就会被缓存起来,没有机会访问到正确的页面,那就只能使用了,所以保证更新页面资源的正确性就显得尤为重要。此外,电信等运营商喜欢在一些高流量网站中劫持广告。在这种情况下,这些广告很可能会在更新过程中被缓存。
6.2 舱单本身的准备要求很严格。注意换行、路径文件名等问题。否则缓存将无效。
6.3 如果更新的资源之一更新失败,会导致所有更新失败,会使用之前版本的缓存。
6.4 第二次更新的问题,即在更新新版本的过程中,用户第一次需要访问旧资源,第二次需要进入新资源。如果此时后端接口发生变化,那么第一次访问的旧数据很可能存在兼容性问题。
6.5 大小限制通常是最大 5mb 缓存,但一般来说已经足够了。
6.6 回滚问题,可以参考《谨慎使用Manifest》之前的文章文章。一般来说,你从无到有,你想回滚到无。
6.7 Android中关闭app后4.4,缓存会丢失;(未测试)!
6.8 频繁的网络请求太多;每次manifest文件发生变化,CACHE:中的资源都会被服务器访问,即使返回304。如果资源比较大,可以在移动端使用。非常消耗流量;