Back返回博客

Next.js 11.1 版本发布

Next.js 11.1 带来了重要安全补丁、ES 模块支持、性能优化、基于 Rust 的工具链、预渲染时 2 倍速的数据获取等多项改进!

我们通过 Next.js 11.1 全面提升了构建性能,主要改进包括:

立即通过 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")。

next.config.js
module.exports = {
  // 优先加载 ES 模块而非 CommonJS
  experimental: { esmExternals: true },
};

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 转换器以最大化性能。例如对 getStaticPropsgetStaticPathsgetServerSideProps 中未使用代码的摇树优化。

在替换 Terser 方面,我们正确保 SWC 压缩器在保持相似输出质量的同时,显著提升压缩性能与并行处理能力。

早期测试显示:使用 SWC 后,原 Babel 代码转换时间从 ~500ms 降至 ~10ms,Terser 代码压缩时间从 ~250ms 降至 ~30ms,整体构建速度提升两倍

我们很高兴宣布 SWC 的创建者 DongYoon KangParcel 贡献者 Maia Teegarden 已加入 Vercel 的 Next.js 团队,专注于提升 next devnext build 性能。将在下个稳定版中分享更多 SWC 集成成果。

性能优化

构建与数据获取

使用 next build 发起大量 HTTP 请求时,平均性能提升约 2 倍。例如从 Headless CMS 获取内容时,您将明显感受到构建速度的提升。

Next.js 现已自动为 node-fetch 添加 polyfill 并默认启用 HTTP Keep-Alive。根据外部基准测试,这将使预渲染速度提升约 2 倍

如需禁用特定 fetch() 调用的 HTTP Keep-Alive,可添加 agent 选项:

import { Agent } from 'https';
const url = '<https://example.com>';
const agent = new Agent({ keepAlive: false });
fetch(url, { agent });

如需全局覆盖所有 fetch() 调用,可在 next.config.js 中配置:

next.config.js
module.exports = {
  httpAgentOptions: {
    keepAlive: false,
  },
};

源码映射

通过优化 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 属性的情况。这些规则将默认显示警告。

特别感谢社区贡献者 JeffersonBledsoe 添加这些规则。

常见拼写错误

现在默认会对 getStaticPropsgetStaticPathsgetServerSideProps 中的常见拼写错误显示警告。例如 getstaticpropsgetStaticprops 将触发警告提示。

特别感谢社区贡献者 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"静态图像导入现在会自动延迟生成模糊占位图,显著提升含有大量静态图像导入项目的开发服务器启动速度:

pages/index.js
import Image from 'next/image';
import author from '../public/me.png';
 
export default function Home() {
  return (
    // 该图像的占位图将在开发环境下延迟生成
    <Image src={author} alt="作者照片" 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