预取与流式加载
Qwik 如何预测下一步交互,并把代码提前放进浏览器缓存。
Qwik 的首屏不需要 JavaScript 就能交互吗?准确说:HTML 立即可见、链接立即可用,而事件处理函数在首次触发时才需要代码。为了不让首次点击等待网络,Qwik 会提前把可能用到的代码放进缓存。
01构建期的模块图#
构建时会生成 q-manifest.json 与紧凑的 bundle graph,记录每个 bundle 中的符号、依赖关系,以及某个 bundle 加载后最可能继续请求哪些 bundle。Qwik Router 也会把每条路由及其依赖写进这张图。
q-manifest.json
└── bundles
├── counter.js → Counter_onClick
├── docs.js → DocsPage, DocsSidebar
└── search.js → SearchDialog, searchIndex
build/q-bundle-graph-abc123.json
└── 概率化的下一跳关系容器恢复时,Qwik 读取这张图,用 <link rel="modulepreload"> 预取静态依赖(高优先级)与动态依赖(低优先级)。浏览器决定何时真正下载。
02三条并行的预取线#
| 对象 | 触发时机 | 目的 |
|---|---|---|
| 事件处理代码 | 页面恢复后立即推测预取 | 首次点击无需等待 |
| 路由代码 | Link 进入视口 | SPA 导航瞬间完成 |
| 路由数据 | 用户表现导航意图 | 页面与数据同时到达 |
<Link> 可以分别控制这两类预取:prefetchBundles 默认 visible,prefetchData 默认 intent。需要节省流量时也可以显式关闭。
<Link href="/docs/" prefetchBundles="visible" prefetchData="intent">
文档
</Link>03消除网络瀑布#
传统模块加载是串行的:A 下载完才知道要 B,B 下载完才知道要 C。Qwik 在服务端就知道整张图,因此可以一次性告诉浏览器接下来需要哪些模块,把瀑布变成并行。
04流式渲染#
SSR 不等整个页面就绪才发送。静态外壳先到,异步边界完成后以独立片段追加。Qwik 支持乱序流式:慢的部分不会阻塞已经准备好的部分。
- 首字节更早,用户更早看到内容。
- 慢 loader 只影响读取它的组件,而不是整页。
- 片段到达后即可恢复,交互与后续内容并行。