尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Umi.js 资源预加载机制:从 dist 产物反推 preload_helper.js 的生成链路
Umi.js 资源预加载机制:从 dist 产物反推 preload_helper.js 的生成链路【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umiUmi.js 生产构建的 dist 目录里,除了路由 chunk,还有一个很小的脚本 preload_helper.js。浏览器在 HTML 解析的极早期就会执行它,为当前路由的 JS 与 CSS 资源插入预加载标签,抢在路由组件挂载之前把资源拉下来。本文从这个最终产物反推整条机制:它由谁生成、内部的数据表如何采集、运行时又如何与打包器运行时协同,避免重复请求。产物反推:HTML head 里多出的一个 script 标签打开构建产物的 index.html,会在 head 看到一个指向{publicPath}/preload_helper.js的 script 标签(若 publicPath 配置为 auto,则按根路径处理);输出目录里同名文件与路由 chunk 放在一起。开启 hash 配置后,文件名会带一段由文件内容计算的 md5 前 8 位摘要作为后缀。这个脚本先于任何路由代码执行,职责只有两件事:判断当前路由该预加载哪些资源,以及把对应标签插入 head。还有两条线索值得注意:tern 微前端模式下,同一段逻辑不落盘成文件,而是把映射表以内联的script typeumi-route-chunk-files-mapJSON 写入 head;而整个生成逻辑统一收敛在 packages/preset-umi/src/features/routePreloadOnLoad/ 插件里,并不在 bundler 包中,stats 只是它的数据来源。映射表从何而来:onBuildComplete 解析 chunks 建立路由与资源映射preload_helper.js 本质是「一个模板 一张数据表」。数据表结构刻意压缩到四个字母字段:interface IRouteChunkFilesMap { p: string; // package.json 的 name,作为 data 属性前缀 b: string; // bundler 类型 f: [string, string | number][]; // [[文件名, chunkId]] r: Recordstring, number[]; // 路由路径 → f 的下标数组 }这张表在构建成功的 onBuildComplete 钩子中拼装,输入是构建 stats(webpack 走stats.toJson(),mako 走 compilation 对象)和 Umi 生成的路由树,过程分三步:遍历所有非 entry chunk,只挑出 .js 与 .css 文件,再看 chunk 的 origins(即它由哪个动态 import 引入)。只有指向生成的core/route.tsx的 origin 才算路由资源,入口 chunk 直接跳过;把每个路由文件的 import 请求经 alias 解析成绝对路径,并沿路由树向上收集父路由(layout、wrappers)的资源文件。route.wrappers 的实现会让 wrapper 路由与内层路由共享同一 absPath,此时保留索引列表更长的一方;r的键是路由 absPath,并按类 react-router 的评分算法排序:静态段 10、动态段 3、空段 1、通配段 -2,排序只影响遍历顺序,不影响匹配结果。触发条件同样写在插件的enableBy里:package.json 必须有 name(它是 data 属性前缀,缺了预加载标记就无从谈起),非 vite 模式、非 mpa 模式,且路由加载器为 esm(routeLoader.moduleType默认即 esm)。模板替换与产物落盘:占位符、terser 与 hash 文件名脚本主体来自 preloadRouteFilesScp.js 模板。文件本身就是手写的压缩风格代码,顶部注释明确提醒不要使用高级语法,以免转译器插入 helper 撑大脚本体积。模板里只有三个占位符:{{routeChunkFilesMap}}、{{basename}}、{{publicPath}}。publicPath 的替换有个细节:若开启了 runtimePublicPath,占位符会被替换成window.publicPath || ...的形式,保证运行时仍能动态取到基础路径。生产模式下,替换后的内容会再过一遍 terser 压缩(去注释、去 debugger),失败时降级使用未压缩版本并打印告警;随后 writeFileSync 写入输出目录,再由 addHTMLHeadScripts(stage: Infinity) 把 script 引用注入 head——第一节看到的那个标签就是这么来的。页面加载时预加载如何生效:路径匹配与 data 属性浏览器执行 preload_helper.js 时的步骤很轻:从 location.pathname 去掉 basename 得到路由路径,base 不匹配则整体跳过,避免非本站路径误触发;先在r里查静态路由的精确命中,未命中才把动态路由键转成正则逐一尝试(/:id变/[^/],/*变/.);js 资源插入script src async,css 资源插入link relpreload asstyle;每个标签额外写入data-{b}属性,值为{包名}:{chunkId}。这个 data 属性是与打包器运行时的协同约定:webpack 加载 chunk 时能凭它识别出已被预加载的脚本并直接复用,而不是对同一 chunk 再发一次请求。预加载因此是「一次下载、两次使用」,不构成浪费。一个容易误判的边界:mako 会把极小的异步 chunk 合并进入口,这类文件不会出现在映射表里,自然也没有预加载标签。这是正确行为,不是遗漏。适用边界:与 routePrefetch、clientLoader 的分工preload_helper.js 只解决「当前路由的资源文件」。它与另外两个预加载能力分工互补:routePrefetch(默认关闭)按用户意图(如鼠标悬停)提前预取即将跳转的路由,配置形如{ defaultPrefetch, defaultPrefetchTimeout };clientLoader 则把数据请求提到页面组件加载完成之前,解决瀑布流问题。三者分别覆盖进入页面、跳转前、数据依赖三个时点,配置上互不干扰。行动建议验证预加载链路是否生效,直接看产物:dist 里存在 preload_helper.js、index.html 的 head 有对应 script 标签,再在 Network 面板确认路由 chunk 早于路由组件挂载出现;若缺失,依次核对 package.json 的 name、esm 路由、非 mpa 三个启用条件。预加载的代价是带宽,而它对当前路由的资源是「全量」预取。对资源特别重的路由,用 clientLoader 与路由级拆分控制首屏体量,比期待预加载文件独力承担更现实。【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

OpenProject 快速上手:从空项目到团队看板的全流程

OpenProject 快速上手:从空项目到团队看板的全流程

OpenProject 快速上手:从空项目到团队看板的全流程 【免费下载链接】openproject OpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue …

📅 2026/9/11 11:38:49
DMA硬件协同思维:从RK3588死锁到STM32H7缓存一致性实战

DMA硬件协同思维:从RK3588死锁到STM32H7缓存一致性实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/11 11:38:49
多轮对话上下文不丢?context-mode实践:滚动摘要+滑动窗口+轻量检索

多轮对话上下文不丢?context-mode实践:滚动摘要+滑动窗口+轻量检索

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/11 11:38:49
MORE NEWS

更多资讯

📰

Vosk 离线语音识别快速上手:从安装到跑通第一条转写结果

Vosk 离线语音识别快速上手:从安装到跑通第一条转写结果 【免费下载链接】vosk-api Offline speech recognition API for Android, iOS, Raspberry Pi and servers with Python, Java, C# and Node 项目地址: https://gitcode.com/GitHub_Trending/vo/vosk-api …

📰

DouK-Downloader 使用指南:10 分钟跑通抖音 TikTok 批量下载与数据采集

DouK-Downloader 使用指南:10 分钟跑通抖音 TikTok 批量下载与数据采集 【免费下载链接】TikTokDownloader 抖音 / TikTok 平台作品下载/数据采集工具 项目地址: https://gitcode.com/GitHub_Trending/ti/TikTokDownloader 每周要归档十几个账号的新作品&…

📰

2026泰安育婴师挑选全攻略:从培训到口碑全维度解析,本地标杆机构实测靠谱

随着生育支持政策的落地和居民家庭育儿观念的升级,越来越多泰安家庭意识到专业育婴服务对产后恢复、宝宝科学成长的重要性。但不少家庭在挑选服务的过程中,很容易被五花八门的宣传绕晕:有的宣传“金牌阿姨”实际专业能力不足,有的…

📰

上海GEO优化公司如何选?途阔营销凭自研与实战领跑

随着文心一言、DeepSeek、通义千问等主流大模型持续普及,越来越多的消费者习惯直接借助AI工具获取品牌、产品及行业信息。生成式引擎优化(GEO)应运而生,打破了传统SEO的边界,成为企业抢占AI搜索流量红利的关键布局。在…

📰

System Informer 系统托盘图标不显示:从根因分析到修复的完整排障

System Informer 系统托盘图标不显示:从根因分析到修复的完整排障 【免费下载链接】systeminformer A free, powerful, multi-purpose tool that helps you monitor system resources, debug software and detect malware. Brought to you by Winsider Seminars &am…

📰

MODBUS RTU协议详解:从报文解析到CRC16校验与RS485调试实战

作为常年泡在工控调试现场的人,我对MODBUS协议算是再熟悉不过了。这个1979年由Modicon公司提出的串行通信协议,四十多年过去了,居然还是工业自动化领域最通用的“普通话”——PLC、触摸屏、变频器、温控表、伺服驱动器、智能电表,…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬