首页 > 系统 > iOS > 正文

详解iOS webview加载时序和缓存问题总结

2019-10-21 18:44:51
字体:
来源:转载
供稿:网友

iOS webView的加载时序

UIWebView加载顺序:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {  NSLog(@"开始请求webview:%@",request.URL.relativeString);  return YES;} - (void)webViewDidStartLoad:(UIWebView *)webView {    NSLog(@"开始加载webview");  }- (void)webViewDidFinishLoad:(UIWebView *)webView {    NSLog(@"结束加载webview");  }  - (void)webView:(UIWebView *)webView didFailLoadWithError:(nonnull NSError *)error {    NSLog(@"webView加载失败"); }

加载的结果:

2017-04-27 08:53:00.535 H5页面调试[1273:150877] 开始请求webview:http://xxxx/index1.html
2017-04-27 08:53:00.537 H5页面调试[1273:150877] 开始加载webview

-----------------显示开始加载html CSS js 和图片资源等(JS引擎单线程顺序执行)---------------

2017-04-27 08:53:01.069 H5页面调试[1273:150877] 结束加载webview

 WKWebView加载时序:

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {  NSLog(@"webview开始请求");  decisionHandler(WKNavigationActionPolicyAllow);}- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {  NSLog(@"webView开始加载");}- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {  NSLog(@"webview开始收到响应");  decisionHandler(WKNavigationResponsePolicyAllow);}-----------------显示开始加载html CSS js 和图片资源等(JS引擎单线程顺序执行)---------------- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {  NSLog(@"1");}- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {  NSLog(@"webview结束加载内容");}- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error{  NSLog(@"webview加载失败");}- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{  NSLog(@"开始重定向的函数");}- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler{  NSLog(@"2");  completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);}

iOS webView加载html5缓存

1.加载html5的过程

每次加载一个HTML5页面,都会有较多的请求。除了HTML主URL自身的请求外,HTML外部引用的JS、CSS、字体文件、图片都是一个独立的HTTP请求,每一个请求都串行的(可能有连接复用)。

2.设置清除html5页面缓存

html5端设置meta标签:

 

复制代码 代码如下:

<meta http-equiv="Pragma" content="no-cache" /><meta http-equiv="Cache-Control" content="no-cache" /><meta http-equiv="Expires" content="0" />

 

ios:设置加载的网络请求不采用本地缓存和远程缓存

iOS,webview加载缓存,wkwebview,加载缓存,webview加载时序

PS:设置上面的只是紧紧可以保证html文件每次从服务器中获取,不从缓存文件中拿,而对于外联CSS JS图片等文件仍旧是从缓存中获取的;

3.设置css JS文件不从缓存中读取

通过添加版本号的和随机数的方法,保证每次加载JS CSS连接都是最新的,通常的做法是添加一个版本号,在每次更新了JS CSS时给版本号+1;保证没有更新时采用缓存文件

有更新可以从服务中获取;

解决方法

1、随机数法

方法一:

document.write( " <script src='test.js?rnd= " + Math.random() + " '></s " + " cript> " )

方法二:

var js = document.createElement( " script " )js.src = " test.js " + Math.random()document.body.appendChild(js)

这样采用随机数的话, js文件将永远得不到缓存,每次都必须重新从服务器加载,即使没有任何更改。

大家如果经常上国外网站的话,可以看到他们通常采用这样的方式来解决:

<script src="test.js?ver=113"></script>

其中 ver=113 的 113就是版本号

这样真正做到了应该缓存的时候缓存静态文件,当版本有更新的时候从获取最新的版本,并更新缓存。

对于图像 <img src="test.jps?ver=版本号"> 来有效利用和更新缓存.

4.iOS清除缓存文件

- (void)removeWebCache{  if ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0) {    NSSet *websiteDataTypes= [NSSet setWithArray:@[                            WKWebsiteDataTypeDiskCache,                            //WKWebsiteDataTypeOfflineWebApplication                            WKWebsiteDataTypeMemoryCache,                            //WKWebsiteDataTypeLocal                            WKWebsiteDataTypeCookies,                            //WKWebsiteDataTypeSessionStorage,                            //WKWebsiteDataTypeIndexedDBDatabases,                            //WKWebsiteDataTypeWebSQLDatabases                            ]];        // All kinds of data    //NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];    NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];    [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{          }];    [[NSURLCache sharedURLCache] removeAllCachedResponses];      } else {    //先删除cookie    NSHTTPCookie *cookie;    NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];    for (cookie in [storage cookies])    {      [storage deleteCookie:cookie];    }        NSString *libraryDir = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];    NSString *bundleId = [[[NSBundle mainBundle] infoDictionary]                objectForKey:@"CFBundleIdentifier"];    NSString *webkitFolderInLib = [NSString stringWithFormat:@"%@/WebKit",libraryDir];    NSString *webKitFolderInCaches = [NSString                     stringWithFormat:@"%@/Caches/%@/WebKit",libraryDir,bundleId];    NSString *webKitFolderInCachesfs = [NSString                      stringWithFormat:@"%@/Caches/%@/fsCachedData",libraryDir,bundleId];    NSError *error;    /* iOS8.0 WebView Cache的存放路径 */    [[NSFileManager defaultManager] removeItemAtPath:webKitFolderInCaches error:&error];    [[NSFileManager defaultManager] removeItemAtPath:webkitFolderInLib error:nil];    /* iOS7.0 WebView Cache的存放路径 */    [[NSFileManager defaultManager] removeItemAtPath:webKitFolderInCachesfs error:&error];    NSString *cookiesFolderPath = [libraryDir stringByAppendingString:@"/Cookies"];    [[NSFileManager defaultManager] removeItemAtPath:cookiesFolderPath error:&error];    [[NSURLCache sharedURLCache] removeAllCachedResponses];  }}

关于保存在沙盒中的缓存文件如下图:

iOS,webview加载缓存,wkwebview,加载缓存,webview加载时序

iOS,webview加载缓存,wkwebview,加载缓存,webview加载时序

5.针对UIWebView出现的内存泄漏方法(网上)

  - (void)webViewDidFinishLoad:(UIWebView *)webView  {    //防止内存泄漏    [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"WebKitCacheModelPreferenceKey"];    //本地webkit硬盘图片的缓存;    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDiskImageCacheEnabled"];//自己添加的,原文没有提到。    //静止webkit离线缓存    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitOfflineWebApplicationCacheEnabled"];//自己添加的,,原文没有提到。    [[NSUserDefaults standardUserDefaults] synchronize];  }  - (void)dealloc  {    [webView loadHTMLString:@"" baseURL:nil];    [webView stopLoading];    [webView removeFromSuperview];    webView = nil;    [[NSURLCache sharedURLCache] removeAllCachedResponses];     [[NSURLCache sharedURLCache] setDiskCapacity:0];     [[NSURLCache sharedURLCache] setMemoryCapacity:0];     NSLog(@"释放了webview");  }  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{      int cacheSizeMemory = 4*1024*1024; // 4MB int           cacheSizeDisk = 32*1024*1024; // 32MB      NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"];     [NSURLCache setSharedURLCache:sharedCache];   }   - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {      [[NSURLCache sharedURLCache] removeAllCachedResponses];  }

PS:经测试好像没什么卵用,先放在这里反正写了也没什么坏处

确定

1.如果没有CDN缓存影响;每次杀死APP后重新进入,第一次加载webview,都会加载全部的数据资源(外联js,外联css,图片等)退出去后,如果在没有更新js,css内容时,默认只会加载html内容,PS:html中的内容 在每次加载webView中都会从服务器中更新一下;

2.如果js css后面都添加了版本号,那么在每次更新版本号时,或者说资源链接变化时,webView一定会重新加载新的内容;如下图

<script type="text/javascript" src="index1.js?v=1.0.0"></script>

疑问?

1.经测试发现,JS CSS没有加版本号,更新JS CSS的内容有时候也会及时从服务器中更新获取,大多数时候又不会更新;不知道是不是跟web服务器的缓存策略有关,还是文件超期了?还是CDN缓存有关?

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VEVB武林网。


注:相关教程知识阅读请移步到IOS开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表