iOS webview加載時序和緩存問題總結

iOS webView的加載時序

UIWebView加載順序:javascript

- (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加載失敗"); }

加載的結果:css

  1. 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加載時序:html

- (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請求,每個請求都串行的(可能有鏈接複用)。html5

2.設置清除html5頁面緩存java

  html5端設置meta標籤:ios

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

  ios:設置加載的網絡請求不採用本地緩存和遠程緩存web

  PS:設置上面的只是牢牢能夠保證html文件每次從服務器中獲取,不從緩存文件中拿,而對於外聯CSS JS圖片等文件仍舊是從緩存中獲取的;緩存

3.設置css JS文件不從緩存中讀取服務器

  經過添加版本號的和隨機數的方法,保證每次加載JS CSS鏈接都是最新的,一般的作法是添加一個版本號,在每次更新了JS CSS時給版本號+1;保證沒有更新時採用緩存文件cookie

有更新能夠從服務中獲取;

解決方法

一、隨機數法
方法一:
  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緩存有關? 

相關文章
相關標籤/搜索