优先根据依赖关系选择:无依赖脚本用 async,有 DOM 依赖的用 defer;loading="lazy" 仅对 img/iframe 生效且需设宽高;preload 须精准用于首屏确定资源并带 as 属性;非关键 CSS 禁用 @import,应分离加载。

script 标签加 async 还是 defer?看依赖关系
不加属性的 <script src="app.js"></script> 会立刻阻塞 HTML 解析,这是首屏白屏最常见原因。async 和 defer 都能避免阻塞下载,但执行时机完全不同:
-
async:适合无依赖脚本(如analytics.js、ads.js),下载不阻塞,但执行时机不可控——可能在 DOM 构建完成前就运行,甚至 DOM 还没就绪就报document.getElementById is not a function -
defer:适合有 DOM 依赖的业务 JS(如初始化轮播、表单校验),下载不阻塞,执行严格在 DOM 解析完成后、DOMContentLoaded事件触发前,且按<script></script>出现顺序执行 - 两者都写在
里也没问题;但如果脚本本身不依赖 DOM,又怕 defer 顺序太晚,用 async 更稳妥
图片懒加载 loading="lazy" 的生效条件和硬性要求
原生 loading="lazy" 只对 <img alt="HTML页面加载过程中对于大尺寸静态资源的非阻塞下载策略" > 和 <iframe></iframe> 生效,且不是“加了就一定懒”:
- 首屏关键图(Hero 图、轮播第一张、按钮图标)必须显式移除
loading="lazy",否则可能被延迟加载,导致空白或布局抖动 - 必须同时设置
width和height属性,否则加载时会触发布局偏移(CLS),直接拉低 Core Web Vitals 分数 - Safari 15.4+ 才支持
<iframe></iframe>的 lazy,旧版安卓 WebView 完全忽略,需降级为data-src+IntersectionObserver - 别同时写
src和loading="lazy"再额外用 JS 监听——浏览器可能先加载src,造成重复请求
preload 不是“提前加载所有东西”的开关
<link rel="preload"> 是高优先级提示,不是万能加速器,加错反而拖慢首屏:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- 只对「当前导航中确定马上要用」的资源有效,比如首屏字体
font.woff2、关键 Hero 图、核心 JS 入口文件 - 必须带
as属性(如as="font"、as="image"),否则浏览器无法正确设置请求优先级 - 字体类资源要加
crossorigin,否则可能因 CORS 失败而加载失败 - 不要 preload CSS 或 JS 入口之后再 import 的子模块——预加载链路断裂,反而浪费带宽
非关键 CSS 必须隔离,不能靠 @import 拖慢渲染
CSS 是渲染阻塞资源,@import 在 CSS 文件中是串行加载机制,极易成为性能瓶颈:
立即学习“前端免费学习笔记(深入)”;
-
@import "reset.css";比<link rel="stylesheet" href="reset.css">多一次网络往返,实测拖慢 FCP 超 300ms -
@import无法被预加载识别,也不能参与并行下载;构建工具(如 PostCSS)虽可内联展开,但 source map 易断 - 非关键 CSS(如打印样式、暗色主题)应改用
<link rel="stylesheet" media="(prefers-color-scheme: dark)">,让浏览器按条件加载 - 首屏关键 CSS 必须内联到
中,其余 CSS 用media="print"或 JS 动态插入来延迟加载
@import、一个没设宽高的 loading="lazy"、一个乱加的 preload,都可能把优化 effort 折损大半。


















