UIWebView 离线缓存和提升加载速度

RNCachingURLProtocol

参考文章:Drop-in Offline Caching for UIWebView (and NSURLProtocol)

能干什么事

  • 缓存网页里的图片
  • 连线的时候,缓存请求
  • 离线的时候,显示最近一次的内容

怎么用

RNCachingURLProtocol 继承于 NSURLProtocol。每次下载 URL 后,都会 cache 到硬盘。cache 方式是 archive 内容到 Library/Caches 目录下。当我们想用的时候,就从这个目录下读取内容。

RNCachingURLProtocol cache 了所有的 HTTP/HTTPS traffic。这个库里只是对 http 进行了 cache,我们想要对 https cache的话,需要在 RNCachingURLProtocol - initialize 里修改支持的 scheme。

使用方法很简单:

  • 导入 RNCachingURLProtocol 到工程内。
  • 在 AppDelegate 的 didFinishLaunchingWithOptions 里注册:[NSURLProtocol registerClass:[RNCachingURLProtocol class]];

然后,你就可以愉快的体验离线缓存了。

提升首次进入网页时的加载速度

无论是冷启动还是热启动,我们都想要快的打开APP,将内容瞬间展示给用户。

而当首页是UIWebView的时候,这个效果就大打折扣了。尤其,当CSS、JS多切复杂的时候。

如果能在首次进入的时候,显示本地缓存的网页,而不是走网络交互,那么速度会有很大的提升。就是用这种办法来变相的提高首次进入时的加载速度的。

当然,还有其他的方法,比如合理优化网页结构、增加CDN提升网站访问速度啊什么的,但是对于我们来说这些都是不可控的,同时也非一时之功。

大体上是当启动App的时候,WebView 加载本地缓存的请求。然后进入网页后,之后所有的操作都是走的服务器的数据,而不再走本地缓存。

具体如下:

  • 在 didFinishLaunchingWithOptions 进行判断
    • 首次安装,WebView 从服务器加载 URL
    • 非首次安装,WebView 从 Cache 加载 URL
  • 在 WebView 加载成功代理 webViewDidFinishLoad 中
    • 设定之后的请求不在走缓存
  • 在 WebView 加载失败代理 didFailLoadWithError 中
    • 设定之后的请求不在走缓存
    • WebView 从新加载一次URL

AppDelegate.m 里

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [self handleNewVersionWithBlock:^(BOOL newVersion) {
        if (newVersion) {
            [RNCachingCustomStatus shared].loadFromCache = NO;
        } else {
            [RNCachingCustomStatus shared].loadFromCache = YES;
        }
    }];
    [NSURLProtocol registerClass:[RNCachingURLProtocol class]];
    return YES;
}

ViewController.m 里

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    CFAbsoluteTime endTime = (CFAbsoluteTimeGetCurrent() - self.startTime);
    NSLog(@"endTime in %f ms", endTime *1000.0);
    [RNCachingCustomStatus shared].loadFromCache = NO;
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
    // 当 cache 被清除后,通过 RNCachingURLProtocol 加载URL会失败,需要在这里进行处理
    [RNCachingCustomStatus shared].loadFromCache = NO;
    NSString *url =  @"https://0.u.7518.cn/";
    [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
}

这样做的结果:

  • 处理之前平均进入一次首页要2.4秒左右
  • 处理之后平均进入一次首页只需要1.5秒左右

效果提升的还是很大的。

Demo

你可能感兴趣的:(UIWebView 离线缓存和提升加载速度)