跳至内容
返回博客

2020年10月27日,星期二

Next.js 10

发布者

我们很高兴地推出 Next.js 10,其特点包括

内置图片组件和自动图片优化

我们使用 Next.js 的目标是改进两件事:开发人员体验和用户体验。

今年,我们已经投入了大量精力来改善开发人员体验和提高所有 Next.js 应用程序的性能。我们专注于减少浏览器需要加载的 JavaScript 量。

我们引入了超过 **20 个新功能**,这些功能可以提高性能和开发人员体验。同时,Next.js 核心代码的 JavaScript 大小 **减少了 16%**。

1 月份,我们与 Google Chrome 团队合作,推出了一种新的最佳 JavaScript 代码分割策略。

例如,Barnebys 的应用程序大小 **减少了 23%**,而 Sumup 的最大 JavaScript 包大小 **减少了 70%**。这些改进是在 **无需更改** 其 Next.js 应用程序中的任何代码的情况下实现的。

公司只需将 Next.js 升级到最新版本,即可自动采用这种新策略。

网络上的图片

虽然我们专注于减少浏览器需要加载的 JavaScript 量取得了成效,但网络不仅仅是 Javascript:它还包括标记和图片。

图片占据网页总字节数的 50%。

图片对最大内容绘制有很大影响,因为它们通常是页面加载时最大的可见元素。最大内容绘制是 Google 将在其搜索排名中使用的核心网络指标 很快

一半的图片大小超过 1 MB,这意味着它们没有针对网络显示进行优化。

如今,用户使用手机、平板电脑和笔记本电脑浏览网页,但图片仍然是“一刀切”。例如:网站加载 2000x2000 像素的图片,但手机却只显示 100x100 像素的图片。

此外,网页上 30% 的图片位于初始视口之外,这意味着浏览器加载用户在向下滚动页面之前看不到的图片。

图片通常没有 widthheight 属性,导致页面加载时图片跳动。这会影响累积布局偏移核心网络指标。

网站上 99.7% 的图片没有使用 WebP 等现代图片格式。

为了以高性能的方式在网页上使用图片,需要考虑很多方面:尺寸、大小、延迟加载和现代图片格式。

开发者必须设置复杂的构建工具来优化图片,但是这些工具通常不涵盖来自外部数据源的用户提交的图片,使得无法优化所有图片。

这项不可能完成的开发任务不可避免地会导致令人沮丧的最终用户体验。

Next.js 图片组件

我们很高兴地宣布我们针对网页上高性能图片的解决方案:Next.js 图片组件和自动图片优化。

从最基本的层面来说,Next.js 图片组件只是 HTML <img> 元素的替代品,为现代网页而进化。

<img
  src="/profile-picture.jpg"
  width="400"
  height="400"
  alt="Profile Picture"
/>
import Image from 'next/image';
<Image
  src="/profile-picture.jpg"
  width="400"
  height="400"
  alt="Profile Picture"
/>;

Google Chrome 团队帮助创建了这个 React 组件,通过将最佳实践设为默认值来提高页面性能。

使用 next/image 组件时,图片会自动延迟加载,这意味着只有当用户即将看到图片时才会渲染它。这可以防止加载初始视口之外的 30% 图片。

图片尺寸得到强制执行,允许浏览器立即渲染图片所需的空间,而不是在加载完成后跳入,从而防止布局偏移。

虽然 HTML <img> 元素上的 widthheight 属性可能会导致响应式布局出现问题,但**使用 next/image 时则不会出现这种情况**。使用 next/image 时,图片会根据提供的 widthheight 属性的纵横比自动进行响应式调整。

开发者可以标记初始视口中的图片,允许 Next.js 自动预加载这些图片。预加载初始视口中的图片已显示出将最大内容绘制时间提高高达 50% 的效果。

自动图片优化

即使与 HTML <img> 元素相比有了这些改进,仍然存在一个主要问题。2000 x 2000 像素的图片被发送到渲染较小图片的手机上。

在 Next.js 10 中,我们也解决了这个问题。next/image 组件将通过内置的图片优化功能自动生成更小的尺寸。

内置的图片优化功能会自动以 WebP 等现代图片格式提供图片,如果浏览器支持的话,WebP 的大小大约比 JPEG 小 30%。它还允许 Next.js 自动采用**未来**的图片格式,并将其提供给支持这些格式的浏览器。

图片优化适用于任何图片源。即使图片来自外部数据源(例如 CMS),它们也会被优化。

Next.js 10 不是在构建时优化图片,而是在用户请求时按需优化图片。与静态网站生成器和仅静态解决方案不同,无论发布 10 张图片还是 1000 万张图片,您的构建时间都不会增加。

结论

新的 next/image 组件和自动图片优化是强大的新原语,将极大地改善用户体验。

next/image 组件处理自动延迟加载、关键图片的预加载、跨设备的正确尺寸调整,并自动支持现代格式。这些功能适用于任何来源的图片。

我们期待着看到这些新原语将使您的用户体验变得多么快。

有关更多详细信息,请查看Next.js 图片组件和自动图片优化文档

国际化路由

今年,一些企业和社区成员帮助我们的团队了解了国际化的重要性。

例如,我们了解到,如果网站被翻译过,72% 的消费者更有可能留在您的网站上,55% 的消费者表示他们只从使用其母语的电子商务网站购买商品。

如果您计划进入不同的国家/地区市场,国际化您的项目对于成功至关重要。

国际化项目有两个主要支柱:翻译和路由。

许多 React 库为应用程序做好翻译准备,但它们中的大多数都期望您手动处理路由,并且通常只适用于一种渲染策略。

因此,作为 Next.js 10 的一部分,我们发布了对国际化路由和语言检测的内置支持。

对国际化路由的内置支持支持 Next.js 的混合策略,因此您可以根据每个页面的需要选择静态生成或服务器渲染。

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

对于这两种策略,您首先在 Next.js 配置中配置区域设置。

next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'nl'],
    defaultLocale: 'en',
  },
};

区域设置是UTS 区域设置标识符,这是一种定义区域设置的标准化格式。

通常,区域设置标识符由语言、区域和脚本组成,用连字符分隔:language-region-script。区域和脚本是可选的。例如

  • en-US - 美式英语
  • nl-NL - 荷兰语(荷兰)
  • nl - 荷兰语,没有特定区域

配置好区域设置后,您可以选择子路径或域名路由。

子路径路由

子路径路由将区域设置放在 URL 中。这允许所有语言都存在于单个域名上。

例如,您可以在 URL 中插入区域设置,例如 /nl-nl/blog/en/blog

域名路由

域名路由使您能够将区域设置映射到顶级域名。例如example.nl可以映射到 nl 区域设置,而example.com可以映射到 en 区域设置。

域名路由需要一些额外的配置来了解如何路由域名。

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 属性添加到 <html> 标签中。

Next.js 不了解页面的变体,因此您需要使用 next/head 添加 hreflang 元标记。您可以在Google 网站管理员文档中了解有关 hreflang 的更多信息。

Next.js 中国际化的未来

国际化路由是旨在简化项目国际化和本地化的一系列功能中的第一个。国际化路由允许与大多数 React 国际化库集成。

要了解有关国际化路由的更多信息,请查看国际化路由文档

Next.js 速度洞察

在 Vercel,我们知道无法衡量的东西就无法修复。

您的访问者对网站性能越来越敏感。超过 50% 的访问者会放弃您的网站,如果加载时间超过 3 秒。如果您从事电子商务,许多人发现将加载时间缩短 1/10 秒会导致转化率提高 1%

由于性能对您的成功至关重要,我们很自豪地发布 Next.js 速度洞察。该解决方案用于跟踪真实世界性能指标并将这些洞察反馈到您的开发工作流程中。

使用 Next.js 速度洞察

不再进行一次测量,您现在将持续进行测量。

不再在您的开发设备上进行测量,测量数据将来自您的访问者使用的实际设备。

Next.js 速度洞察旨在关注全局,深入了解您的受众以及您的应用程序如何为您的用户提供服务。

我们如此坚持收集真实数据,是因为性能不佳的原因并不总是最明显的。性能下降可能来自各种地方——第三方脚本和样式表,或者尺寸过大或加载缓慢的第一方字体、图像和视频。

核心 Web 指标

Google 与Web 性能工作组合作,建立了一套指标来准确衡量用户体验您网站性能的方式:恰如其分地命名为 Web 指标。Web 指标是跟踪网站的感知加载速度、响应能力和视觉稳定性的指标——这三者对网站的整体健康至关重要!

感知加载速度可以通过最大内容绘制来衡量,即页面所有内容都已显示时。例如,当我打开一个购买一双运动鞋的链接时——在我看到运动鞋、价格和添加到购物车按钮之前经过的时间就是 LCP。

页面响应能力可以通过首次输入延迟来衡量,该指标衡量用户必须等待多长时间才能看到他们与页面首次交互的反应。例如,我点击添加到购物车和购物车中商品数量增加之间的时间就是 FID。

最后,视觉稳定性可以通过累积布局偏移来衡量,即元素在显示给用户后移动的程度。例如,我们都遇到过试图点击由于图像加载延迟而移动的按钮的挫败感——这就是布局偏移。

持续测量和符合您真实用户的这些 Web 指标至关重要。这是真正了解您的网站如何为用户提供服务的唯一方法。您的网站的性能可能会根据用户的设备及其网络状况或他们与页面的交互方式而发生巨大变化。加载个性化内容或广告的网站也可能体验到用户之间性能的巨大差异。

模拟测试无法捕获这些重要的信号。

Next.js 速度洞察允许您捕获真实世界的洞察,而不是合成基准。它支持持续的测量流,而不是依赖于偶尔的测试,确保它是您开发工作流程的一部分。

Next.js 速度洞察允许您捕获真实世界的洞察,而不是合成基准。它支持持续的流测量,而不是依赖于偶尔的测试,确保它是您开发工作流程的一部分

访问nextjs.org/analytics立即了解如何在您的应用程序中启用它。

Next.js 电子商务

电子商务是网络最重要的用途之一。新的 Next.js 10 功能是电子商务的强大新工具。

因此,今天,我们与 BigCommerce 合作,发布了 Next.js 电子商务,这是一个面向电子商务网站的一体化 React 入门套件。只需点击几下,Next.js 开发人员就可以克隆、部署和完全自定义它。立即在nextjs.org/commerce开始。

React 17 支持

React 17 对 Next.js 没有任何重大更改,但是需要进行一些维护更改,例如更新对等依赖项。当使用 React 17 时,新的 JSX 转换会自动启用,无需进行任何配置更改。

要开始使用 React 17,您只需升级 Next.js 和 React 即可

终端
npm install next@latest react@latest react-dom@latest

getStaticProps / getServerSideProps 快速刷新

在对您的getStaticPropsgetServerSideProps函数进行编辑时,Next.js 现在将自动重新运行该函数并应用新数据。这使您能够更快地迭代,而无需刷新页面。

要了解有关getStaticPropsgetServerSideProps的更多信息,您可以阅读数据获取文档

MDX 的快速刷新

当通过@next/mdx将 Next.js 与 MDX 结合使用时,更改 MDX 内容现在将利用快速刷新,确保浏览器在编辑时无需重新加载页面。

@next/mdx 文档指导您如何使用 Next.js 设置 MDX。

从第三方 React 组件导入 CSS

您现在可以在 React 组件内部导入第三方 CSS。这允许仅对单个组件进行代码拆分的 CSS。例如,您现在可以使用react-datepicker库,而无需在_app.js中导入 CSS

components/MyComponent.js
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
 
function MyComponent() {}

您可以参考内置 CSS 支持文档,以了解有关 Next.js 如何处理 CSS 导入的更多信息。

自动解析href

如果您之前使用过动态路由,您可能之前遇到过必须同时为next/link提供hrefas属性的情况。它看起来像这样

<Link href="/categories/[slug]" as="/categories/books" />

这允许 Next.js 为动态参数插入 href,但是,当开发人员忘记添加as或在href中添加as导致页面转换不使用客户端路由时,会导致摩擦。

几个月前,我们着手解决开发人员的这种摩擦,其主要目标是改善开发人员体验和最终用户体验。我们逐步朝着允许自动解析href的解决方案努力。

我们很高兴地宣布,作为 Next.js 10 的一部分,您不再需要在大多数用例中使用as属性。这减少了开发者的负担,并改善了最终用户体验。

此更改完全向后兼容,如果您当前同时使用hrefas,则保留现有行为。

为了采用自动href解析,您只需将next/link的使用更改为仅使用href,其中包含您之前在as属性中使用的值。

<Link href="/categories/books" />

要了解有关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 <transform> <path>

要了解有关 codemods 的更多信息,您可以查看Next.js Codemods 文档

getStaticPaths 的阻塞回退

在 Next.js 9.3 中,我们引入了getStaticPropsgetStaticPaths以及在getStaticPaths中返回fallback属性的功能。fallback属性允许生成额外的静态页面,而无需进行完整重建,最初提供一个静态 HTML 文件,然后在后续请求中将其替换为完全渲染的内容。在过去几个月里,我们收到了很多来自希望获得类似但略有不同的行为的公司反馈:当用户第一次请求页面时,进行阻塞预渲染。在此初始渲染之后,页面将被重用于后续请求。

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

我们很高兴地宣布getStaticPaths的新fallback: 'blocking'模式,该模式启用了阻塞行为,其中不会向浏览器发送静态回退。相反,初始请求将等待预渲染。

pages/posts/[id].js
export function getStaticPaths() {
  return {
    // enables blocking mode for the fallback behavior
    fallback: 'blocking',
  };
}

要了解有关增量生成额外静态页面的fallback行为的更多信息,您可以参考fallback文档

getStaticProps / getServerSideProps 的重定向和 notFound 支持

自从引入getStaticPropsgetServerSideProps以来,我们注意到用户需要返回重定向和 404 响应的情况。为了帮助简化这些情况,我们现在允许从getStaticPropsgetServerSideProps返回两个新字段:notFoundredirect

notFound 支持

当使用true返回notFound字段时,将返回默认的 404 页面,状态代码为404。这允许您避免使用 SSG 生成额外页面,并且不必手动处理渲染 404 页面。

pages/posts/[id].js
export function getStaticProps() {
  return {
    // returns the default 404 page with a status code of 404
    notFound: true,
  };
}

redirect 支持

现在可以返回重定向,其中包含destination以及重定向是否应该是永久性的,例如permanent: true。还可以返回可选的statusCode来代替permanent字段,以用于您需要使用特定状态而不是默认状态的情况。

pages/posts/[id].js
export function getStaticProps() {
  return {
    // returns a redirect to an internal page `/another-page`
    redirect: {
      destination: '/another-page',
      permanent: false,
    },
  };
}
pages/posts/[id].js
export function getServerSideProps() {
  return {
    // returns a redirect to an external domain `example.com`
    redirect: {
      destination: 'https://example.com',
      permanent: false,
    },
  };
}

结论

我们很高兴看到 Next.js 采用率的持续增长

  • 我们拥有超过1,300名独立贡献者,自 9.5 版本发布以来,新增贡献者超过120名。
  • 在 GitHub 上,该项目已被加星超过54,800次。

加入 Next.js 社区,访问GitHub 讨论. 讨论是一个社区空间,允许您与其他 Next.js 用户联系,并自由提问或分享您的工作。

致谢

我们感谢我们的社区,包括所有帮助塑造此版本的外部反馈和贡献。

此版本由以下人员的贡献带来:@ijjk、@adebiyial、@elliottsj、@saintmalik、@HaNdTriX、@prateekbh、@amirsaeed671、@paambaati、@imagentleman、@gregrickaby、@Janpot、@atcastle、@Kirkhammetz、@remorses、@davidsonsns、@kmkzt、@slawekkolodziej、@Timer、@styfle、@timneutkens、@ykzts、@ashconnell、@orYoffe、@lfades、@justinwhall、@fbaiodias、@ludofischer、@felipeguilhermefs、@gr-qft、@TasukuUno、@YichiZ、@weichienhung、@seosmmbusiness、@HsuTing、@gsimone、@peduarte、@ztanner、@neighborhood999、@chibicode、@merceyz、@opudalo、@lunchboxav、@mohsen1、@akd-io、@justman00、@helloworld、@devknoll、@borekb、@ArthurMaverick、@sakito21、@TrySound、@omBratteng、@svenheden、@hallaji、@kettanaito、@vvo、@m-lautenbach、@jensmeindertsma、@Zeko369、@longlho、@stefanprobst、@laugharn、@sdornan、@daneroo、@mohd-akram、@austingmhuang、@sphilee、@devinekadeni、@Bacher、@nghiepit、@tomasdisk、@leader22、@paulogdm、@284km、@belgattitude、@geritol、@stigkj、@sampoder、@samrobbins85、@Pitasi、@digitalPlayer1125、@timfee、@plug-n-play、@philihp、@leerob、@dylanjha、@Kerumen、@rdimaio、@jorisw、@zerbinidamata、@jamesgeorge007、@Jashnm 和 @futantan!