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

发布时间 - 2026-01-11 03:09:26    点击率:

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:设置加载的网络请求不采用本地缓存和远程缓存

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];
  }
}

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

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缓存有关?

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


# iOS  # webview加载缓存  # wkwebview  # 加载缓存  # webview加载时序  # iOS开发中WebView的基本使用方法简介  # IOS中UIWebView加载Loading的实现方法  # IOS中的webView加载HTML  # 轻松理解iOS 11中webview的视口  # iOS Webview自适应实际内容高度的4种方法详解  # ios开发加载webview显示进度条实例  # iOS 对当前webView进行截屏的方法  # iOS获取cell中webview的内容尺寸  # iOS去除Webview键盘顶部工具栏的方法  # 加载  # 随机数  # 都是  # 器中  # 不从  # 如下图  # 单线程  # 离线  # 会有  # 放在  # 也会  # 也没  # 没有任何  # 是从  # 只会  # 如果没有  # 能有  # 可以看到  # 较多  # 写了 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何操作JSON类型的数据库字段?(Eloquent示例)  Laravel API资源类怎么用_Laravel API Resource数据转换  Laravel模型关联查询教程_Laravel Eloquent一对多关联写法  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试  制作电商网页,电商供应链怎么做?  javascript中的try catch异常捕获机制用法分析  如何做网站制作流程,*游戏网站怎么搭建?  移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?  ,在苏州找工作,上哪个网站比较好?  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  百度输入法ai组件怎么删除 百度输入法ai组件移除工具  Laravel如何使用Blade模板引擎?(完整语法和示例)  Laravel如何处理和验证JSON类型的数据库字段  千问怎样用提示词获取健康建议_千问健康类提示词注意事项【指南】  JavaScript如何实现继承_有哪些常用方法  Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】  如何续费美橙建站之星域名及服务?  Laravel怎么解决跨域问题_Laravel配置CORS跨域访问  香港服务器建站指南:外贸独立站搭建与跨境电商配置流程  做企业网站制作流程,企业网站制作基本流程有哪些?  Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件  公司网站制作价格怎么算,公司办个官网需要多少钱?  如何打造高效商业网站?建站目的决定转化率  javascript事件捕获机制【深入分析IE和DOM中的事件模型】  Laravel怎么连接多个数据库_Laravel多数据库连接配置  如何基于PHP生成高效IDC网络公司建站源码?  如何在宝塔面板中修改默认建站目录?  Windows Hello人脸识别突然无法使用  如何在万网开始建站?分步指南解析  小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像  JavaScript如何实现路由_前端路由原理是什么  专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?  高端智能建站公司优选:品牌定制与SEO优化一站式服务  如何在 Pandas 中基于一列条件计算另一列的分组均值  如何在IIS中新建站点并配置端口与IP地址?  EditPlus 正则表达式 实战(3)  如何撰写建站申请书?关键要点有哪些?  敲碗10年!Mac系列传将迎来「触控与联网」双革新  软银砸40亿美元收购DigitalBridge 强化AI资料中心布局  如何快速生成可下载的建站源码工具?  如何确保FTP站点访问权限与数据传输安全?  HTML5空格和margin有啥区别_空格与外边距的使用场景【说明】  Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录  如何快速搭建高效WAP手机网站吸引移动用户?  利用vue写todolist单页应用  laravel怎么配置和使用PHP-FPM来优化性能_laravel PHP-FPM配置与性能优化方法  香港服务器选型指南:免备案配置与高效建站方案解析  Laravel Asset编译怎么配置_Laravel Vite前端构建工具使用  laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法