我们通过 Next.js 11.1 全面提升了构建性能,主要改进包括:
- 安全补丁:重要更新以防止潜在的开放重定向漏洞
- ES 模块支持:通过实验性标志立即启用
- 基于 Rust 的工具链:采用 SWC 替代原有 JS 工具链(Babel 和 Terser)
- 更快的数据获取:预渲染时通过 HTTP
keep-alive
实现 2 倍速数据获取 - 更快的源码映射:使用源码映射时构建速度提升 70%,内存占用减少 67%
- ESLint 集成优化:更易用的默认配置与拼写错误检查
next/image
改进:可选的 Sharp 支持,更好的next export
兼容性
立即通过 npm i next@latest
命令升级体验。
安全补丁
Next.js 团队与安全研究人员合作,致力于预防潜在漏洞。特别感谢 Robinhood 的 Gabriel Benmergui 发现并负责任地披露了 pages/_error.js
可能导致的开放重定向问题。
该问题虽不会直接危害用户,但可能通过从可信域名重定向至攻击者域名实施钓鱼攻击。我们已在 Next.js 11.1 中发布补丁防止此类开放重定向,并添加了安全回归测试。
详情请参阅公开的 CVE。建议立即升级至最新版本以增强应用安全性。如需报告安全问题,请发送邮件至 [email protected]
。
注意:部署在 Vercel 的 Next.js 应用不受此漏洞影响(因此无需采取任何措施)。
ES 模块支持
我们正在为 Next.js 提供全面的 ES 模块支持,包括作为输入模块和输出目标。从 Next.js 11.1 开始,您可以通过实验性标志导入使用 ES 模块的 npm 包(例如在其 package.json
中声明 "type": "module"
)。
ES 模块支持包含对原有 CommonJS 导入行为的向后兼容。在 Next.js 12 中,esmExternals: true
将成为默认配置。欢迎试用新选项并通过 GitHub Discussions 反馈建议。
采用基于 Rust 的 SWC
我们正在集成 SWC —— 一个用 Rust 编写的超快 JavaScript/TypeScript 编译器,它将替代 Next.js 中原有的两个工具链:用于单文件转译的 Babel 和用于输出包压缩的 Terser。
在将 Babel 替换为 SWC 的过程中,我们将所有 Next.js 自定义代码转换移植到 Rust 编写的 SWC 转换器以最大化性能。例如对 getStaticProps
、getStaticPaths
和 getServerSideProps
中未使用代码的摇树优化。
在替换 Terser 方面,我们正确保 SWC 压缩器在保持相似输出质量的同时,显著提升压缩性能与并行处理能力。
早期测试显示:使用 SWC 后,原 Babel 代码转换时间从 ~500ms 降至 ~10ms,Terser 代码压缩时间从 ~250ms 降至 ~30ms,整体构建速度提升两倍。
我们很高兴宣布 SWC 的创建者 DongYoon Kang 和 Parcel 贡献者 Maia Teegarden 已加入 Vercel 的 Next.js 团队,专注于提升 next dev
和 next build
性能。将在下个稳定版中分享更多 SWC 集成成果。
性能优化
构建与数据获取
使用 next build
发起大量 HTTP 请求时,平均性能提升约 2 倍。例如从 Headless CMS 获取内容时,您将明显感受到构建速度的提升。
Next.js 现已自动为 node-fetch 添加 polyfill 并默认启用 HTTP Keep-Alive。根据外部基准测试,这将使预渲染速度提升约 2 倍。
如需禁用特定 fetch()
调用的 HTTP Keep-Alive,可添加 agent 选项:
如需全局覆盖所有 fetch()
调用,可在 next.config.js
中配置:
源码映射
通过优化 webpack 资源与源码映射处理流程,启用浏览器源码映射的性能损耗降低约 70%,内存占用减少约 67%。
此优化仅影响在 next.config.js
中配置了 productionBrowserSourceMaps: true
的 Next.js 应用。在 Next.js 11.1 中,启用源码映射后构建时间仅增加 11%。
我们还与 Sentry 合作优化了 Sentry Next.js 插件的源码映射上传性能。
ESLint 改进
Next.js 11 通过 next lint
引入了内置 ESLint 支持。自发布以来,我们持续添加帮助开发者修复常见错误的规则。
默认无障碍规则
现在默认包含更完善的无障碍规则,可检测 ARIA 属性不匹配或使用不存在 ARIA 属性的情况。这些规则将默认显示警告。
- aria-props
- aria-proptypes
- aria-unsupported-elements
- role-has-required-aria-props
- role-supports-aria-props
特别感谢社区贡献者 JeffersonBledsoe 添加这些规则。
常见拼写错误
现在默认会对 getStaticProps
、getStaticPaths
和 getServerSideProps
中的常见拼写错误显示警告。例如 getstaticprops
或 getStaticprops
将触发警告提示。
特别感谢社区贡献者 kaykdm 创建此规则。
next/image
改进
我们收集了大量关于 next/image
和内置图像优化的社区反馈,很高兴分享在性能、开发体验和用户体验方面的多项改进。
图像优化
默认情况下,Next.js 使用 WebAssembly 执行图像优化,这种方式通过显著减小安装包体积且无需安装后步骤来优化安装时间。在 Next.js 11.1 中,您可以选择安装 sharp
来优化未缓存图像的生成时间(代价是安装时间更长)。
基于 WebAssembly 的图像优化器已更新支持 Apple M1 等 ARM 芯片(需 Node.js 16)。
内置图像优化器现在能根据响应体内容自动检测外部图像类型。这使得当 AWS S3 等服务的响应头为 Content-Type: application/octet-stream
时,Next.js 仍能优化图像。
开发环境下模糊占位图的延迟生成
在 next dev
期间,使用 placeholder="blur"
的静态图像导入现在会自动延迟生成模糊占位图,显著提升含有大量静态图像导入项目的开发服务器启动速度:
其他图像改进
- 已加载过的图像不再延迟加载:当图像之前已在页面加载过(通过客户端导航或在页面其他位置加载),Next.js 将自动跳过延迟加载以避免显示前的闪烁现象
- 支持
next export
使用自定义图像加载器:next/image
现在支持next export
与任何第三方图像优化服务配合使用。当需要为next/image
提供自定义loader
属性时,可在next.config.js
中配置images.loader: "custom"
- 新增图像加载完成事件:根据用户反馈,我们为
next/image
新增了onLoadingComplete
属性,用于注册图像完全加载后的回调函数 - 可配置默认图像缓存 TTL(存活时间):现在可通过
images.minimumCacheTTL
配置优化图像的默认缓存时间。建议优先使用静态图像导入,因其 URL 包含图像内容哈希值会自动采用最大 TTL
社区
Next.js 是超过 1,700 名独立开发者、Google 和 Facebook 等行业合作伙伴以及核心团队共同努力的成果。
我们欣喜地看到社区持续壮大。仅过去六个月,Next.js 在 NPM 的周下载量就从 410 万增长至 620 万(增幅 50%),Alexa 全球 top 10,000 网站中使用 Next.js 的主页数量也增长了 50%。
本版本由以下贡献者共同打造:@abotsi, @adam-cowley, @afbarbaro, @akellbl4, @AndreVarandas, @andys-github, @angeloashmore, @apuyou, @arturmuller, @AryanBeezadhur, @atcastle, @borekb, @brandonchinn178, @breyed, @brijendravarma, @ctbarna, @ctjlewis, @darshkpatel, @delbaoliveira, @destruc7i0n, @devknoll, @enesakar, @enzoferey, @euess, @fabb, @gnbaron, @hiro0218, @housseindjirdeh, @huozhi, @ijjk, @JacobLey, @jameshoward, @jamsinclair, @janicklas-ralph, @jarvelov, @javivelasco, @jaybekster, @JeffersonBledsoe, @jflayhart, @johnrackles, @jviide, @karlsander, @kasipavankumar, @kaykdm, @kdy1, @kylemh, @leerob, @LetItRock, @lsndr, @lucleray, @m-abdelwahab, @mandarons, @markkaylor, @mastoj, @michalbundyra, @michielvangendt, @Munawwar, @mvasilkov, @NickCrews, @NickKelly1, @noahweingand, @noreiller, @nyedidikeke, @omasher, @orta, @pa-rang, @padmaia, @papaponmx, @PaulvdDool, @petermekhaeil, @phocks, @pranavp10, @qwertyforce, @raon0211, @reod, @rishabhpoddar, @roim, @Ryz0nd, @sa3dany, @sachinraja, @samrobbins85, @schoenwaldnils, @schultzp2020, @sedlukha, @sergioalvz, @shibe23, @smitssjors, @sohamsshah, @sokra, @stefanprobst, @stovmascript, @stuymedova, @styfle, @tanys123, @ThangHuuVu, @theostrahlen, @thomasmarshall, @tigger9flow, @timneutkens, @Timvdv, @tmcgann, @tomchen, @UniqueNL, @Vadorequest, @vitalybaev, @yunger7, @zackdotcomputer, @zeekrey