一、核心概念
1.1 预加载 (Preloading)
定义:在用户需要之前,提前加载资源(JS、CSS、图片等)并缓存到浏览器内存中,但不执行也不渲染页面。
本质:资源的提前获取,而非页面的提前准备。
类比:餐厅后厨提前备好食材(洗好、切好),但还没下锅炒。
1.2 预渲染 (Prerendering)
定义:不仅加载资源,还在后台完整执行并渲染整个页面(包括JS、DOM、CSSOM),完成后置于隐藏标签页,用户点击时直接切换显示。
本质:页面的完全准备就绪。
类比:餐厅直接把菜炒好保温,客人一点就上桌。
二、技术实现对比
| 维度 |
预加载 (Preload/Prefetch) |
预渲染 (Prerender) |
| 加载内容 |
单个资源文件 |
完整HTML页面及其所有子资源 |
| 是否执行JS |
仅下载,不执行 |
完整执行(包括脚本、XHR请求) |
| DOM/CSSOM |
不构建 |
完整构建隐藏页面 |
| 内存消耗 |
低(仅缓存资源) |
高(完整页面实例) |
| 网络消耗 |
中等(按需加载资源) |
高(加载页面所有依赖) |
| 适用场景 |
下一屏资源、路由懒加载 |
确定会访问的下一页(如步骤表单、搜索结果页) |
| 即时性 |
仍需解析执行(几十ms) |
近乎瞬时(<10ms切换) |
三、预加载的具体实现
3.1 HTML标签方案(最推荐)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <link rel="preload" href="critical.css" as="style" /> <link rel="preload" href="hero-image.jpg" as="image" /> <link rel="preload" href="main.js" as="script" />
<link rel="prefetch" href="page2.js" as="script" /> <link rel="prefetch" href="next-page.css" as="style" />
<link rel="preconnect" href="https://api.example.com" />
<link rel="dns-prefetch" href="https://cdn.example.com" />
|
3.2 动态JS预加载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| const preloadImage = (url) => { const img = new Image(); img.src = url; };
const preloadScript = (url) => { const link = document.createElement("link"); link.rel = "prefetch"; link.href = url; document.head.appendChild(link); };
let timer; linkElement.onmouseenter = () => { timer = setTimeout(() => { import("./heavy-component.js"); }, 100); };
|
3.3 框架集成
React + Webpack:
1 2 3 4 5 6 7 8
| const Profile = lazy( () => import( "./Profile" ), );
|
Next.js:
1 2 3 4 5
| <Link href="/about">About</Link>
<Link href="/about" prefetch={false}>About</Link>
|
四、预渲染的实现方案
4.1 Speculation Rules API(现代标准)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <script type="speculationrules"> { "prerender": [ { "source": "list", "urls": ["next-page.html", "checkout.html"], "requires": ["anonymous-client-ip-when-cross-origin"] } ], "prefetch": [ { "source": "list", "urls": ["likely-next.html"] } ] } </script>
|
4.2 服务端预渲染
静态生成(SSG):在构建时生成完整的 HTML 页面,适合静态内容。通过 getStaticProps 和 getStaticPaths 实现,支持增量静态再生(ISR)以定期更新页面内容。