Files
knowledge-kit/Chapter2 - Web FrontEnd/2.5.md
2020-02-25 17:46:51 +08:00

123 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# H5性能优化方面的探索
> H5很重要很重要很重要重要的事情必须重复多遍H5的优点跨平台、迭代快、开发体验好。缺点加载慢用户体验差。所以在接下来很长一段时间内我将会从H5的几个缺点发面去研究如何优化。
## 一、缓存问题及其解决办法
经常遇到一个问题H5页面由于缓存问题经常在H5发布新版本之后客户端App看不到最新的效果之前由于杂七杂八的问题项目工期紧没好好研究最近抽空研究了下缓存问题。
缓存问题具体表现为UIWebview首次打开加载慢第二次加载速度明显快H5资源更新过后在App上看不到更改的效果
为此我认为是缓存造成的问题我进入App目录下看到Library下的Caches下面有很多文件名称很长的文件点击预览可以看到是图片、css等本来我想着找出H5资源缓存到App中的特点然后用NSFileManager删除掉缓存文件发现此路不通。
#### 我想通过控制变量法研究缓存是否存在。
#### 做了一个实验。步骤如下:
* 用HBuilder一个编辑器开启后本机端口8020就可以访问网页打开H5工程
* 在App的一个UIWebview页面上通过和电脑在同一个局域网的方式加载网页
* 在App上查看效果观察某个元素的样式
* 在HBuilder编辑器中修改元素样式
* 在App上将UIWebView返回上一界面再次进入查看该元素的样式
* 确定有没有变化,来确定有没有缓存
结论:页面实时效果变化的,没有缓存
对比实验:
* 用HBuilder一个编辑器开启后本机端口8020就可以访问网页打开H5工程
* git提交到服务端
* 在App的一个UIWebview页面上通过公网IP的方式加载网页
* 在App上查看效果观察某个元素的样式
* 在HBuilder编辑器中修改元素样式
* git提交后发布到服务器上
* 在App上将UIWebView返回上一界面再次进入查看该元素的样式
* 确定有没有变化,来确定有没有缓存
结论页面没有看到最新的效果明显缓存了。但是我很想知道为什么本地局域网的方式请求网页不会缓存而通过公网IP的方式会缓存。
为此我做了进一步的实验用谷歌浏览器分别请求本地局域网和公网ip查看资源加载的情况。
1、公网IP
![公网IP
](/assets/屏幕快照 2017-09-15 下午5.56.28.png)
2、本地局域网
![本地局域网](/assets/屏幕快照 2017-09-15 下午6.27.16.png)
关键词Status Code
结论从图上可以看出本地局域网不管首次加载还是刷新都是直接请求而通过局域网的方式请求首次请求是从服务器上获取在此刷新的时候是从from memory cache中获取的。
#### 猜想
局域网 的方式网速都比较快所以不会缓存;
公网IP的方式可能由于网速问题会将首次请求到的资源缓存下来。
所以确定缓存存在了,那么如何避免缓存?
* App在启动后请求一个接口这个接口的目的是获取当前H5资源的版本号
* 将获得的版本号保存下来App本地保存
* 由于UIWebView上加载网页发起网络请求都可以通过一个代理方法所拦截所以我们可以在这个代理方法中判断url的参数可能是[http://www.a.com/login、http://www.a.com/login.html、http://www.a.com/login.html?name=geek、http://www.a.com/login\#readme等等所以我们判断过url后考虑如何将版本号加到url里面](http://www.a.com/login、http://www.a.com/login.html、http://www.a.com/login.html?name=geek、http://www.a.com/login#readme等等所以我们判断过url后考虑如何将版本号加到url里面)
* 由于我们的App使用了不同模块的UIWebView但是都是在UIWebView上需要大量的JS交互所以使用了WebViewJavascriptBridge这个库。UIWebView本身的代理方法不会执行所以修改这个库里面的WebViewJavascriptBridge.m文件的代码差不多是下面的方式
```
- (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 OKfrom cache 有的缓存是304 Not modified。如果运维移除了Entity Tag就一直是200from cache。如果没有移除的话2者是交替出现的。
为什么2者会有区别
* 200 OKfrom cache是直接点击链接或者在浏览器地址栏中输入网址敲回车键的结果
* 而304 modified是我们刷新了浏览器页面时触发或者设置了长缓存、但Entity Tags没有移除时触发
做了 实验得出结论:
* 直接访问有缓存的网站都触发 200 OK \(from cache\)
* 刷新浏览器则会触发304
* 同一域名下,没有 Entity Tag 的资源直接访问,是 200 OK \(from cache\) 的结果
* 同一域名下有Entity Tag 的资源直接访问是出现304 Not Modified