H5性能优化方面的探索

H5性能优化方面的探索

H5很重要,很重要,很重要,重要的事情必须重复多遍,H5的优势:跨平台、迭代快、开发体验好。缺点:加载慢,用户体验差。因此在接下来很长一段时间内我将会从H5的几个缺点发面去研究如何优化。css

1、缓存问题及其解决办法

常常遇到一个问题,H5页面因为缓存问题常常在H5发布新版本以后客户端App看不到最新的效果,以前因为杂七杂八的问题项目工期紧没好好研究,最近抽空研究了下缓存问题。html

缓存问题具体表现为:UIWebview首次打开加载慢;第二次加载速度明显快;H5资源更新事后在App上看不到更改的效果git

为此我认为是缓存形成的问题,我进入App目录下,看到Library下的Caches下面有不少文件名称很长的文件,点击预览能够看到是图片、css等,原本我想着找出H5资源缓存到App中的特色,而后用NSFileManager删除掉缓存文件,发现此路不通。web

我想经过控制变量法研究缓存是否存在。

作了一个实验。步骤以下:

  • 用HBuilder(一个编辑器,开启后本机端口8020就能够访问网页)打开H5工程
  • 在App的一个UIWebview页面上经过和电脑在同一个局域网的方式加载网页
  • 在App上查看效果,观察某个元素的样式
  • 在HBuilder编辑器中修改元素样式
  • 在App上将UIWebView返回上一界面,再次进入查看该元素的样式
  • 肯定有没有变化,来肯定有没有缓存

结论:页面实时效果变化的,没有缓存浏览器

对比实验:缓存

  • 用HBuilder(一个编辑器,开启后本机端口8020就能够访问网页)打开H5工程
  • git提交到服务端
  • 在App的一个UIWebview页面上经过公网IP的方式加载网页
  • 在App上查看效果,观察某个元素的样式
  • 在HBuilder编辑器中修改元素样式
  • git提交后发布到服务器上
  • 在App上将UIWebView返回上一界面,再次进入查看该元素的样式
  • 肯定有没有变化,来肯定有没有缓存

结论:页面没有看到最新的效果,明显缓存了。可是我很想知道为何本地局域网的方式请求网页不会缓存,而经过公网IP的方式会缓存。性能优化

为此,我作了进一步的实验,用谷歌浏览器分别请求本地局域网和公网ip查看资源加载的状况。服务器

一、公网IP 网络

二、本地局域网运维

关键词Status Code

结论:从图上能够看出本地局域网无论首次加载仍是刷新都是直接请求;而经过局域网的方式请求:首次请求是从服务器上获取,在此刷新的时候是从(from memory cache)中获取的。

猜测

局域网 的方式网速都比较快因此不会缓存;

公网IP的方式可能因为网速问题会将首次请求到的资源缓存下来。

因此肯定缓存存在了,那么如何避免缓存?

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    if (webView != _webView) { return YES; }
    NSURL *url = [rntity Tag 的资源直接访问equest URL];
    if ([request.URL.absoluteString containsString:@"http"] || [request.URL.absoluteString containsString:@"https"]) {
        if ([request.URL.absoluteString containsString:@"?"]) {
            url = [NSURL URLWithString:[NSString stringWithFormat:@"%@&h5V=%@",request.URL.absoluteString,[ProjectUtil getH5VersionString]]];
        }else{
            url = [NSURL URLWithString:[NSString stringWithFormat:@"%@?h5V=%@",request.URL.absoluteString,[ProjectUtil getH5VersionString]]];
        }
    }
    LBPLOG(@"url->%@",[url absoluteString]);
    __strong WVJB_WEBVIEW_DELEGATE_TYPE* strongDelegate = _webViewDelegate;
    if ([_base isCorrectProcotocolScheme:url]) {
        if ([_base isBridgeLoadedURL:url]) {
            [_base injectJavascriptFile];
        } else if ([_base isQueueMessageURL:url]) {
            NSString *messageQueueString = [self _evaluateJavascript:[_base webViewJavascriptFetchQueyCommand]];
            [_base flushMessageQueue:messageQueueString];
        } else {
            [_base logUnkownMessage:url];
        }
        return NO;
    } else if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) {
        return [strongDelegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType];
    } else {
        return YES;
    }
}

总结:

App的缓存问题暂时研究到这里,后期会继续研究其余方面的问题

拓展

经过浏览器咱们知道有的缓存是200 OK(from cache ),有的缓存是304 Not modified。若是运维移除了Entity Tag就一直是200(from cache)。若是没有移除的话2者是交替出现的。

为何2者会有区别?

  • 200 OK(from cache)是直接点击连接或者在浏览器地址栏中输入网址敲回车键的结果
  • 而304 modified是咱们刷新了浏览器页面时触发或者设置了长缓存、但Entity Tags没有移除时触发

作了 实验得出结论:

  • 直接访问有缓存的网站都触发 200 OK (from cache)

  • 刷新浏览器则会触发304

  • 同一域名下,没有 Entity Tag 的资源直接访问,是 200 OK (from cache) 的结果

  • 同一域名下,有Entity Tag 的资源直接访问,是出现304 Not Modified