浏览器缓存机制导致的白屏问题解决
创作时间:
作者:
@小白创作中心
浏览器缓存机制导致的白屏问题解决
引用
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;
热门推荐
姿势不对颈椎“受罪” 手法治疗来“解救”
如何建立一个公司数据库
医药纯化水处理设备——保障药品质量的关键
心理学:为什么坏坏的人会更有魅力?这才是本质
梦参老和尚:这样观想地藏菩萨,有无穷无尽加持力
如何设计一份详细的工资明细表?
原理图与PCB设计核心指南
电脑装机指南
揭秘网络诈骗:剖析虚假宣传视频的本质
北京标准时间:定义、应用与未来展望
卡方检验详解分析与实例
人的认知共有七层,看看你在第几层?
提升翻译技巧的五大诀窍
昼盲的主要原因是视杆细胞病变
贵州特色美食:折耳根炒腊肉的制作方法
广东城乡联动展岭南风情,春节假期第六日接待游客数较去年同期明显增长
基于STM32的火灾报警系统设计与实现
数字人理解图文怎么做
“大学生落户深圳有补贴吗?”深圳这些区可申请!
Tor 与 VPN – 它们之间的主要区别
《诛仙》作者“发卖”角色,网文圈又掐架了
看得见的中华文化之礼 ——评《华服霓裳:京剧戏服探秘》
探究蓝田玉市场行情:价格趋势及每吨价位分析
口腔溃疡盐水漱口有用吗
如何理解团队定位
水原华城:韩国京畿道的世界文化遗产
替米沙坦降压药的副作用是什么
如何通过4P策略提升市场营销效果?
大国之盾 | 055型驱逐舰
清凉圣境五台山:华北屋脊上的佛教文化瑰宝