当前位置: 移动技术网 > IT编程>移动开发>IOS > 详解iOS webview加载时序和缓存问题总结

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

2019年07月24日  | 移动技术网IT编程  | 我要评论

梦特蓓妮,a.mimich.info,印度男吃砖头20年

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 uicollectionview实现横向滚动

    现在使用卡片效果的app很多,之前公司让实现一种卡片效果,就写了一篇关于实现卡片的文章。文章最后附有demo实现上我选择了使用uicollectionview ... [阅读全文]
  • iOS UICollectionView实现横向滑动

    本文实例为大家分享了ios uicollectionview实现横向滑动的具体代码,供大家参考,具体内容如下uicollectionview的横向滚动,目前我使... [阅读全文]
  • iOS13适配深色模式(Dark Mode)的实现

    iOS13适配深色模式(Dark Mode)的实现

    好像大概也许是一年前, mac os系统发布了深色模式外观, 看着挺刺激, 时至今日用着也还挺爽的终于, 随着iphone11等新手机的发售, ios 13系统... [阅读全文]
  • ios 使用xcode11 新建项目工程的步骤详解

    ios 使用xcode11 新建项目工程的步骤详解

    xcode11新建项目工程,新增了scenedelegate这个类,转而将原appdelegate负责的对ui生命周期的处理担子接了过来。故此可以理解为:ios... [阅读全文]
  • iOS实现转盘效果

    本文实例为大家分享了ios实现转盘效果的具体代码,供大家参考,具体内容如下demo下载地址: ios转盘效果功能:实现了常用的ios转盘效果,轮盘抽奖效果的实现... [阅读全文]
  • iOS开发实现转盘功能

    本文实例为大家分享了ios实现转盘功能的具体代码,供大家参考,具体内容如下今天给同学们讲解一下一个转盘选号的功能,直接上代码直接看viewcontroller#... [阅读全文]
  • iOS实现轮盘动态效果

    本文实例为大家分享了ios实现轮盘动态效果的具体代码,供大家参考,具体内容如下一个常用的绘图,主要用来打分之类的动画,效果如下。主要是ios的绘图和动画,本来想... [阅读全文]
  • iOS实现九宫格连线手势解锁

    本文实例为大家分享了ios实现九宫格连线手势解锁的具体代码,供大家参考,具体内容如下demo下载地址:效果图:核心代码://// clockview.m// 手... [阅读全文]
  • iOS实现卡片堆叠效果

    本文实例为大家分享了ios实现卡片堆叠效果的具体代码,供大家参考,具体内容如下如图,这就是最终效果。去年安卓5.0发布的时候,当我看到安卓全新的material... [阅读全文]
  • iOS利用余弦函数实现卡片浏览工具

    iOS利用余弦函数实现卡片浏览工具

    本文实例为大家分享了ios利用余弦函数实现卡片浏览工具的具体代码,供大家参考,具体内容如下一、实现效果通过拖拽屏幕实现卡片移动,左右两侧的卡片随着拖动变小,中间... [阅读全文]
验证码:
移动技术网