移动端web缓存,优化第二次访问速度
lanjingling0510 opened this issue · 0 comments
移动端带宽流量要比pc端宝贵的多, 200k的资源在pc端毫无压力,但在不稳定的移动3g下,需要1s中左右。Wi-Fi情况下网络延迟很大,达到200-400ms,直接结果就是304或者200情况下css,js加载很慢,加大白屏时间。
当前问题是如何缓存webpack打包的bundle js文件,提高移动端第二次访问速度?
探索方案一:service worker cache
缓存是service worker做得很好的事情之一,要安装 service worker ,你需要在你的页面上注册。下面的代码会告诉浏览器你的 service worker 脚本在哪里。
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js').then(() => {
console.log('Service worker registered!');
}).catch((error) => {
console.log('Error registering service worker: ', error);
});
} else {
console.log('Not supported by browser');
}
通过webpack.config.js配置,添加sw-precache-webpack-plugin插件
new SWPrecacheWebpackPlugin(
{
cacheId: 'cqaso-web-mobile',
filename: 'service-worker.js',
verbose: true,
}
)
SWPrecacheWebpackPlugin是一个webpack插件,用于使用service worker来缓存外部项目依赖项。 它将使用sw-precache生成service worker文件并将其添加到您的构建目录。为了在service worker中生成预缓存的名单, 这个插件必须应用在assets已经被webpack打包之后。
然而,这个方案只能在HTTPS协议中应用,http不能生效。
探索方案二: html5离线应用缓存
离线访问对基于网络的应用而言越来越重要。虽然所有浏览器都有缓存机制,但它们并不可靠,也不一定总能起到预期的作用。HTML5 使用 ApplicationCache 接口解决了由离线带来的部分难题。
使用缓存接口可为您的应用带来以下三个优势:
- 离线浏览 - 用户可在离线时浏览您的完整网站
- 速度 - 缓存资源为本地资源,因此加载速度较快。
- 服务器负载更少 - 浏览器只会从发生了更改的服务器下载资源。
应用缓存(又称 AppCache)可让开发人员指定浏览器应缓存哪些文件以供离线用户访问。即使用户在离线状态下按了刷新按钮,您的应用也会正常加载和运行。
通过webpack.config.js配置,添加appcache-webpack-plugin插件
var AppCachePlugin = require('appcache-webpack-plugin');
module.exports = {
plugins: [
new AppCachePlugin({
network: null, // No network access allowed!
fallback: [],
settings: ['prefer-online'],
exclude: [], // Exclude file.txt and all .js files
output: 'my-manifest.appcache'
})
]
}
要启用某个应用的应用缓存,请在文档的 html 标记中添加 manifest 属性:
<html manifest="my-manifest.appcache">
...
</html>
鉴于项目的实时性比较强,大部分已实时数据渲染为主,离线缓存并没有什么价值。
探索方案三: LocalStorage本地缓存
基本原理就是使用md5版本号+localStorage,把静态文件存储在浏览器本地数据,利用js控制js的加载运行。
配置webpack, 提取入口文件公共chunks, 只要chunks内容不变,打包后的chunks代码就不会改变,md5文件名就不会变。
new webpack.optimize.CommonsChunkPlugin({
name: [
'vendor', 'manifest'
], // vendor libs + extracted manifest
minChunks: Infinity
}),
new webpack.HashedModuleIdsPlugin(),
new WebpackChunkHash(),
通过webpack的html-webpack-plugin插件,配置ejs模板, 使用lsLoader.js异步请求js文件,顺序运行,存储到localstorage中,第二次访问直接从localstorage运行。版本更新后,md5文件名变化的从新请求,更新相应的localstorage。
<script src="/lsLoader.js"></script>
<!-- lsLoader加载chunks -->
<script type="text/javascript">
lsloader.load("manifest", "<%= htmlWebpackPlugin.files.chunks['manifest'].entry %>");
lsloader.load("vendor", "<%= htmlWebpackPlugin.files.chunks['vendor'].entry %>");
lsloader.load("main", "<%= htmlWebpackPlugin.files.chunks['main'].entry %>");
</script>
3G网下缓存前和缓存后的访问速度对比
3G网下毫无压力,该方案兼容良好