内置组件抽象化了实现常见UI优化的复杂性。这些组件包括:
元数据可帮助搜索引擎更好地理解你的内容(从而提高搜索引擎优化效果),并允许你自定义内容在社交媒体上的展示方式,帮助你在不同平台上创建更具吸引力和一致性的用户体验。
Next.js/public文件夹可用于提供静态资源,例如:图片、字体和其他文件。/public文件夹中的文件还可由CDN提供商缓存,以便高效分发。
示例:
importImagefrom'next/image'然后,你就可以定义图片的src(本地或远程)。
要使用本地图像,请import你的.jpg、.png或.webp图像文件。
要使用远程图片,src属性应为URL字符串。
有时,你可能想优化远程图片,但仍需使用内置的Next.js图片优化API。为此,请将loader保留为默认设置,并为图片srcprop输入绝对URL。
为保护应用程序不受恶意用户的攻击,必须定义一个远程主机名列表,以便与next/image组件一起使用。
Next.js应用程序的默认加载器使用内置的图像优化API,该API可优化网络上任何地方的图像,然后直接从Next.js网络服务器提供图像。如果想直接从CDN或图像服务器提供图像,只需编写几行JavaScript,就能编写自己的加载器函数。
一旦确定了LCP图像,就可以像这样添加属性:
由于next/image的设计是为了保证良好的性能效果,因此在使用时不能造成布局偏移,必须以以下三种方式之一确定大小:
如果我不知道图像的尺寸怎么办?
如果你在不知道图片大小的情况下从源访问图片,你可以采取以下几种方法:
next/font将自动优化你的字体(包括自定义字体),并移除外部网络请求,以改善隐私和性能。
next/font包含内置的自动自托管功能,可用于任何字体文件。这意味着,由于使用了底层CSSsize-adjust属性,你可以以最佳方式加载网络字体,而不会出现布局偏移。
这一新的字体系统还能让你方便地使用所有Google字体,同时兼顾性能和隐私。CSS和字体文件会在构建时下载,并与其他静态资源一起自行托管。浏览器不会向Google发送任何请求。
自动自我托管任何Google字体。字体包含在部署中,由与部署相同的域提供。浏览器不会向Google发送任何请求。
//app/layout.jsconstroboto=Roboto({weight:['400','700'],style:['normal','italic'],subsets:['latin'],display:'swap',})需要知道:对于包含多个单词的字体名称,请使用下划线(_)。例如:RobotoMono应导入为Roboto_Mono。
这可以通过在函数调用中添加来实现:
你可以在应用程序中导入和使用多种字体。可以采取两种方法。
第一种方法是创建一个实用程序函数,用于导出、导入字体并在需要时应用字体的className。这样可以确保只有在渲染时才会预载字体:
建议:谨慎使用多种字体,因为每一种新字体都会给客户端带来额外的下载资源。
在下面的例子中,我们使用了next/font/google中的Inter字体(你可以使用Google或本地字体中的任何字体)。使用variable选项加载字体,定义CSS变量名,并将其赋值给inter。然后,使用inter.variable将CSS变量添加到HTML文档中。
//tailwind.config.js/**@type{import('tailwindcss').Config}*/module.exports={content:['./pages/**/*.{js,ts,jsx,tsx}','./components/**/*.{js,ts,jsx,tsx}','./app/**/*.{js,ts,jsx,tsx}',],theme:{extend:{fontFamily:{sans:['var(--font-inter)'],mono:['var(--font-roboto-mono)'],},},},plugins:[],}现在,你可以使用font-sans和font-mono实用程序类将字体应用到元素中。
每次调用localFont或Google字体函数时,该字体都会在应用程序中作为一个实例托管。因此,如果在多个文件中加载相同的字体函数,就会托管同一字体的多个实例。在这种情况下,建议采取以下措施:
要为多条路由加载第三方脚本,请导入next/script并将脚本直接包含在布局组件中:
要为所有路由加载第三方脚本,请导入next/script,并将脚本直接包含在根布局中:
建议:我们建议仅在特定页面或布局中包含第三方脚本,以尽量减少对性能的不必要影响。
虽然next/script的默认行为允许你在任何页面或布局中加载第三方脚本,但你可以使用strategy属性对其加载行为进行微调:
此策略仍处于试验阶段,只有在next.config.js中启用nextScriptWorkers标志后才能使用:
//next.config.jsmodule.exports={experimental:{nextScriptWorkers:true,},}然后,运行next(通常是npmrundev或yarndev),Next.js就会引导你安装所需的软件包,完成设置:
npmrundev你会看到如下说明:请运行npminstall@builder.io/partytown来安装Partytown。
设置完成后,定义strategy="worker"将自动在你的应用程序中实例化Partytown,并将脚本卸载到网络worker。
脚本组件还支持内联脚本,即不从外部文件加载的脚本。只需将JavaScript放在大括号中,即可编写内联脚本:
事件处理程序可与脚本组件一起使用,以便在特定事件发生后执行附加代码:
Next.js有一个元数据API,可用于定义应用程序元数据(例如:HTMLhead元素中的meta和link标签),以提高搜索引擎优化和网络共享性。
有两种方法可以为应用程序添加元数据:
要定义静态元数据,请从layout.js或静态的page.js文件中导出一个Metadata对象。
你可以使用generateMetadata函数来fetch需要动态值的元数据。
需要知道:
这些特殊文件可用于元数据:
你可以将这些文件用于静态元数据,也可以用代码编程生成这些文件。
基于文件的元数据具有更高的优先级,将优先于任何基于配置的元数据。
即使路由没有定义元数据,也会添加两个默认meta标签:
元数据是按顺序评估的,从根代码段开始,直到最接近最终page.js代码段的代码段。例如:
如果想在片段之间共享某些嵌套字段,同时覆盖其他字段,可以将它们提取到一个单独的变量中:
ImageResponse构造函数允许你使用JSX和CSS生成动态图像。这对于创建OpenGraph图像、Twitter卡片等社交媒体图像非常有用。
ImageResponse使用Edge运行时,Next.js会自动将正确的头添加到edge缓存的图片中,从而帮助提高性能并减少重新计算。
要使用它,可以从next/og导入ImageResponse:
JSON-LD是一种结构化数据格式,搜索引擎可以用它来理解你的内容。例如:你可以用它来描述一个人、一个事件、一个组织、一部电影、一本书、一份食谱以及许多其他类型的实体。
例如,如果在public文件夹中添加me.png,下面的代码就可以访问该图片:
运行以下命令安装插件:
npmi@next/bundle-analyzer#oryarnadd@next/bundle-analyzer#orpnpmadd@next/bundle-analyzer然后,将包分析器的设置添加到next.config.js中。
//next.config.jsconstwithBundleAnalyzer=require('@next/bundle-analyzer')({enabled:process.env.ANALYZE==='true',})/**@type{import('next').NextConfig}*/constnextConfig={}module.exports=withBundleAnalyzer(nextConfig)分析你的包运行以下命令分析包:
ANALYZE=truenpmrunbuild#orANALYZE=trueyarnbuild#orANALYZE=truepnpmbuild报告将在浏览器中打开三个新标签页,你可以检查它们。在开发过程中和部署网站前定期这样做,可以帮助你更早地识别大型包,并构建性能更高的应用程序。
通过它,你可以延迟加载客户端组件和导入的库,只有在需要时才将它们包含在客户端包中。例如:你可能想推迟加载一个模态框,直到用户点击打开它。
有两种方法可以在Next.js中实现懒加载:
如果要禁用客户端组件的预渲染,可以将ssr选项设为false:
constComponentC=dynamic(()=>import('../components/C'),{ssr:false})导入服务器组件如果动态导入服务器组件,只有作为服务器组件子组件的客户端组件才会被懒加载,而不是服务器组件本身。
你可以使用name属性处理这些指标的所有结果。
//app/components/web-vitals.tsx'useclient'import{useReportWebVitals}from'next/web-vitals'exportfunctionWebVitals(){useReportWebVitals((metric)=>{switch(metric.name){case'FCP':{//处理FCP结果}case'LCP':{//处理LCP结果}//...}})}将结果发送到外部系统你可以将结果发送到任何端点,以衡量和跟踪网站上的真实用户性能。例如:
仪表是使用代码将监控和日志工具集成到应用程序中的过程。这样,你就可以跟踪应用程序的性能和行为,并调试生产中的问题。
Next.js提供了一个register函数,该函数可从项目根目录(如果使用src文件夹,则位于src文件夹内)中的instrumentation.ts|js文件导出。每当启动一个新的Next.js服务器实例时,Next.js就会调用register函数。
部署register函数后,每次冷启动时都会调用该函数(但在每个环境中都会调用一次)。
你可以在instrumentation.ts中导入具有副作用的文件,你可能希望在register函数中使用这些文件,如下例所示:
//your-project/instrumentation.tsimport{init}from'package-init'exportfunctionregister(){init()}不过,我们建议使用register函数中的import来导入具有副作用的文件。下面的示例演示了在register函数中import的基本用法:
//your-project/instrumentation.tsexportasyncfunctionregister(){awaitimport('package-with-side-effect')}这样做可以将所有副作用集中在代码中的一个地方,避免导入文件造成任何意想不到的后果。
我们会在所有环境中调用register,因此有必要有条件地导入任何不支持edge和nodejs的代码。你可以使用环境变量NEXT_RUNTIME来获取当前环境。导入特定环境的代码如下所示:
//your-project/instrumentation.tsexportasyncfunctionregister(){if(process.env.NEXT_RUNTIME==='nodejs'){awaitimport('./instrumentation-node')}if(process.env.NEXT_RUNTIME==='edge'){awaitimport('./instrumentation-edge')}}OpenTelemetry需要知道:此功能是试验性的,你需要在next.config.js中提供experimental.instrumentationHook=true;以明确选择加入。
可观察性对于了解和优化Next.js应用程序的行为和性能至关重要。
随着应用程序变得越来越复杂,识别和诊断可能出现的问题也变得越来越困难。通过利用日志和指标等可观察性工具,开发人员可以深入了解应用程序的行为,并确定需要优化的领域。有了可观察性,开发人员就能在问题演变成重大问题之前主动加以解决,并提供更好的用户体验。因此,强烈建议在Next.js应用程序中使用可观察性来提高性能、优化资源和增强用户体验。
我们建议使用OpenTelemetry来检测应用程序。这是一种与平台无关的应用程序检测方式,允许你在不更改代码的情况下更改可观察性提供者。阅读OpenTelemetry官方文档了解有关OpenTelemetry及其工作原理的更多信息。
本文档中使用了Span、Trace或Exporter等术语,所有这些术语都可以在OpenTelemetryObservabilityPrimer中找到。
Next.js支持开箱即用的OpenTelemetry仪表,这意味着我们已经为Next.js本身安装了仪器。启用OpenTelemetry后,我们会自动将所有代码(例如:getStaticProps)封装在带有有用属性的spans中。
需要知道:我们目前仅在无服务器功能中支持OpenTelemetry绑定。我们不为edge或客户端代码提供任何绑定。
OpenTelemetry具有可扩展性,但正确设置它可能相当繁琐。因此,我们准备了一个@vercel/otel软件包,帮助你快速入门。它不具有可扩展性,如果你需要自定义设置,则应手动配置OpenTelemetry。
使用之前,需要安装@vercel/otel:
//your-project/instrumentation.tsimport{registerOTel}from'@vercel/otel'exportfunctionregister(){registerOTel('next-app')}需要知道:
如果我们的封装程序@vercel/otel不能满足你的需求,你可以手动配置OpenTelemetry。
首先需要安装OpenTelemetry软件包:
如果一切运行正常,你应该可以看到标为GET/requested/pathname的根服务器跨度。该特定跟踪的所有其他跨度都将嵌套在该跨度之下。
Next.js会跟踪比默认情况下更多的跨度。要查看更多跨度,必须设置NEXT_OTEL_VERBOSE=1。
使用OpenTelemetry收集器部署时,可以使用@vercel/otel。它既可以在Vercel上部署,也可以自行部署。
我们确保OpenTelemetry在Vercel上开箱即用。
部署到其他平台也很简单。你需要启动自己的OpenTelemetry收集器来接收和处理来自Next.js应用程序的遥测数据。
安装并运行收集器后,就可以按照各自的部署指南将Next.js应用程序部署到所选平台。
npminstall@opentelemetry/api下面的示例演示了一个获取GitHubstars并添加自定义fetchGithubStars维度以跟踪获取请求结果的函数:
import{trace}from'@opentelemetry/api'exportasyncfunctionfetchGithubStars(){returnawaittrace.getTracer('nextjs-example').startActiveSpan('fetchGithubStars',async(span)=>{try{returnawaitgetValue()}finally{span.end()}})}register函数将在代码在新环境中运行前执行。你可以开始创建新的跨度,它们应该会被正确地添加到导出的跟踪中。
Next.js会自动为你设置多个跨度,以便为你提供有关应用程序性能的有用信息。
跨度属性遵循OpenTelemetry语义约定。我们还在next命名空间下添加了一些自定义属性:
此跨度表示传入Next.js应用程序的每个请求的根跨度。它跟踪HTTP方法、路由、目标和请求的状态代码。
属性:
此跨度表示在应用程序路由器中渲染路由的过程。
该跨度表示代码中执行的获取请求。
此跨度表示在应用程序路由器中执行API路由处理程序。
此跨度表示特定路由的getServerSideProps执行情况。
此跨度表示特定路由的getStaticProps执行情况。
该跨度表示为特定路由渲染文档的过程。
该跨度表示为特定页面生成元数据的过程(一个路由可以有多个这样的跨度)。
@next/third-parties是一个库,它提供了一系列组件和实用程序,可改善在Next.js应用程序中加载常用第三方库的性能和开发人员体验。
@next/third-parties提供的所有第三方集成都经过了性能和易用性方面的优化。
要开始使用,请安装@next/third-parties库:
npminstall@next/third-parties@latestnext@latest@next/third-parties目前是一个正在积极开发的实验性库。在我们努力添加更多第三方集成时,建议使用最新或金丝雀标志安装。
可从@next/third-parties/google中导入谷歌支持的所有第三方库。
GoogleTagManager组件可用于在页面中实例化一个Google标签管理器容器实例化到你的页面。默认情况下,它会在页面水合后获取原始内嵌脚本。
要为所有路径加载Google标签管理器,请直接在根布局中包含该组件,并输入GTM容器ID:
要为所有路由加载Google分析,请在根布局中直接包含该组件,并输入测量ID:
当浏览器历史状态发生变化时,Google分析会自动跟踪页面浏览。这意味着在Next.js路由之间进行客户端导航时,无需任何配置即可发送页面浏览数据。