、html页面会缓存吗?
单纯的html页面不会缓存,htm是一种标记语言,用来描述和标记的,不能实现缓存。html里面的JavaScript代码是当这个html页面加载时浏览器解释执行,也不可以实现数据缓存。
二、html 页面怎么对缓存进行设置
根据服务器系统环节的不同设置方法不一样
1、在Apache环境下
可以通过在.htaccess文件中添加下面的代码,设置图片的HTTP缓存和有效期(需要开启apache的headers模块支持):
其中max-age后面这个数字就是设置的缓存有效期(以秒为单位),比如上面的代码设置了网站的图片使用为期一年(秒)的HTTP缓存。
2、在Nginx下
可以通过修改nginx.conf配置文件,来修改缓存设置:
location~*\.(flv|gif|jpg|jpeg|png|ico|swf)${;access_logoff;break;}
注意:同样的方法,可以给js和css文件设置缓存。
html缓存:html5 应用程序缓存和浏览器缓存有什么区别
应用程序缓存是会预加载的,保证齐全地供应和保存。浏览器缓存没有这些控制,不能作为程序缓存使用。不幸地,应用程序缓存过於简单,导致效率不彰,预期将会被ServiceWorker取代。
存是个老生长谈的问题,对于前端工程师来讲更是我们的必修课。或许很多人会说我的项目并没有问题,根本不需要聊什么缓存。如果真的是这样,只能证明你前端道路才刚刚开始。
小郭今天分享缓存的原因在于:公司的一个核心APP中嵌入了SPA,而且应用核心都分布在SPA中,功能复杂且重。问题出现了:应用核心页面打开一直处于加载状态,排除掉弱网环境的原因,重点就在于没有缓存,每次进入页面都需要重载DOM和数据,拖慢页面打开速度。
那应该处理缓存问题呢?接下来小郭从三个方向来讲解。
在了解浏览器缓存前,我们需要先了解一下相关的概念:cache-control,expires,last-Modified,ETag。
浏览器通过请求头实现缓存,关键的请求头有cache-control,expires,last-Modified,ETag等。我们从时间和空间两个角度来看浏览器缓存。
时间
浏览器发送第一次请求:不缓存,服务端根据设定的缓存策略返回相应的header,如:cache-control,expires,last-Modified,ETag。
浏览器发送第二次请求:
空间
如果缓存就按理论上设置,那就太简单了。在实际应用有个严重的问题,我们不仅要缓存代码,还需要更新代码。如果静态资源名字不变,怎么让浏览器即能缓存又能在有新代码时更新。最简单的解决方式就是静态资源路径添加一个版本值,版本不变就走缓存策略,版本变了就加载新资源。如下:
<script src="xx/xx.js?v=24334452"></script>
然而这种处理方式在部署时有问题。
解决方法:静态资源和页面是分开部署
这些问题的本质是以上的部署方式是“覆盖式发布”,解决方式是“非覆盖式发布”。即用静态资源的文件摘要信息给文件命名,这样每次更新资源不会覆盖原来的资源,先将资源发布上去。这时候存在两种资源,用户用旧页面访问旧资源,然后再更新页面,用户变成新页面访问新资源,就能做到无缝切换。简单来说就是给静态文件名加hash值。
那如何实现呢?
现在前端代码都用webpack之类的构建工具打包,那么结合webpack该怎么做,怎么才能做到持久化缓存?
一、webpack给文件名添加hash值是很简单的,但hash/chunkhash/contenthash要用哪个呢?
官方定义
hash: unique hash generated for every build
chunkhash: hashes based on each chunks' content
contenthash: hashes generated for extracted content
根据分析,contenthash才是我们需要的,内容有更新,hash值才会更新。
二、webpack会打包业务代码、第三方库及运行时代码,为保证缓存互不干扰,应该将它们提取出来。
第三方库提取方式是设置optimization的splitChunks的cacheGroups。splitChunks能提取模块,cacheGroups能缓存模块,并且cacheGroups的配置会覆盖splitChunks相同配置,既能提取又能缓存,故只需设置cacheGroups。
运行时代码的提取方式为配置runtimeChunk,默认为false,表示运行时代码嵌入到不同的chunk文件中;现在将运行时代码提取出来,并命名为manifest。
module.exports = {
entry: {
index: "./src/index.js",
bar: "./src/bar.js"
},
output: {
filename: "[name].[contenthash].js"
},
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test:/[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "all"
}
}
},
runtimeChunk: {
name: "manifest"
}
}
};
三、 moduleName 和 chunkName 对文件的影响
module:就是js模块
chunk:webpack编译过程中由多个module组成的文件
bundle:bundle是chunk文件的最终状态,是webpack编译后的结果
一个文件被分离为3个文件,文件间怎么相互依赖的,会影响彼此打包,解决方法是将moduleId和chunkId改成按照文件路径生成。
optimization: {
moduleIds: 'hashed',
namedModules: true,
namedChunks: true
}
这样子moduleId在编译后的文件是文件目录的hash值,更加安全。这也是namedChunks在production默认为false的原因,不想依赖的文件路径在编译后的文件直接展示,但是为了持久性缓存,这里也只能打开。
四、CSS文件缓存
当css代码提取成单独文件,当我们改变css时,怎么保证不影响引用它的js文件呢?配置如下:
plugins: [
new MiniCssExtractPlugin({
filename: "[contenthash].css"
})
]
webpack持久化缓存目标是当且仅当该文件内容变动才改变该文件名字的hash值
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
output: {
filename: [name].[contenthash].js, // 让hash值只在内容变动时更新
chunkFilename: [name].[contenthash].js // 动态引入的模块命名,同上
},
module: {
rules: [ {
test: /\.css$/,
use: [
"loader: MiniCssExtractPlugin.loader", // 提取出来css "css-loader"
]
} ]
},
optimization: {
moduleIds: "hashed", // 混淆文件路径名
runtimeChunk: { name: 'manifest' }, // 提取runtime代码命名为manifest
namedModules: true, // 让模块id根据路径设置,避免每增加新模块,所有id都改变,造成缓存失效的情况
namedChunks: true, // 避免增加entrypoint,其他文件都缓存失效
cacheGroups: {
vendor: { // 提取第三方库文件
test: /[\\/]node_modules[\\/]/,
name: 'vendors', chunks: 'all',
},
},
}
plugins: [
new webpack.HashedModuleIdsPlugin(), // 与namedModules: true作用一样
new MiniCssExtractPlugin({
filename: "[contenthash].css", // css文件也是按contenthash命名
chunkFilename: "[contenthash].css", // 动态引入的css命名,同上
})
],
}
浏览器有其缓存机制,想要既能缓存又能在部署时没有问题,需要给静态文件名添加hash值。在webpack中,有些配置能让我们实现持久化缓存。感兴趣的同学可以自行去测试哦!
有任何问题可以在下方留言,想了解更多前端知识欢迎关注公众号“一郭鲜”,文章也将同步于公众号,前端学习不迷路
用场景:
无论我们用PC端浏览网站还是用的移动端,网站都会缓存一些CSS,JS等文件。尤其是JS,我们常会写些代码,我之前曾在苹果手机上多番尝试都没办法清除缓存的文件。后面通过在JS后面增加版本号即可解决问题。
那么,我们先来看看重现问题,我们写的JS引用,如下图:
以上是没有版本号的,如果你修改了tool.min.js文件,并上传到服务器。刷新该页面后,仍然对新修改的不会有任何响应,因为缓存了。
解决办法:
在后面加上?V=xxx,版本号,那么浏览器就会把它当作一个新的文件,重新加载,如下图:
当然,我们作为一些长期维护的网站,我们的版本号很可能更多的是这样:
<script type="text/javascript" src="https://acstatic-dun.126.net/tool.min.js?v=2022031701"></script>
其中:
1)20220317代表的是今天的日期
2)最后两位数字代码的是当天更新的第几次。
这样做了之后,无论我们在移动端还是PC端就不会出现缓存的现象。
当然缓存这块完全看浏览器,不排除有些浏览器仍然没生效,那就只有清除浏览器缓存了。
不过怎么主流的IE浏览器,微信浏览器,GOOGLE器不会出现这个问题。
欢迎加我,一起分享开发的思路与代码
*请认真填写需求信息,我们会在24小时内与您取得联系。