HTML 异步加载资源优化
非关键资源异步加载,不阻塞首屏渲染,是现代 Web 性能优化的核心策略。
JavaScript 异步加载
async 属性
下载时不阻塞 HTML 解析,下载完成后立即执行。
HTML
<!-- 独立脚本,无依赖关系 -->
<script src="analytics.js" async></script>
<script src="ads.js" async></script>
async 脚本执行顺序不确定,适合独立的第三方脚本。
defer 属性
下载时不阻塞解析,HTML 解析完成后按顺序执行。
HTML
<!-- 有依赖关系的脚本 -->
<script src="jquery.js" defer></script>
<script src="app.js" defer></script>
defer 保持脚本执行顺序,适合有依赖的业务脚本。
动态脚本加载
JavaScript
// 按需加载脚本
function loadScript(src) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = src;
script.async = true;
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
});
}
// 使用示例
loadScript('https://cdn.example.com/heavy-lib.js')
.then(() => console.log('库加载完成'));
CSS 异步加载
媒体查询切换
HTML
<link rel="stylesheet" href="print.css" media="print" onload="this.media='all'">
preload + onload
HTML
<link rel="preload" href="non-critical.css" as="style" onload="this.rel='stylesheet'">
动态插入
JavaScript
// 用户交互后加载
document.getElementById('theme-btn').addEventListener('click', () => {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'dark-theme.css';
document.head.appendChild(link);
});
图片懒加载
原生懒加载
HTML
<img src="hero.jpg" alt="首屏图片" loading="eager">
<img src="gallery-1.jpg" alt="延迟加载" loading="lazy">
<img src="gallery-2.jpg" alt="延迟加载" loading="lazy">
IntersectionObserver 实现
JavaScript
const images = document.querySelectorAll('img[data-src]');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
}, { rootMargin: '50px' });
images.forEach(img => observer.observe(img));
HTML
<img data-src="lazy-image.jpg" src="placeholder.jpg" alt="懒加载图片">
iframe 懒加载
HTML
<iframe src="video.html" loading="lazy"></iframe>
async 与 defer 对比
| 特性 | async | defer |
|---|---|---|
| 执行时机 | 下载完立即执行 | DOMContentLoaded 前 |
| 执行顺序 | 不保证顺序 | 按声明顺序执行 |
| 阻塞 DOM | 执行时阻塞 | 不阻塞 |
| 适用场景 | 独立第三方脚本 | 业务脚本 |
注意事项
async 和 defer 只对外部脚本有效,内联脚本不支持。
懒加载图片需设置占位图,避免布局偏移(CLS)。
关键首屏图片不要使用懒加载,影响 LCP 指标。
异步 CSS 加载前需隐藏闪烁,或使用 noscript 降级。
要点总结
- async 用于独立第三方脚本
- defer 用于有依赖的业务脚本
- 非关键 CSS 使用 preload 异步加载
- 图片使用原生 loading="lazy" 懒加载
- 关键首屏资源不使用异步加载
📝 发现内容有误?点击此处直接编辑