用 fetch + insertAdjacentHTML 会闪屏,因首屏 header 等关键内容需等待异步加载完成才插入;应内联关键区块、异步加载非关键部分,并确保路径、样式作用域与时序正确。

直接复制粘贴
为什么用 fetch + insertAdjacentHTML 最常用但总闪一下?
因为浏览器先渲染空白 DOM,等 fetch 返回 HTML 字符串、解析、插入才补上导航栏。用户看到的是“白屏 → 闪现 header”,尤其在弱网下更明显。
缓解办法不是加 loading,而是分层加载:
- 首屏关键区块(比如
<header>)手动内联到每个页面的 HTML 源码里,确保 DOM 加载即可见 - 非关键部分(如统计脚本、页脚版权年份、多语言切换器)用
fetch异步加载,绑定在DOMContentLoaded后执行 - 避免在
<head>里发起 fetch —— 它会阻塞 HTML parser,触发parser-blocking警告
Thymeleaf 项目里怎么安全抽公共片段?
别手写 include 或拼字符串。Thymeleaf 原生支持 th:fragment + th:replace/th:include,服务端渲染时就完成组装,零客户端延迟、无 CSP 风险。
立即学习“前端免费学习笔记(深入)”;
实操要点:
- 在
templates/common/header.html里定义:<header th:fragment="main(title, user)"><h1 th:text="${title}"></h1><span th:text="${user?.name}"></span></header> - 在业务页引用:
<div th:replace="common/header :: main('首页', ${currentUser})"></div> - 注意:传参必须是后端已计算好的对象,不能传 JS 变量;
th:include会保留外层<div>,th:replace则完全替换,按语义选
静态站点(Vite/Webpack)怎么避免手动重复写 header?
别用 fs.readFileSync 在浏览器里读文件——Node.js API 在前端根本不存在。也别信 import html from './header.html?raw' 就万事大吉,它只给你字符串,innerHTML = html 后 script 不执行、事件不绑定、样式可能被隔离。
推荐路径:
- Vite 项目:装
vite-plugin-html,配置inject: { data: { header: readFileSync('./src/_shared/header.html', 'utf8') } },模板中用<%= header %> - 更现代方案:把 header 写成
Header.vue,只含<template>,用<Header />复用,响应式、可传 prop、样式 scoped 隔离全天然支持 - 绝对不要用
<iframe src="header.html">—— 它创建独立上下文,CSS/JS 不继承,SEO 友好性归零,移动端高度自适应极难做
真正容易被忽略的点:提取时是否检查了 background-image: url(...) 中的相对路径?是否剥离了原页面里写死的 onclick="xxx()"?这些细节不处理,复用后的页面大概率样式错位或交互失效。



















