ilo*_*zcd 12 javascript lazy-loading prefetch webpack
我最近在做一些网站优化工作,我开始使用 webpack 中的代码拆分,使用 import 语句,如下所示:
import(/* webpackChunkName: 'pageB-chunk' */ './pageB')
哪个正确创建了pageB-chunk.js,现在假设我想在 pageA 中预取这个块,我可以通过在 pageA 中添加以下语句来实现:
import(/* webpackChunkName: 'pageB-chunk' */ /* webpackPrefetch: true */ './pageB')
这将导致
<link rel="prefetch" href="pageB-chunk.js">
附加到 HTML 的头部,然后浏览器将预取它,到目前为止一切顺利。
问题是我在这里使用的import语句不仅预取 js 文件,还评估 js 文件,意味着该 js 文件的代码被解析并编译为字节码,执行该 JS 的顶级代码。
这是移动设备上非常耗时的操作,我想优化它,我只想要预取部分,我不想要评估和执行部分,因为稍后发生一些用户交互时,我会触发解析& 评价我自己
????????? 我只想触发前两步,图片来自https: //calendar.perfplanet.com/2011/lazy-evaluation-of-commonjs-modules/?????????
当然我可以通过自己添加预取链接来做到这一点,但这意味着我需要知道我应该在预取链接中放入哪个 URL,webpack 肯定知道这个 URL,我如何从 webpack 获取它?
webpack 有什么简单的方法来实现这一点吗?
更新: 我将所有内容都包含在 npm 包中,请查看! https://www.npmjs.com/package/webpack-prefetcher
经过几天的研究,我最终编写了一个定制的 babel 插件......
简而言之,该插件的工作原理如下:
Prefetcher 是一个帮助器类,包含 webpack 输出的清单,可以帮助我们插入预取链接:
export class Prefetcher {
static manifest = {
"pageA.js": "/pageA.hash.js",
"app.js": "/app.hash.js",
"index.html": "/index.html"
}
static function fetch(chunkId) {
const link = document.createElement('link')
link.rel = "prefetch"
link.as = "script"
link.href = Prefetcher.manifest[chunkId + '.js']
document.head.appendChild(link)
}
}Run Code Online (Sandbox Code Playgroud)
使用示例:
const pageAImporter = {
prefetch: () => import(/* prefetch: true */ './pageA.js')
load: () => import(/* webpackChunkName: 'pageA' */ './pageA.js')
}
a.onmousehover = () => pageAImporter.prefetch()
a.onclick = () => pageAImporter.load().then(...)Run Code Online (Sandbox Code Playgroud)
该插件的详细信息可以在这里找到:
再说一次,这是一种非常 hacky 的方式,我不喜欢它,如果你希望 webpack 团队实现这个,请在这里投票: