webpack 集成 basket.js 实现 localStorage 本地缓存
basket.js 是什么
basket.js 可以用来加载 js 和 css 脚本并且保存到 LocalStorage
上,使我们可以更加精准地控制缓存,即使是在 http 缓存过期之后也可以使用。因此可以使我们防止不必要的重新请求 js 脚本,提升网站加载速度。
basket.js 的简单使用方式
basket.require({url: 'helloworld.js'});
和浏览器缓存相比的优势
在 PC 端和浏览器缓存相比没有任何优势,移动端 SPA 值得尝试。
(特别是在某信的 WebView 里,304 缓存的时间短如小香菇 2333)
以下总结来自某乎:
PC 上应用价值不大的原因在于:
- 兼容性不太好,不支持 LS 的浏览器比例仍然很大
- 网络速度快,协商缓存响应快,LS 读取 + eval 很多时候会比不上 304
- 通常需要 SEO,导致 css 不能缓存,仅缓存 js 使得整个缓存方案意义进一步减小
- 浏览器本地缓存足够可靠持久
- 跨页面间共享缓存即便有浪费也差别不大
移动端 webapp 值得一试的原因在于:
- 兼容性好
- 网速慢,LS 读取 + eval 大多数情况下快于 304
- 都说是 webapp 了,不需要 seo,css 也可以缓存,再通过 js 加载
- 浏览器缓存经常会被清理,LS 被清理的几率低一些
- 以模块文件为单位,缓存失效率低
- 不同页面状态直接访问、二次访问、页面状态跳转资源组合是不确定的,不能通过 url 来缓存资源,否则就不 “增量” 啦
暗中观察
以最常见的 vue-cli
来举例(PS:虽然不用 Vue,但是它的 webpack 配置还行,直接抄了),默认会打包出以下几个 js 文件,在 Chrome 的 network
选项卡中可以看到加载过程。
改造 HtmlWebpackPlugin 的模板文件
在 ejs 模板中加入以下代码, keys
数组可能需要对应自己的 entry
名来修改。
<% if (process.env.NODE_ENV === 'production') { %>
<script src="<%=htmlWebpackPlugin.files.publicPath %>basket.full.min.js"></script>
<script>
<%
var resources = [];
var keys = ["manifest", "vendor", "main"];
// css
for (var css in htmlWebpackPlugin.files.css) {
resources.push({
url: htmlWebpackPlugin.files.css[css],
execute: false
});
}
// js
var i = -1;
for (var chunk in htmlWebpackPlugin.files.chunks) {
i++;
resources.push({
url: htmlWebpackPlugin.files.chunks[chunk].entry,
execute: true
});
}
%>
(function(b) {
b.require.apply(this, <%=JSON.stringify(resources) %>)
.then(function(responses) {
responses.forEach(function(response) {
if (!response.execute) {
var style = document.createElement('style');
style.innerHTML = response.data;
var head = document.getElementsByTagName('head')[0];
head.appendChild(style);
}
});
});
})(basket);
</script>
<% } >
webpack 配置文件也需要相应修改,因为没有用到 CDN 上的 basket.full.min.js
,所以就自己本地托管吧。
使用 CopyWebpackPlugin
把 node_modules
目录中的 js 复制到打包目录下:
new CopyWebpackPlugin([
{
from: path.join(__dirname, 'node_modules/basket.js/dist/basket.full.min.js'),
to: path.join(__dirname, 'dist')
}
])
同时 HtmlWebpackPlugin
中 inject
选项需要设置为 false
,这样打包的时候就不会在 index.html
中置入 <script>
标签啦~(≧▽≦)/~。
大成功
重新打包编译,打开浏览器测试,可以看到结果。 basket.js
会以 ajax 的形式调用这些静态文件并缓存到 LocalStorage
里。
再次刷新页面,就不会有这些请求~(≧▽≦)/~ 啦。