浏览器缓存机制导致的白屏问题解决
创作时间:
作者:
@小白创作中心
浏览器缓存机制导致的白屏问题解决
引用
CSDN
1.
https://blog.csdn.net/Andrew_Chenwq/article/details/145636752
项目部署更新后,用户反应长时间白屏,多次刷新后仍然白屏。本文将详细介绍如何排查和解决这一问题,重点讨论了通过Nginx配置和代码层面的解决方案。
问题描述
项目部署更新后,用户反应长时间白屏,多次刷新后仍然白屏。
问题排查
用户那边多次刷新后仍然白屏无法显示,首先可以排除网络问题导致的加载缓慢,其次部署后我访问是正常的,也可以排除代码报错导致的白屏原因(react项目若没有做错误边界处理,JS发生错误也会使其白屏), 那么问题其实很明显了就是资源文件的错误加载导致无法正常渲染。
解决方案
注意: 一般普通用户的浏览器缓存是默认开启的,开发中我们防止缓存带来的更新延时,一般会自行关闭,但用户不是开发,是无法做到让每个用户去关闭缓存的,也不建议关闭缓存,因为缓存可以加快页面加载速度,提升用户体验,所以我们需要找到一种方法,既能保证用户访问时加载最新的资源文件,又能保证用户访问时加载的index.html是最新的,而不是缓存中的index.html。
- 利用nginx禁止index.html缓存,因为index.html是入口文件,若缓存了,那么即使资源文件更新了,用户访问的也是旧的资源文件,依旧导致白屏。
// nginx配置
server {
location / {
# 对 HTML 文件设置不缓存
if ($request_filename ~* .*\.(html|htm)$) {
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires 0;
}
# 带哈希的静态资源长期缓存
if ($request_filename ~* .*\.(css|js|png|jpg|jpeg|gif|ico|webp|svg)$) {
expires 365d;
add_header Cache-Control "public, immutable";
}
try_files $uri $uri/ /index.html;
}
}
// vite.config.ts
build: {
rollupOptions: {
output: {
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[name]-[hash].[ext]',
manualChunks(id) {
if (id.includes('node_modules')) {
return id.toString().split('node_modules/')[1].split('/')[0].toString();
}
},
},
},
},
这个方法是最高效的,即保留了了浏览器缓存,又避免了index.html缓存带来的问题。
- 奈何我司运维不肯配合,只能采用第二种方案,在代码中监听资源文件的加载情况,若加载失败则强制刷新并清空缓存。
注意: 这里的刷新不是简单的刷新页面,而是强制刷新,即强制清除缓存,重新加载资源文件。
强制刷新清空缓存有以下几种方式
一. 利用window.location.reload(true)方法,当设置为’true’时,浏览器会绕过缓存,从服务器重新加载页面,不过这个参数存在浏览器兼容问题,可以排除。
二. 利用meta的特性, 但是某些浏览器可能不完全遵循 HTML 中的 http-equiv 缓存指令,服务器响应头始终优先级更高。
<!-- 在 HTML 头部添加 -->
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
三. 最后,最简单请求的URL后面加上时间戳,这样每次请求的URL都是不同的,浏览器就不会缓存了。
window.location.href = window.location.href.split('?')[0] + '?ts=' + Date.now();
完整代码
// App.tsx
...
import { useEffect } from 'react';
function App() {
// 监听白屏
// 1. 利用addEventListener监听error事件,当资源文件加载失败时,强制刷新页面
useEffect(() => {
window.addEventListener(
'error',
(event) => {
const target = event.target as Element | null;
if (target && (target.tagName === 'SCRIPT' || target.tagName === 'LINK')) {
window.location.href = window.location.href.split('?')[0] + '?ts=' + Date.now();
}
},
true,
);
// 2.也可以利用性能监控这个API,监听资源加载情况,当资源加载失败时,强制刷新页面
// const resourceObserver = new PerformanceObserver((list) => {
// list.getEntries().forEach((entry) => {
// console.log(entry, 'eeeee');
// if (entry.entryType === 'resource' && entry.duration === 0 && entry.transferSize === 0) {
// window.location.href = window.location.href.split('?')[0] + '?ts=' + Date.now();
// }
// });
// });
// // 启动监听
// resourceObserver.observe({ entryTypes: ['resource'] });
return () => window.removeEventListener('error', () => {});
}, []);
return (
...
);
}
export default App;
热门推荐
服务管理流程如何标准化
2024年中国茶产业成熟度分析简报
葵花籽油有转基因的吗 葵花籽油致癌吗 转基因油对人体有害吗
《红猪》:现实映照与多重反思
C++递归经典问题——汉诺塔
孕妇能否享用酸奶?孕妇喝酸奶的正确姿势,花样喝法等你来学!
手腕扭伤后的紧急处理与康复指导
房贷年龄限制你知道吗?一文教你搞定购房计划
别再用碱水泡发干鱿鱼了,这样做鲜味不流失
增值税进项税额不得抵扣的情形
合伙人利润分配的法律指南
种植牙的基础知识
ps处理大型图片需要什么配置?4k修图ps电脑配置要求
鱼刺卡喉的S型鱼刺——后匙骨卡喉揭秘
鱼为什么要长那些暗搓搓的小刺?
手上长倒刺,真的不是缺维生素(内附处理妙招)
公司裁员时如何计算遣散费?新规和赔偿标准全解析,确保你的权益
南方哪里可以看到雪
哪些因素会影响健身教练的薪资?
飞机轮挡血案引发的思考
值得骄傲的中国车——从文化历史角度看中国汽车品牌
泰拉瑞亚断裂英雄剑获取攻略:从机械Boss到日食事件
范成大《四时田园杂兴·其二十五》:日长篱落无人过,惟有蜻蜓蛱蝶飞
红茶冲泡后变色:原因、解决方法及如何避免
苹果手机容易发烫?这几个实用方法帮你快速降温
红枸杞的功效与作用是什么
政协委员:坚持为发展献计 为民生建言
如何通过项目结构划分提高开发效率?
全方位省钱指南:三亚至新疆自驾游路线、预算与技巧全解析
怎样挑选优质牛仔面料