Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
、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小時內與您取得聯系。