美文网首页good
iOS 提高WebView加载速度优化方案

iOS 提高WebView加载速度优化方案

作者: 马威明 | 来源:发表于2023-04-17 20:07 被阅读0次

背景

开发中 WebView是很常用的技术方案 相比native 也有着很明显的一些优点 如:
1、实现安卓 iOS的复用
2、不用发版 动态更新页面
3、节约native开发资源
......
但同时 也存在一些缺点 比较明显的就是 加载速度比较慢 用户体验不如native
所以 提高WebView的加载速度 提升用户体验是避不开的问题

WebView加载速度优化方案

一、WebView加载过程

想要优化WebView加载速度 首先需要了解下网页加载过程:
初始化webview -> 建立连接 -> 请求页面 -> 下载数据 -> 解析HTML -> 请求 js/css 资源 -> dom 渲染 -> 解析 JS 执行 -> JS 请求数据 -> 解析渲染 -> 下载渲染图片

二、WebView优化方案

1、提前初始化WebView
当App打开时,默认是并不初始化浏览器内核的;只有当创建WebView实例的时候,才会创建WebView的基础框架。
所以与浏览器不同,App中打开WebView的第一步并不是建立连接,而是启动浏览器内核。
提前初始化WebView可以节省这部分时间
提前初始化WebView分为两种情况
① 刚启动 还没打开过WebView
可以初始化一个全局单例WebView 在APP刚启动时就初始化 打开具体页面是都复用这同一个WebView
这种方式存在的一个缺点就是如果用户不打开WebView 会造成资源的浪费
② 每次打开WebView时 如果之前没有打开过 把当前WebView存到内存中 下次打开 直接取出来使用

根据url取出WebView
③ 对于确定性比较高的常用网页 可以在启动时直接保存到内存 用户打开时就可以直接显示
根据url预加载WebView
2、预存HTML到本地
APP启动时预存HTML到本地 打开WebView准备加载HTML文件时 WKURLSchemeHandler 拦截请求资源判断资源是否和本地资源一致(一致则返回本地资源文件,不一致则请求网络资源)
这种预存方式不能处理Http、Https等常规scheme 本地资源不存在时 请求网络资源时 可能需要主动转换成http/https
- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask {
    self.holdUrlSchemeTasks[urlSchemeTask.description] = @(YES);
    /// 优先加载本地资源,本地没有加载网络资源化
    NSString *urlString = urlSchemeTask.request.URL.absoluteString;
    NSString *fileName = [urlString lastPathComponent];
    NSString *markStrig = [NSString stringWithFormat:@"%@/",NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject];
    NSRange range = [urlString rangeOfString:markStrig];
    if (range.location != NSNotFound) {
        fileName = [urlString substringFromIndex:range.location];
    }
    NSString *mainBundlePath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
    NSString *htmlPath = [mainBundlePath stringByAppendingFormat:@"/"];
    NSString *filePath = [htmlPath stringByAppendingFormat:@"%@",fileName];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    /// 判断文件是否存在
    if ([fileManager fileExistsAtPath:filePath]) {
        NSData *data = [NSData dataWithContentsOfFile:filePath];
        NSURLResponse *response = [[NSURLResponse alloc] initWithURL:urlSchemeTask.request.URL MIMEType:@"text/html" expectedContentLength:data.length textEncodingName:nil];
        [urlSchemeTask didReceiveResponse:response];
        [urlSchemeTask didReceiveData:data];
        [urlSchemeTask didFinish];
    } else {
        NSString *schemeUrl = urlSchemeTask.request.URL.absoluteString;
        if ([schemeUrl hasPrefix:@"qekj"]) {
            schemeUrl = [schemeUrl stringByReplacingOccurrencesOfString:@"qekj" withString:@"http"];
        }
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:schemeUrl]];
        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
        NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
        NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSNumber *number = self.holdUrlSchemeTasks[urlSchemeTask.description];
                BOOL flag = number.boolValue;
                if (flag == NO) {
                    return;
                }
                if (response) {
                    [urlSchemeTask didReceiveResponse:response];
                } else {
                    NSURLResponse *response = [[NSURLResponse alloc] initWithURL:urlSchemeTask.request.URL MIMEType:@"未知类型" expectedContentLength:data.length textEncodingName:nil];
                    [urlSchemeTask didReceiveResponse:response];
                }
                [urlSchemeTask didReceiveData:data];
                if (error) {
                    [urlSchemeTask didFailWithError:error];
                } else {
                    [urlSchemeTask didFinish];
                }
            });
        }];
        [dataTask resume];
    }
}
处理自定义请求的方案
scheme替换
3、H5的css、js文件、图片资源压缩处理
这个需要H5同学帮助
H5的css、js文件压缩方案
4、js、css、image等资源进行离线缓存
WKWebView是有缓存策略模式的 通常情况下 我们是关闭缓存的 不然可能会出现数据不能及时更新的问题
如果开启了本地缓存配置 建议H5链接增加一个类似于版本号的标识 如果内容有更新 则版本号+1 WKWebView的缓存是通过urlString来判断是否需要重新加载 版本号变化 会认为是新的网页 则会重新加载
WKWebView默认缓存策略

参考

支付宝移动端动态化方案实践
Web离线技术
WKURLSchemeHandler协议优化HTML加载速度
iOS WebView的性能、体验优化
移动 H5 首屏秒开优化方案探讨
iOS html5使用缓存并及时更新方案总结

相关文章

  • Android webview提升打开速度方案

    前言 为了提高WebView的加载速度,提升用户体验,WebView优化方案如下:思路:让WebView打开时加载...

  • WebView的使用

    WebView的基本使用 WebView的中级使用 WebView的高级使用 优化网页加载速度 Android和JS交互

  • WebView加载速度优化

    在做混合应用的时候,有几个痛点,一个是无网络无法使用,还有一个是受网络环境影响的网页加载速度。今天就这两个问题,和...

  • Android WebView 优化梳理

    1.针对加载webView中的资源时加快加载的速度优化(主要是针对图片)原因:html代码下载到WebView后,...

  • 使用WKWebView替换UIWebView

    在iOS开发APP的过程中,我们都是用webview来完成一些网页HTML、JS的加载,webview加载速度慢,...

  • webview加载速度优化实践

    1,以内存换时间 全局保持一个webview列表,每次打开Activity都会加载

  • 20-IOS图片加载优化方案

    iOS图片加载速度极限优化—FastImageCache解析 2015-2-9

  • Android WebView 优化梳理

    作者:Mino 1.针对加载webView中的资源时加快加载的速度优化(主要是针对图片) 原因:html代码下载到...

  • Android 缓存方案探究&实践

    网上看了很多的WebView缓存的文章,做了个H5缓存的方案,提高H5体验,提升H5加载 速度。主要部分为缓存和文...

  • UIWebView相关网站

    加载webView 内存泄露 导致内存暴涨的几种解决方案 http://blog.csdn.net/ios_pop...

网友评论

    本文标题:iOS 提高WebView加载速度优化方案

    本文链接:https://www.haomeiwen.com/subject/wodcjdtx.html