首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Next.js 10 正式发布:带来诸多新特性

我们很高兴为大家介绍全新 Next.js 10,其中的新特性包括:

  • 内置图像组件与自动图像优化功能: 使用新的 next/image 组件自动优化图像
  • 国际化路由: 使用内置原语轻松对您的 Next.js 应用程序进行国际化
  • Next.js Analytics: 衡量用户实际性能并加以调整
  • Next.js Commerce: 适用于高性能电子商务网站的多合一启动套件
  • React 17 支持: Next.js 现已全面兼容最新 React 版本
  • getStaticProps / getServerSideProps Fast Refresh: 在对数据获取方法进行编辑时,自动重新加载各项属性
  • Fast Refresh for MDX: 使用 @next/mdx,Fast Refresh 现可直接应用更改而无需重新加载整个页面
  • 可从第三方 React 组件导入 CSS:: 现支持从 npm 处导入组件所需要的 CSS
  • 自动解析 href:next/link 上不再需要 as 属性
  • @next/codemod CLI: 允许您轻松访问全部 Next.js codemods
  • 取消 getStaticPaths 回退: 在生成新的静态页面时直接等待预渲染结果,而不再提供静态回退页面

内置图像组件与自动图像优化功能

此次 Next.js 新版本的核心目标有二:改善开发人员体验,改善用户体验。

今年,我们已经在改善开发者体验与提升 Next.js 应用程序性能方面投入了大量精力。我们专注于减少浏览器所需加载的 JavaScript 代码量。

我们推出了 20 多项新功能,可改善性能与开发人员体验。此外,Next.js 的核心 JavaScript 代码量则减少了 16%。

今年 1 月,我们与谷歌 Chrome 小组合作推出了一种新的 JavaScript 代码拆分最佳策略。

例如,Barnebys 应用程序的体积可借此减少 23%,Sumup 中最大 JavaScript 软件包的体积减少达 70%。这些改进无需对 Next.js 应用程序内的代码做出任何修改,您可直接享受版本升级带来的“瘦身”效果。

各企业只需要将 Next.js 升级至最新版本,即可自动使用这项新策略。

网络图像

虽然我们减少浏览器中 JavaScript 代码加载量的努力得到了回报,但除了 JS 代码之外,网络中还充斥着大量标记与图像数据。

目前,网页总字节数的约 50% 来自图像数据。

作为页面中所加载的最大可见元素,图像对于最大内容绘制性能有着直接影响,这项指标也即将决定了谷歌如何在搜索结果中对各个网站进行排名。

半数图像的体积超过 1 MB——换言之,这些图片并未针对网络浏览环境进行优化。

如今,用户普遍使用手机、平板电脑以及笔记本设备浏览网络,而图像仍是其中最为僵化的显示素材。例如,网站可能加载了一张 2000 x 2000 像素的图片,但手机只会将其显示为 100 x 100 像素的形式。

此外,网页上有 30% 的图像都处于初始视口之外,意味着浏览器仍然在大量加载那些用户调整滚动条后才会看到的图像。

大部分图像都没有 width 与 height 属性,导致它们在页面加载过程中会突然跳出,这同样有损谷歌在 Core Web Vital 中提出的“累积布局偏移”( Cumulative Layout Shift)指标。

更重要的是目前网站上 99.7% 的图像仍未使用 WebP 等现代图像格式。

为了以高性能方式使用网页图像,我们需要从大小、体积、延迟加载与现代图像格式等多个角度进行考量。

开发人员需要设置复杂的构建工具以优化图像,但这些工具往往无法覆盖作为外部数据源的用户们自行提交的图像,最终导致遗留下大量优化空白。

而正是这一切,带来了令人沮丧的用户体验。

Next.js 图像组件

为此,我们高兴地宣布新版本中提供的高性能图像解决方案:Next.js 图像组件与自动图像优化功能。

基本上,Next.js 图像组件属于 HTML 元素的直接替代方案,属于专为现代网络开发的新型方法。

代码语言:javascript
复制
<imgsrc="/profile-picture.jpg"width="400"height="500">
importImagefrom'next/image'

<Imagesrc="/profile-picture.jpg"width="400"height="400">

谷歌 Chrome 团队协助我们创建了这款 React 组件,通过将最佳实践设定为默认方法以提升页面性能。

在使用 next/image 组件时,图像会自动延迟加载,意味着图像仅在邻近用户观看视口时才进行实际渲染。以此为基础,多达 30% 的视口外图像将不再占用宝贵的系统资源。

图像尺寸也成为强制执行项,浏览器可以立即呈现图像所占据的显示空间,而不会在加载完成时突然跳出一张大图。这就从根本上解决了布局偏移的问题。

另外,next/image 还消除了常见于响应式布局中,由 HTML 元素引发的 width 与 height 问题。在使用 next/image 时,图像将自动根据提供的 width 与 height 比例进行响应。

开发人员可以标记初始视口中的图像,使 Next.js 自动对这些图像进行预加载。通过在初始视口中预加载图像,网站的最大内容绘制(Largest Contentful Paint)指标可提升达 50%。

自动图像优化

虽然与 HTML 元素相比有所改进,但对于之前提到的将高清度图像渲染为手机端小图像的问题,我们还需要拿出有针对性的解决方案。

在 Next.js 10 中,我们的 next/image 组件通过内置的图像优化功能,自动为图像生成较小尺寸的适用版本。

内置图像优化会自动以 WebP 等现代格式交付图像。只要浏览器支持,WebP 图像的大小比 JPEG 小 30%。Next.js 10 还将自动支持更多未来陆续推出的图像格式,并根据浏览器的支持能力选择使用。

图像优化适用于各类图像源,并可对来自外部数据源的图像(例如 CMS)进行优化。

Next.js 10 不会在 build 过程中进行图像优化,而是根据用户请求执行按需优化。与静态站点生成器与纯静态解决方案不同,无论您需要发布 10 张图像还是 1000 万张图像,build 时长都不会增加。

总结

新的 next/image 组件与自动图像优化功能作为强大的最新原语,将极大改善用户的使用体验。

其中 next/image 组件能够处理自动延迟加载、关键图像预加载、跨设备正确调整图像大小以及自动支持现代图像格式等任务,对不同来源提供的图像进行全面优化。

我们也期待看到这些新功能为用户带来更顺畅的使用体验。

关于更多详细信息,请参阅 Next.js 图像组件与自动图像优化说明文档

国际化路由

今年,结合一部分企业及社区成员的反馈,我们的团队开始意识到国际化的重要意义。

例如,我们发现如果外文网站提供翻译版本,则访问者的驻留几率将提升至 72%。有 55% 的消费者表示他们只会在提供母语版本的电子商务网站上购买商品。

如果您打算冲击其他国家 / 地区的市场,那么对项目的国际化调整将直接决定产品的最终命运。

项目的国际化调整分为两块:翻译,与路由。

大部分 React 都提供翻译完成的应用程序,但却很少为您提供自动路由处理方案,而且通常只使用一种渲染策略。

考虑到这一现实,我们决定在 Next.js 10 中发布对国际化路由以及语言检测的内置支持。

内置的国际化路由功能支持 Next.js 的混合策略,您可以在静态生成与服务器渲染之间自由做出选择。

Next.js 10 支持两种最常见的路由策略:子路径路由,与域路由。

对于这两种策略,您都需要先在 Next.js 配置中指定语言环境。

代码语言:javascript
复制
// next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'nl'],
    defaultLocale: 'en'
  }
}

Locales 代表的是 UTS 语言环境标识符,属于一种用于定义语言环境的标准化格式。

通常,Locale 标识符由语言、区域与脚本组成,各元素之间使用破折号分隔,即:语言 - 区域 - 脚本。其中的区域与脚本属于可选项。例如:

  • en-US- 在美国使用的英语
  • nl-NL- 在荷兰使用的荷兰语
  • nl- 无特定使用区域的荷兰语

在完成区域配置之后,您即可选择子路径路由或域路由。

子路径路由

子路径路由将 locale 放入 url,因此可以在单一域中包含全部语言。

例如,您可以将 locale 插入 url 中,形成 /nl-nl/blog 以及 /en/blog。

域路由

域路由意味着您将语言环境与顶级域名映射起来。例如,example.nl 可映射至 nl 语言环境,example.com 则映射至 en 语言环境。

您还需要提供额外配置,才能在域路由内实现域名路由:

代码语言:javascript
复制
// next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'nl'],
    domains: [
      {
        domain: 'example.com',
        defaultLocale: 'en'
      },
      {
        domain: 'example.nl',
        defaultLocale: 'nl'
      }
    ]
  }
}

语言检测

Next.js 10 在 / 路由上提供基于 Accept-Language 标头的内置语言检测功能,目前所有现代浏览器均支持此项检测。配置的语言环境将与 Accept-Language 标头相匹配,而后根据预设策略进行重新定向。

搜索引擎优化

Next.js 能够感知用户所访问页面的语言类别,因此会自动将 lang 属性添加至标签当中。

但 Next.js 无法识别出页面的变体,因此需要由您使用 next/head 添加 hreflang 元标签。关于 hreflang 元标签的更多详细信息,请参阅 谷歌 Webmasters 说明文档。

Next.js 还将提供更多国际化选项

国际化路由只是 Next.js 一系列国际化功能中的一种,旨在降低项目国际化与本地化的实现难度。国际化路由能够与大部分 React 国际化库相集成。

要了解关于国际化路由的更多详细信息,请参阅 国际化路由说明文档。

Next.js Analytics

在 Vercel,我们非常了解用户在性能衡量方面面临的挑战。

目前,网站访问者对于性能变得愈发敏感。一旦页面加载时间超过 3 秒,则 50% 以上的用户都会关闭当前站点。在电子商务领域,人们发现只要将加载时间缩短 1/10 秒,即可将客户转化率提升 1%。

考虑到性能的重要意义,我们在 Next.js 10 中推出了 Next.js Analytics,专门用于跟踪实际性能指标并将结果反馈至您的开发工作流当中。

使用 Next.js Analytics:

您可以真正实现对性能的持续测量。

相较于以往通过开发设备进行测量,现在您可以通过访问者的实际设备获取测量结果。

Next.js Analytics 旨在关注整体性能态势,深入了解访问者情况及其在使用应用程序时感受到的性能。

考虑到影响性能的因素多种多样,我们一直坚持对实际数据的收集。性能下降问题可能有多方面原因,例如第三方脚本与样式表、第一方字体、图像及视频过大或者加载过慢等。

Core Web Vitals

谷歌与网络性能工作组共同建立了一套指标,用以准确衡量用户体验到的网站性能,即 Web Vitals。Web Vitals 负责跟踪网站可感知的加载速度、响应速度与视觉稳定性指标,借此评判目标网站的整体使用感受。

感知加载速度可以通过“最大内容绘制”(简称 LCP)指标来衡量,也可以由页面内所有内容的显示速度来衡量。例如,当我们打开某款运动鞋的链接时,从看到运动鞋图片、显示价格到加载好可点击的购物车按钮的整个时间周期,即为 LCP。

您还可以通过“首次输入延迟”(FID)来衡量页面的响应速度,借此判断用户需要等待多长时间才能首次与页面正常交互。例如,从单击“添加到购物车”到购物车中商品数量实际增加之间的时间,即为 FID。

最后,视觉稳定性则主要通过累积布局偏移来衡量,即显示内容在初步展现给用户之后,还有多少元素会出现移位。例如,很多朋友都经历过本来想点按钮,却错误点上了突然显示出来的图片的尴尬,这就是所谓布局偏移。

对于实际用户,请围绕上述 Web Vital 指标持续进行衡量与关注。网站的实际性能可能会因用户设备、网络状况或者页面交互方式而有所差异。另外,不同用户看到的个性化内容或广告也会有所不同,这一切都会给最终性能造成直接影响。

模拟测试无法捕捉到这些重要信号。

Next.js Analytics 使您能够捕捉到真实结果,而不再是粗略的综合性基准。这项功能令持续测量成为可能,并将真实性能融入到开发者的工作流当中。

您可访问 nextjs.org/analytics 以了解如何在应用程序内使用 Next.js Analytics 的详尽说明。

Next.js Commerce

电子商务已经成为现代网络最重要的用途之一。Next.js 10 也为您带来一款强大的新型电子商务工具。

我们与 BigCommerce 合作发布了 Next.js Commerce,这是一款用于电子商务网站的多合一启动套件。只需单击几下,Next.js 开发者即可克隆、部署其中的各项功能并充分进行自定义。请访问 nextjs.org/commerce 立即体验。

React 17 支持

React 17 并未对 Next.js 造成太多影响,只需要进行一些维护性的变更,例如更新对等项依赖关系等。在使用 React 17 时,新的 JSX 转换将自动启用,您无需更改任何配置。

您只需要升级 Next.js 与 React,即可马上开始使用 React 17:

代码语言:javascript
复制
npm install next@latest react@latest react-dom@latest

getStaticProps / getServerSideProps Fast Refresh

在对 getStaticProps 与 getServerSideProps 函数进行编辑时,Next.js 现在会自动重新运行这些函数并应用新数据。以此为基础,您无需刷新当前页面即可实现快速迭代。

要了解关于 getStaticProps 及 getServerSideProps 的更多详细信息,请参阅数据获取说明文档

Fast Refresh for MDX

在配合 MDX 使用 Next.js 时,您现在可以使用 Fast Refresh 通过 @next/mdx 变更 MDX 内容,使得浏览器不必对正在编辑的页面进行重新加载。

@next/mdx 说明文档对于在 Next.js 中设置 MDX 的流程做出了详细解释:

从第三方 React 组件处导入 CSS

现在,您可以从 React 组件之内导入第三方 css。这意味着您可以针对单一组件对 CSS 进行代码拆分。例如,现在您可以直接使用 react-datepicker 库,且无需在 _app.js 中导入 CSS:

代码语言:javascript
复制
 importDatePickerfrom'react-datepicker'
import'react-datepicker/dist/react-datepicker.css'

关于 Next.js 如何实现 CSS 导入的更多详细信息,请参阅 内置 CSS 支持说明文档

自动解析 href

如果您之前使用过动态路由,估计也遇到过需要为 next/link 提供 href 及 as 属性的情况。操作过程类似于:

代码语言:javascript
复制
 <Linkhref="/categories/[slug]"as="/categories/books">

此时 Next.js 会插入 href 作为动态参数;但如果开发人员忘记在 href 中添加 as,或者忘记之前已经添加过 as 属性,则会导致页面转换时不使用客户端路由的冲突。

几个月前,我们开始着手解决这个问题,旨在改善开发人员及最终用户的实际体验。我们希望分步推进,提供一套能够自动解决 href 问题的方案。

我们很高兴地宣布,作为 Next.js 10 的新特性,您在大多数用例中已经不必使用 as 属性。这将极大简化开发人员的工作流程,提高最终用户体验。

这项变更还全面向下兼容,您既可以使用新的设定,也可以继续沿用原有 href 与 as。

要实现自动 href 解析,您只需要对 next/link 的用法做出调整,要求 href 保留此前的 as 值作为属性。

关于 next.link 与客户端路由的更多详细信息,请参阅 next/link 说明文档。

@next/codemod CLI

我们一直在努力通过全面的向下兼容性控制 Next.js 的升级影响。我们会先对用户们普遍不满意的功能进行调整,以此为基础引入新的解决方案。除此之外,我们还针对所有 Next.js 功能进行了广泛的集成测试,包括复制本地开发流程进行实际测试。

如果放弃 Next.js 中的某项功能会给代码库造成较大影响时,我们会将其创建为一个 codemod。Codemod 是一种自动化代码转换机制,供您在项目之上运行以实现源代码更新。

例如,我们曾发布一个 codemod,用于将指标函数与匿名函数更新为命名函数。之所以决定进行更新,是因为之前的 React Fast Refresh 无法将这些函数检测为有效的 React 组件。同样的,React hooks eslint 规则也无法将该函数视为 React 组件。

在 Next.js 10 当中,我们发布了新的 Next.js codemods CLI 工具,使您能够通过单一命令完成应用程序更新:npx @next/codemod。

要了解关于 codemods 的更多详细信息,请参阅 Next.js Codemods 说明文档

取消 getStaticPaths 回退

在 Next.js 9.3 中,我们引入了 getStaticProps 与 getStaticPaths 以在 getStaticPaths 当中返回 fallback 属性。其中 fallback 属性允许用户在无需完全重建的前提下,提供静态 HTML 文件以生成新的静态页面,并在后续请求中逐步替换新的呈现内容。过去几个月中,不少企业反馈称他们喜欢这项功能,但希望能稍加调整:当用户首次请求页面时,最好能够阻止预渲染。在初始渲染完成之后,再将该页面重复用于响应后续请求。

在 Next.js 10 中,我们解决了这个问题。

此次我们为 getStaticPaths 带来了新的 fallback: 'blocking’模式,保证不再向浏览器发送任何静态回退内容,转而等待初始请求再执行预渲染。

代码语言:javascript
复制
 export function getStaticPaths() {
  return {
    // enables blocking mode for the fallback behavior
    fallback: 'blocking'
  }
}

关于如何通过 fallback 行为逐步生成新的静态页面的更多详细信息,请参阅 fallback 说明文档

总结

我们对于 Next.js 采用率的持续增长感到无缘欣慰:

  • 自 9.5 版本发布以来,我们已经拥有 1300 多位独立贡献者,包括 120 多位新加入的贡献者。
  • 在 GitHub 上,我们的项目已经获得 54800 多次打分。

欢迎大家通过 GitHub Discussions 加入 Next.js 社区大家族。通过这里的社区空间,您可以与其他 Next.js 用户联系,随意提问并分享您的工作成果。

原文链接:

https://nextjs.org/blog/next-10

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/ei4jdyaRI6vuffd2aDq8
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券