整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Next.js 7.0正式发布:重新编译速度提高42

Next.js 7.0正式发布:重新编译速度提高42%,支持WebAssembly

者|Next.js 团队

译者|无明

出处丨前端之巅

在经过 26 次金丝雀发布和 340 万次下载之后,近日,我们正式发布了 Next.js 7.0,新功能包括:

  • DX 改进:启动速度提高 57%,重新编译速度提高 42%;
  • 使用 react-error-overlay 更好地报告错误;
  • 编译管道升级:Webpack 4 和 Babel 7;
  • 标准化的动态导入;
  • 静态 CDN 支持;
  • 较小的初始 HTML 载荷;
  • App 和 Page 之间的 React Context(服务器端渲染)。

DX 改进

Next.js 的主要目标之一是提供最佳的性能和开发者体验。最新版本为构建和调试管道带来了很多重大改进。

得益于 Webpack 4 和 Babel 7,以及我们对代码库做出的很多改进和优化,Next.js 现在在开发过程中的启动速度提高了 57%。

我们新增了增量编译缓存,让变更代码的构建速度快了 40%。

以下是我们收集的一些示例数据:


因为使用了 webpackbar,在开发和构建的同时可以看到更好的实时反馈:


使用 react-error-overlay 更好地报告错误

准确地渲染错误对于良好的开发和调试体验来说是至关重要的。到目前为止,我们可以渲染错误消息和堆栈跟踪信息。我们在此基础上更进一步,我们使用 react-error-overlay 来丰富堆栈跟踪信息:

  • 准确的服务器端和客户端错误位置;
  • 高亮显示错误来源;
  • 完整的堆栈跟踪信息。

这是之前和之后的错误显示比较:


另外,借助 react-error-overlay,你只需单击特定代码块就可以轻松打开文本编辑器。

支持 Webpack 4

从发布第一个版本以来,Next.js 一直使用 Webpack 来打包代码和重用丰富的插件。Next.js 现在使用了最新的 Webpack 4,其中包含很多改进和 bug 修复。

  • 支持.mjs 源文件;
  • 代码拆分改进;
  • 更好的摇树优化(删除未使用的代码)支持。

另一个新功能是支持 WebAssembly,Next.js 甚至可以进行 WebAssembly 服务器渲染。

这里有一个例子:

https://github.com/zeit/next.js/tree/canary/examples/with-webassembly

CSS 导入

因为使用了 Webpack 4,我们引入了一种从捆绑包中提取 CSS 的新方法,这个插件叫作 mini-extract-css-plugin(https://github.com/webpack-contrib/mini-css-extract-plugin)。

mini-extract-css-plugin 提供了 @zeit/next-css、@zeit/next-less、@zeit/next-sass 和 @zeit/next-stylus。

这些 Next.js 插件的新版本解决了与 CSS 导入相关的 20 个问题,例如,现在支持 import() 动态导入 CSS:

// components/my-dynamic-component.js
import './my-dynamic-component.css'
export default ()=> <h1>My dynamic component</h1>
// pages/index.js
import dynamic from 'next/dynamic'
const MyDynamicComponent=dynamic(import('../components/my-dynamic-component'))
export default ()=> <div>
 <MyDynamicComponent/>
</div>

一个重大改进是现在不再需要在 pages/_document.js 中添加一下内容:

<link rel="stylesheet" href="/_next/static/style.css" />

Next.js 会自动注入这个 CSS 文件。在生产环境中,Next.js 还会自动向 CSS URL 中添加内容哈希,当文件发生变更时,最终用户就不会得到旧文件,并且能够获得不可变的永久缓存。

简而言之,要在 Next.js 项目中支持导入.css 文件,只需要在 next.config.js 中注册 withCSS 插件:

const withCSS=require('@zeit/next-css')
module.exports=withCSS({/* my next config */})

标准化动态导入

从版本 3 开始,Next.js 就通过 next/dynamic 来支持动态导入。

作为这项技术的早期采用者,我们必须自己编写解决方案来处理 import()。

因此,Next.js 逐渐缺失 Webpack 后来引入的一些功能,包括 import()。

例如,无法手动命名和捆绑某些文件:

import(/* webpackChunkName: 'my-chunk' */ '../lib/my-library')

另一个例子是在 next/dyanmic 模块之外使用 import()。

从 Next.js 7 开始,我们不再直接使用默认的 import(),Next.js 为我们提供了开箱即用的 import() 支持。

这个变更也是完全向后兼容的。使用动态组件非常简单:

import dynamic from 'next/dynamic'
const MyComponent=dynamic(import('../components/my-component'))
export default ()=> {
 return <div>
 <MyComponent />
 </div>
}

这段代码的作用是为 my-component 创建一个新的 JavaScript 文件,并只在渲染< MyComponent/>时加载它。

最重要的是,如果没有进行渲染,< script>标记就不会出现在初始 HTML 文档中。

为了进一步简化我们的代码库并利用优秀的 React 生态系统,在 Next.js 7 中,我们使用 react-loadable 重写了 next/dynamic 模块。这为动态组件引入了两个很棒的新特性:

  • 使用 next/dynamic 的 timeout 选项设置超时;
  • 使用 next/dynamic 的 delay 选项设置组件加载延迟。例如,如果导入非常快,可以通过这个选项让加载组件在渲染加载状态之前等待一小段时间。

支持 Babel 7

Next.js 6 中就已经引入了 Babel 7 测试版。后来 Babel 7 稳定版本发布,现在,Next.js 7 正在使用这个新发布的稳定版 Babel 7。

一些主要特性:

  • Typescript 支持,在 Next.js 中可以使用 @zeit/next-
  • typescript;
  • 片段语法<>支持;
  • babel.config.js 支持;
  • 通过 overrides 属性将预设 / 插件应用于文件或目录的子集。

如果你的 Next.js 项目中没有自定义 Babel 配置,那么就不存在重大变更。

但如果你具有自定义 Babel 配置,则必须将相应的自定义插件 / 预设升级到最新版本。

如果你从 Next.js 6 以下的版本升级,可以使用 babel-upgrade 工具。

除了升级到 Babel 7 之外,当 NODE_ENV 被设置为 test 时,Next.js Babel 预设(next/babel)现在默认将 modules 选项设置为 commonjs。

这个配置选项通常是在 Next.js 项目中创建自定义.babelrc 的唯一理由:

{
 "env": {
 "development": {
 "presets": ["next/babel"]
 },
 "production": {
 "presets": ["next/babel"]
 },
 "test": {
 "presets": [["next/babel", { "preset-env": { "modules": "commonjs" } }]]
 }
 }
}

使用 Next.js 7,这将变成:

{
 "presets": ["next/babel"]
}

现在可以删除.babelrc,因为在没有 Babel 配置时,Next.js 将自动使用 next/babel。

较小的初始 HTML 载荷

Next.js 在预渲染 HTML 时会将页面内容放在< html>、< head>、< body>结构中,并包含页面所需的 JavaScript 文件。

这个初始载荷之前约为 1.62kB。在 Next.js 7 中,我们优化了初始 HTML 载荷,现在为 1.5kB,减少了 7.4%,让页面变得更加精简。


我们主要通过以下几种方式来缩小文件:

  • 移除 __next-error div;
  • 内联脚本被最小化,在未来的版本中,它们将被完全移除;
  • 去掉未使用的 NEXT_DATA 属性,例如 nextExport 和 assetPrefix 属性。

静态 CDN 支持

在 Next.js 5 中,我们引入了 assetPrefix 支持,让 Next.js 可以自动从某个位置(通常是 CDN)加载资源。如果你的 CDN 支持代理,可以使用这种办法。你可以像这样请求资源:

https://cdn.example.com/_next/static/<buildid>/pages/index.js

通常,CDN 先检查缓存中是否包含这个文件,否则直接从源中请求文件。

不过,某些解决方案需要将目录直接预先上传到 CDN 中。这样做的问题在于 Next.js 的 URL 结构与.next 文件夹中的文件夹结构不匹配。例如我们之前的例子:

https://cdn.example.com/_next/static/<buildid>/pages/index.js
// 映射到:
.next/page/index.js

在 Next.js 7 中,我们改变了.next 的目录结构,让它与 URL 结构相匹配:

https://cdn.example.com/_next/static/<buildid>/pages/index.js
// 映射到:
.next/static/<buildid>/pages/index.js

尽管我们建议使用代理类型的 CDN,但新结构也允许不同类型 CDN 的用户将.next 目录上传到 CDN。

styled-jsx 3

我们也引入了 styled-jsx 3,Next.js 的默认 CSS-in-JS 解决方案,现在已经为 React Suspense 做好了准备。

如果一个组件不属于当前组件作用域的一部分,那么该如何设置这个子组件的样式呢?例如,如果你将一个组件包含在父组件中,并只有当它被用在父组件中时才需要特定的样式:

const ChildComponent=()=> <div>
 <p>some text</p>
</div>
export default ()=> <div>
 <ChildComponent />
 <style jsx>{`
 p { color: black }
 `}</style>
</div>

上面的代码试图选择 p 标签,但其实不起作用,因为 styled-jsx 样式被限定在当前组件,并没有泄漏到子组件中。解决这个问题的一种方法是使用:global 方法,将 p 标记的前缀移除。但这样又引入了一个新问题,即样式泄露到了整个页面中。

在 styled-jsx 3 中,通过引入一个新的 API css.resolve 解决了这个问题,它将为给定的 syled-jsx 字符串生成 className 和< style>标签(styles 属性):

import css from 'styled-jsx/css'
const ChildComponent=({className})=> <div>
 <p className={className}>some text</p>
</div>
const { className, styles }=css.resolve`p { color: black }`
export default ()=> <div>
 <ChildComponent className={className} />
 {styles}
</div>

这个新 API 可以将自定义样式传给子组件。

由于这是 styled-jsx 的主要版本,如果你使用了 styles-jsx/css,那么在捆绑包大小方面有一个重大变化。在 styled-jsx 2 中,我们将生成外部样式的“scoped”和“global”版本,即使只使用“scoped”版本,我们也会将“global”版本包含在内。

使用 styled-jsx 3 时,全局样式必须使用 css.global 而不是 css,这样 styled-jsx 才能对包大小进行优化。

App 和 Page 之间的 React Context(服务器端渲染)

从 Next.js 7 开始,我们支持 pages/_app.js 和页面组件之间的 React Context API。

以前,我们无法在服务器端的页面之间使用 React 上下文。原因是 Webpack 保留了内部缓存模块而不是使用 require.cache,我们开发了一个自定义 Webpack 插件来改变这种行为,以便在页面之间共享模块实例。

这样我们不仅可以使用新的 React 上下文,在页面之间共享代码时还能减少 Next.js 的内存占用。


社 区

从 Next.js 首次发布以来,就已获得相当多的用户,从财富 500 强公司到个人博客。我们非常高兴看到 Next.js 的采用量一直在增长。

目前,超过 12,500 个被公开索引的域名在使用 Next.js。我们有超过 500 名贡献者,他们至少提交过一次代码。在 GitHub 上,这个项目已经有 29,000 个 star。自首次发布以来,已提交了大约 2200 个拉取请求。

Next.js 社区在 spectrum.chat/next-js 上拥有近 2000 名成员。

英文原文

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

览器兼容

浏览器

浏览器大战

第一次浏览器大战发生在上个世纪90年代,微软发布了它的IE浏览器,和网景公司的Netscape Navigator浏览器大打出手。 ?

第二次浏览器大战发生在20世纪。 ?

战争产物:Internet Explorer 9


13年市场比重


14年市场比重

15年市场比重

17年市场比重

19年市场比重


浏览器内核 ( 现代4大内核 )

Trident 代表作:IE

元老级内核之一,由微软开发,并于1997年10月首次在ie 4.0中使用,凭借其windows垄断优势,Trident市场占有率一直很高。然而垄断并非,没有竞争就没有进步,长期以往,Trident内核一度停滞不前,更新缓慢,甚至一度与W3C标准脱节。2011年,从ie 9开始,Trident开始支持HTML5和CSS 3,因此我们也经常会看到有些网站在浏览时会提示用户(在Internet Explorer 9.0+以上浏览效果最佳)。前端程序员做浏览器兼容一般也不再会考虑ie 8之前的浏览器了。

Gecko 代表作:Mozilla

元老级内核之一,由Netscape公司Mozilla组织开发。1998年,Netscape在于IE浏览器竞争失利之后,成立了非正式组织Mozilla,由其开发新一代内核,后命名为“Gecko”。FireFox也是这班人开发出来了,因此这也就是Mozilla一直使用的内核。 Gecko的特点是代码完全公开,因此其开发程度很高,全世界的程序员都可以为其编写代码,增加功能。

WebKit : 苹果 & 谷歌旧版本

这是苹果公司开发的内核,也是其旗下产品Ssfari浏览器使用的内核。Webkit引擎包含了WebCode排版引擎和JavaScriptCode解析引擎,分别是从KDE的KHTML和KJS衍生而来,它们都是自由软件,在GPL条约下授权,同时支持BSD系统开发。 Chrome、360极速浏览器以及搜狗高速浏览器也使用Webkit作为内核(在脚本理解方面,Chorome使用自己研发的V8引擎)。

Blink : 代表作:谷歌 & 欧鹏

这是由Google和Opera Software开发的浏览器排版引擎,Google计算将这个渲染引擎作为Chromium计划的一部分,并且在2013年4月公布了这一消息。这一渲染引擎是开源引擎Webkit中WebCore组件的一个分支,并且在Chrome(28及往后版本)、Opera(15及往后版本)和Yandex浏览器中使用

Presto ( Opera前内核 已经废弃 )


为什么会出现浏览器兼容问题?

由于各大主流浏览器由不同的厂家开发,所用的核心架构和代码也很难重和,这就为各种莫名其妙的Bug(代码错误)提供了温床。再加上各大厂商出于自身利益考虑而设置的种种技术壁垒,都让CSS应用起来比想象得要麻烦。浏览器的兼容问题是我们必须去克服的。

CSS Bug、CSS Hack和Filter

  • CSS Bug: CSS样式在各浏览器中解析不一致的情况,或者说CSS样式在浏览器中不能正确显示的问题称为CSS bug.
  • CSS Hack: CSS中,Hack是指一种兼容CSS在不同浏览器中正确显示的技巧方法,因为它们都属于个人对CSS代码的非官方的修改,或非官方的补丁。有些人更喜欢使用patch(补丁)来描述这种行为。
  • Filter:表示过滤器的意思,它是一种对特定的浏览器或浏览器组显示或隐藏规则或声明的方法。本质上讲,Filter是一种用来过滤不同浏览器的Hack类型。


常见的BUG

IE低版本常见CSS解析Bug及hack

1)图片有边框BUG

当图片加<a href=“#”></a>在IE上会出现边框

Hack:给图片加border:0;或者border:0 none;


2)图片间隙

div中的图片间隙BUG

描述:在div中插入图片时,图片会将div下方撑大大约三像素。

hack1:将</div>与<img>写在一行上;

hack2:将<img>转为块状元素,给<img>添加声明:display:block;


3) 双倍浮向(双倍边距)(只有IE6出现)

描述:当Ie6及更低版本浏览器在解析浮动元素时,会错误地把浮向边边界(margin)加倍显示。

hack:给浮动元素添加声明:display:inline;


4)默认高度(IE6、IE7)

描述:在IE6及以下版本中,部分块元素拥有默认高度(在16px左右;)

hack1:给元素添加声明:font-size:0;

hack2:给元素添加声明:overflow:hidden;

非IE BUG

5)表单元素对齐不一致

描述:表单元素行高对齐方式不一致

hack:给表单元素添加声明:float:left;


6)按钮元素默认大小不一

描述:各浏览器中按钮元素大小不一致

hack1: 统一大小/(用a标记模拟)

hack2:input外边套一个标签,在这个标签里写按钮的样式,把input的边框去掉。

hack3:如果这个按钮是一个图片,直接把图片作为按钮的背景图即可。


7)鼠标指针bug

描述:cursor属性的hand属性值只有IE9以下浏览器识别,其它浏览器不识别该声明,cursor属性的pointer属性值IE6.0以上版本及其它内核浏览器都识别该声明。

hack: 如统一某元素鼠标指针形状为手型,

应添加声明:cursor:pointer cursor: ;

auto默认

crosshair加号

text文本

wait等待

help帮助

progress过程

inherit继承

move移动

ne-resize向上或向右移动

pointer手形

8)透明属性

兼容其他浏览器写法:opacity:value;(value的取值范围0-1; 例:opacity:0.5;)

IE浏览器写法:filter:alpha(opacity=value);取值范围 1-100(整数)

过滤器

1.下划线属性过滤器

当在一个属性前面增加了一个下划线后,由于符合标准的浏览器不能识别带有下划线的属性而忽略了这个声明,但是在IE6及更低版本浏览器中会继续解析这个规则。


语法:选择符{_属性:属性值;}


2. !important


关键字过滤器 它表示所附加的声明具有最高优先级的意思。但由于IE6及更低版本不能识别它, 我们可以利用IE6的这个Bug作为过滤器来兼容IE6和其它标准浏览器。


语法:选择符{属性:属性值!important;}


3. *属性过滤器


当在一个属性前面增加了*后,该属性只能被IE7浏览器识别,其它浏览器混略该属 性的作用。


语法:选择符{*属性:属性值;}


4. :IE版本识别;其它浏览器都不识别

语法:选择符{属性:属性值;}


5. >5. \0 : IE8 及以上版本识别;其它浏览器都不识别

家好,我是Echa。

好消息,2023年10月26号Next.js 官方研发团队Lee Robinson 和Tim Neutkens一起对外宣布Next.js 14 正式发布。距离上一个Next.js 13.5 版本(2023年9月19日),只用了短短37 天时间,而且直接跨越式从 Next.js 13.5 跳到 14版本,从侧面说明了Next.js 研发团队技术实力非常不错的,但其Github仓库的 star 数已超过 114k,并且在全球拥有超过 114w名用户。Next.js 官方研发团队真厉害,给咱们开发人员带来了很多方便,小编举起大拇指点赞。

Next.js Github 主页

但是又会有人说前端太卷了,根本学不过来;还有人会说各自为了完成KPI;粉丝们你们怎么看呢?欢迎在评论下说出自己的看法。

借此机会,小编先给大家详细介绍一下Next.js 到底是什么,能做什么,有哪些优点等等,只有彻底了解了Next.js ,才能说出自己观点。希望对大家有所帮助,多了解,多学点有益无害,说不定哪天团队开发项目中就用上,你说是不是?下面小编给大家一一介绍上面的问题。

全文大纲

  1. Next.js 介绍
  2. 为什么选择 Next.js ?
  3. Next.js 有哪些优势呢?
  4. Next.js 渲染方式有哪些?
  5. 手把手教你搭建属于自己的Next.js 项目
  6. Next.js 14发布了哪些内容呢?

Next.js 介绍

传送门:https://nextjs.org/

Github:https://github.com/vercel/next.js


Next.js 中文官网

Next.js是一个流行的React框架,为开发人员提供了许多有用的功能和便利,用于构建现代化、可扩展的Web应用程序,用于构建React应用程序。它在React的基础上提供了一些增强功能,包括服务器渲染(SSR)、静态生成(SSG)、路由等。Next.js的目标是简化React应用程序的开发流程,并提供更好的性能。

Next.js 为您提供生产环境所需的所有功能以及最佳的开发体验:包括静态及服务器端融合渲染、 支持 TypeScript、智能化打包、 路由预取等功能无需任何配置。

为什么选择 Next.js ?

因为全球领先的公司都在使用并喜爱 Next.js。

选择 Next.js原因如下:

  • 零配置

自动编译并打包。从一开始就为生产环境而优化。

  • 混合模式: SSG 和 SSR

在一个项目中同时支持构建时预渲染页面(SSG)和请求时渲染页面(SSR)。

  • 增量静态生成

在构建之后以增量的方式添加并更新静态预渲染的页面。

  • 支持 TypeScript

自动配置并编译 TypeScript。

  • 快速刷新

快速、可靠的实时编辑体验,已在 Facebook 级别的应用上规模上得到验证。

  • 基于文件系统的路由

每个 pages 目录下的组件都是一条路由。

  • API路由

创建 API 端点(可选)以提供后端功能。

  • 内置支持CSS

使用 CSS 模块创建组件级的样式。内置对 Sass 的支持。

  • 代码拆分和打包

采用由 Google Chrome 小组创建的、并经过优化的打包和拆分算法。

小编描述了这么多,不如直接上图:


为什么选择 Next.js


Next.js官网描述是:这是一个用于生产环境的React框架,对这句话的理解得关注这两个关键词:

生产环境:能用于生产就得考虑到方方面面功能,比如性能怎么保证、SSR/CSR/SSG等渲染机制的支持、打包、路由支持、css module,对开发环境的友好,是否能内置支持TypeScript,配置方面也尽可能简化

React框架:所以Next.js是基于React开发,跟Vue和Angular无关。

要从头开始使用 React 构建一个完整的 Web 应用程序,需要考虑许多重要的细节:

  • 必须使用打包程序(例如 webpack)打包代码,并使用 Babel 等编译器进行代码转换。
  • 你需要针对生产环境进行优化,例如代码拆分。
  • 你可能需要对一些页面进行预先渲染以提高页面性能和 SEO。你可能还希望使用服务器端渲染或客户端渲染。
  • 你可能必须编写一些服务器端代码才能将 React 应用程序连接到数据存储。

一个框架就可以解决上述这些问题。但是,这样的框架必须具有正确的抽象级别,否则它将不是很有用。它还需要具有出色的“开发人员体验”,以确保您和您的团队在编写代码时拥有出色的体验。

Next.js 有哪些优势呢?

Next.js 官方案例提供了周边框架的搭建案例,方便开发者配置相关框架和插件,具体如下:

Next.js 官方案例

前面内容小编也有提到了Next.js 优势,具体如下:

  • 零配置:无需配置webpack、babel等工具,只需安装next、react和react-dom即可开始开发。
  • 路由系统:无需使用第三方库,只需在pages目录下创建文件或文件夹,即可实现动态路由和嵌套路由。
  • 代码分割:自动对每个页面进行代码分割,优化性能和加载速度。
  • 预渲染:可以选择使用SSR或SSG来预渲染页面,提高SEO和用户体验。
  • API路由:可以在pages/api目录下创建API路由,处理各种后端逻辑。
  • 插件系统:可以使用各种插件来扩展Next.js的功能,如图片优化、国际化、数据获取等。

Next.js 插件

完善的工程化机制

你不需要自己去配置 webpack 方案,它已经内置了以下工程化基础:

  • babel 内置,支持JS代码向后兼容
  • postcss 内置,支持CSS代码向后兼容
  • browserslist 支持配置兼容的浏览器信息,配合 babel 和 postcss 工作。
  • TypeScript 可选择使用,保证代码的质量,以及可阅读性和可维护性。
  • eslint 可选择使用,检测代码格式,可自定义规则。vscode 编写代码,或者build打包时都会有提示。
  • prettier 可通过扩展使用,格式化代码,可自定义规则。
  • css modules 内置
  • css-in-js 可扩展使用
  • tailwind css 可扩展使用

也做了一些打包优化功能:

  • tree shaking
  • 代码压缩
  • 页面自动静态化
  • 按需打包第三方 es 包(通过设置 transpilePackages 属性,让部分包可以被 next-babel 打包)
  • 异步动态加载组件,和 React.lazy 功能一样,只不过实现得更早。

Next.js 渲染方式有哪些?

Next.js 渲染方法总共分四种:客户端渲染(CSR)、服务器端渲染(SSR)、静态站点生成(SSG)和增量静态生成(ISR)。

渲染是将React代码转换成HTML的过程。用户选择的渲染方法取决于所处理的数据以及用户对性能的关注程度。

在Next.js中,渲染的用途非常广泛。用户可以用静态或增量方式渲染客户端或服务器端页面。

小编让大家看看这些方法是如何工作的以及每种方法有怎样的表现。具体如下:

客户端渲染(CSR)

当用户需要频繁更新数据或不想预渲染页面时,应该使用客户端渲染(CSR)。用户可以在页面层面或组件层面实现CSR。在页面层面,Next.js在运行时获取数据;而在组件层面执行操作时,它在页面挂载时获取数据。正因为如此,CSR可能导致性能变慢。

使用useEffect()钩子在客户端渲染页面,如下所示:

import { useState, useEffect } from 'react'
function Home() {
  const [data, setData]=useState(null)
  const [isLoading, setLoading]=useState(false)
  useEffect(()=> {
    setLoading(true)
    fetch('/api/get-data')
      .then((res)=> res.json())
      .then((data)=> {
        setData(data)
        setLoading(false)
      })
  }, [])
  if (isLoading) return <p>Loading...</p>
  if (!data) return <p>No data</p>
  return (
    <div>
      // Use data
    </div>
  )
}

还可以使用SWR钩子。它缓存数据,一旦数据过时,就重新验证数据。

import useSWR from 'swr'
const fetcher=(...args)=> fetch(...args).then((res)=> res.json())
function Home() {
  const { data, error }=useSWR('/api/data', fetcher)
  if (error) return <div>Failed to load</div>
  if (!data) return <div>Loading...</div>
  return (
    <div>
      // Use data
    </div>
  )
}

在Next.js 13中,用户需要使用客户端组件,为此在文件顶部添加“use client”指令。

"use client";
export default ()=> {
  return (
      <div>
       // Client component
      </div>
  );
};

SSR和CSR的区别在于,在SSR中,从服务器上的每个页面请求获取数据;而在CSR中,从客户端获取数据。

服务器端渲染(SSR)

服务器端渲染(SSR)

就服务器端渲染(SSR)而言,当用户访问网页时,浏览器向服务器发送关于该页面的请求。服务器从数据库获取必要的数据(如果需要的话),并将其与页面内容一同发送到浏览器。然后浏览器将其显示给用户。

浏览器对用户点击的每个链接发出此请求,这意味着服务器每次都处理请求。这可能会降低网站的性能。然而,服务器端渲染非常适合使用动态数据的页面。

每当用户请求时,使用getServerSideProps重新构建页面。

export default function Home({ data }) {
  return (
    <main>
      // Use data
    </main>
  );
}
export async function getServerSideProps() {
  // Fetch data from external api
 const res=await fetch('https://.../data')
  const data=await res.json()
  // Will be passed to the page component as props
  return { props: { data } }
}

getServerSideProps只在服务器上运行,它是这样运行的:

  • 当用户直接访问页面时,它在请求时运行,页面使用它返回的属性来预渲染。
  • 当用户通过Next链接访问页面时,浏览器向运行它的服务器发送请求。

在新版本中,用户可以选择使用页面或布局中的动态数据获取来享用服务器端渲染。

动态数据获取是fetch()请求,它通过将缓存选项设置为“no-store”来选择退出缓存。

fetch (https://..。', {cache: 'no-store'});

或者,将revalidate设置为0:

fetch (https://..。', {next: {revalidate: 0}});

静态站点生成(SSG)

就静态站点生成(SSG)而言,页面在构建期间只获取一次数据。静态生成页面非常快,性能良好,因为所有页面都事先构建。SSG因此非常适合使用静态内容(比如销售页面或博客)的页面。

在Next.js中,用户必须从想要静态渲染的页面中导出 getStaticProps函数。

export default function Home({ data }) {
  return (
    <main>
      // Use data
    </main>
  );
}
export async function getStaticProps() {
  // Fetch data from external API at build time
  const res=await fetch('https://.../data') 
  const data=await res.json()
  // Will be passed to the page component as props
 return { props: { data } }
}

用户还可以在getStaticProps里面查询数据库。

export async function getStaticProps() {
  // Call function to fetch data from database
  const data=await getDataFromDB()
  return { props: { data } }
}

在Next.js 13中,静态渲染是默认操作,内容被获取和缓存,除非用户关闭了缓存选项。

async function getData() {
  const res=await fetch('https://.../data');
  return res.json();
}
export default async function Home() {
  const data=await getData();
  return (
    <main>
      // Use data
    </main>
  );
}

增量静态生成(ISR)

有时用户想使用SSG,但又想定期更新内容,这时候增量静态生成(ISG)大有帮助。

ISG让用户可以在构建静态页面后在指定的时间间隔后创建或更新静态页面。这样一来,用户不需要重建整个站点,只需重建需要它的页面。

ISG保留了SSG的优点,又增加了为用户提供最新内容的好处。ISG非常适合站点上那些使用不断变化的数据的页面。比如说,用户可以使用ISR渲染博文,以便在编辑文章或添加新文章后博客保持更新。

若要使用ISR,将revalidate属性添加到页面上的getStaticProps函数中。

export async function getStaticProps() {
  const res=await fetch('https://.../data')
  const data=await res.json()
  return {
    props: {
      data,
    },
    revalidate: 60
  }
}

在这里,当请求在60秒后到来时,Next.js将尝试重新构建页面。下一个请求将产生带有更新页面的响应。

在Next.js 13中,使用fetch中的revalidate,就像这样:

fetch (https://..。/data', {next: {revalidate: 60}});

用户可以将时间间隔设置为最适合其数据的任何时间间隔。

如何选择渲染方法?

到目前为止,用户已了解了Next.js中的四种渲染方法:CSR、SSR、SSG和ISG。每种方法都适用于不同的情况。CSR适用于需要新数据的页面。SSR适用于使用动态数据的页面,但它对SEO较为友好。

SSG适合数据基本上静态的页面,而ISG最适合含有用户想要间隔更新的数据的页面。SSG和ISG从性能和SEO方面来说都很出色,因为数据预获取,用户还可以缓存数据。

手把手教你搭建属于自己的Next.js 项目

系统环境需求

  • Node.js 12.22.0 或更高版本
  • MacOS、Windows (包括 WSL) 和 Linux 都被支持

安装设置

我们建议使用 create-next-app创建新的 Next.js 应用程序,它会自动为你设置所有内容。创建项目,请运行:

npx create-next-app@latest
# or
yarn create next-app

如果你希望使用 TypeScript 开发项目,可以通过 --typescript 参数创建 TypeScript 项目:

npx create-next-app@latest --typescript
# or
yarn create next-app --typescript

安装完成后:

  • 运行 npm run dev yarn dev 来启动开发服务器,访问地址为 http://localhost:3000
  • 通过 http://localhost:3000 地址访问你的应用程序。
  • 编辑 pages/index.js 文件并在浏览器中查看更新。

手动安装设置

为你的项目安装 next、react react-dom

npm install next react react-dom
# or
yarn add next react react-dom

打开 package.json 文件并添加 scripts 配置段:

"scripts": {
  "dev": "next dev",
  "build": "next build",
  "start": "next start",
  "lint": "next lint"
}

这些脚本涉及开发应用程序的不同阶段:

  • dev - 运行 next dev,以开发模式启动 Next.js
  • build - 运行 next build,以构建用于生产环境的应用程序
  • start - 运行 next start,已启动 Next.js 生产环境服务器
  • lint - 运行 next lint,以设置 Next.js 的内置 ESLint 配置

Next.js 是围绕着 页面(pages) 的概念构造的。一个页面(page)就是一个从 pages 目录下的 .js、.jsx、.ts 或 .tsx 文件导出的 React 组件。

页面(page) 根据其文件名与路由关联。例如,pages/about.js 被映射到 /about。甚至可以在文件名中添加动态路由参数。

在你的项目中创建一个 pages 目录。

为 ./pages/index.js 文件填充如下内容:

function HomePage() {
  return <div>Welcome to Next.js!</div>
}

export default HomePage

到目前为止,我们得到了:

  • 自动编译和打包(利用 webpack 和 babel)
  • React 快速刷新
  • ./pages/ 中的 静态生成和服务器端渲染
  • 静态文件服务。./public/ 被映射到 /

此外,任何 Next.js 应用程序从一开始就是可以投入到生产环境中。

Next.js 14发布了哪些内容呢?

Next.js 14 官方正式发布该版本的主要更新如下:

  • Turbopack:App & Pages Router 通过 5000 个测试
    • 本地服务器启动速度提高了 53%
    • 通过快速刷新,代码更新速度提高 94%
  • 服务端操作(稳定):逐步增强的数据变更
    • 集成了缓存和重新验证
    • 简单的函数调用,或者与表单原生配合工作
  • 部分预渲染(预览):快速的初始静态响应 + 流式动态内容
  • Next.js Learn(全新):教授 App Router、身份验证、数据库等内容的免费课程。

可以通过以下命令来立即升级最新版本:

npx create-next-app@latest



Next.js 编译器

自 Next.js 13 发布以来,Next 团队一直致力于提高 Next.js 中 Pages 和 App Router 的本地开发性能。

之前,Next 团队通过重写 Next.js 的 next dev 和其他部分以实现这一目标。然而,后来改变了方法,采取了更渐进的方式。现在,重点是首先支持所有 Next.js 的功能,因此基于 Rust 的编译器很快就会稳定下来。

Next.js 使用基于 Rust 引擎的 Turbopack,现在已经通过了 5000 个 next dev 的集成测试。这些测试涵盖了过去 7 年中的错误修复和重现。

在大型 Next.js 应用 vercel.com 上进行测试时,可以看到:

  • 本地服务器启动速度提高高达 53.3%
  • 通过快速刷新,代码更新速度提高高达 94.7%

该基准测试是大型应用(和大型模块图)性能改进的实际结果。现在,next dev 的 90% 测试已经通过,在使用 next dev --turbo 时,应该会看到更快、更可靠的性能表现。

一旦达到 100% 的测试通过,将在即将发布的次要版本中将 Turbopack 移至稳定版本。另外,还将继续支持使用 webpack 进行自定义配置和生态系统插件。

可以在 areweturboyet.com 上关注通过测试的百分比。

表单和数据变更

Next.js 9 引入了 API Routes,这是一种快速构建后端端点的方法,可以与前端代码一起使用。

例如,可以在 api/ 目录中创建一个新文件:

//pages/api/submit.ts
import type { NextApiRequest, NextApiResponse } from 'next';
 
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  const data=req.body;
  const id=await createItem(data);
  res.status(200).json({ id });
}

然后,在客户端,可以使用 React 和 onSubmit 等事件处理程序来获取 API 路由:

//pages/index.tsx
import { FormEvent } from 'react';
 
export default function Page() {
  async function onSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
 
    const formData=new FormData(event.currentTarget);
    const response=await fetch('/api/submit', {
      method: 'POST',
      body: formData,
    });
 
    // Handle response if necessary
    const data=await response.json();
    // ...
  }
 
  return (
    <form onSubmit={onSubmit}>
      <input type="text" name="name" />
      <button type="submit">Submit</button>
    </form>
  );
}

现在,随着 Next.js 14 的推出,希望简化开发者在编写数据变更时的体验。此外,还希望在用户网络连接较慢或从低功率设备提交表单时改善用户体验。

服务端操作(稳定)

如果不想手动创建 API Route,那么可以定义一个函数,在服务端安全地运行,并直接从 React 组件中调用它。

App Router 构建在 React canary 通道上,对于框架 采用新功能来说是稳定的。从 v14 开始,Next.js 已升级到最新的 React canary,其中包括稳定的服务器操作。

App Router 是建立在 React canary 通道上的,这个通道对于框架来采用新功能是稳定的。从 v14 开始,Next.js 已经升级到了最新的 React canary 版本,其中包含稳定的服务端操作功能。

前面 Pages Router 的例子可以简化为一个文件:

// app/page.tsx
export default function Page() {
  async function create(formData: FormData) {
    'use server';
    const id=await createItem(formData);
  }
 
  return (
    <form action={create}>
      <input type="text" name="name" />
      <button type="submit">Submit</button>
    </form>
  );
}

服务端操作对于之前使用过服务端中心框架的开发者来说应该会很熟悉。它是建立在 Web 基础知识(如表单和 FormData Web API)之上的。

通过表单使用服务端操作对于渐进增强是有帮助的,但并不是必需的。也可以直接将其作为函数调用,而无需使用表单。在使用 TypeScript 时,这提供了完整的端到端类型安全性,确保客户端和服务端之间的安全性。

数据变更、页面重新渲染或重定向可以在一次网络往返中完成,确保在客户端上显示正确的数据,即使上游提供者的响应速度较慢。此外,可以组合和重用不同的操作,包括在同一个路由中使用多个不同的操作。

缓存、重新验证、重定向等

服务端操作深度集成到整个 App Router 模型中。你可以:

  • 使用 revalidatePath() 或 revalidateTag() 可以重新验证缓存的数据。
  • 使用redirect()重定向到不同的路由。
  • 使用cookies()设置和读取cookie
  • 使用 useOptimistic() 处理乐观 UI 更新
  • 使用 useFormState() 捕获并显示来自服务端的错误
  • 使用 useFormStatus() 在客户端显示加载状态

部分预渲染(预览)

Next.js 中正在开发的部分预渲染推出了预览版,它是一种针对动态内容的编译器优化,可以实现快速的初始静态响应。

部分预渲染建立在对服务端渲染(SSR)、静态站点生成(SSG)和增量静态重新验证(ISR)进行了十年的研究和开发的基础上。

Motivation(动机)

目前存在过多的运行时、配置选项和渲染方法需要考虑。希望在享受静态网页的速度和可靠性的同时,也能支持完全动态、个性化的响应。不过,拥有出色的性能和个性化体验不应以复杂性为代价。

面临的挑战是创建更好的开发体验,简化现有模型,而无需引入新的需要学习的 API。虽然部分缓存服务端内容的方法已经存在,但这些方法仍然需要满足旨在实现的开发者体验和可组合性目标。

部分预渲染不需要学习新的 API。

建立在 React Suspense 之上

部分预渲染是由 Suspense 边界定义的。以下是它的工作原理。考虑以下电子商务页面:

// app/page.tsx
export default function Page() {
  return (
    <main>
      <header>
        <h1>My Store</h1>
        <Suspense fallback={<CartSkeleton />}>
          <ShoppingCart />
        </Suspense>
      </header>
      <Banner />
      <Suspense fallback={<ProductListSkeleton />}>
        <Recommendations />
      </Suspense>
      <NewProducts />
    </main>
  );
}

启用部分预渲染后,该页面将根据 <Suspense /> 边界生成静态骨架,它包含了页面的结构和布局,但不包含动态内容。React Suspense 的fallback也会被预渲染。

然后,在静态骨架中,Suspense 的fallback将被动态组件替换,例如读取 cookie 来确定购物车内容,或者根据用户显示横幅广告。

当发出请求时,立即提供静态 HTML 骨架:

<main>
  <header>
    <h1>My Store</h1>
    <div class="cart-skeleton">
      <!-- Hole -->
    </div>
  </header>
  <div class="banner" />
  <div class="product-list-skeleton">
    <!-- Hole -->
  </div>
  <section class="new-products" />
</main>

由于 <ShoppingCart /> 组件需要读取cookie以查看用户会话,因此该组件将作为同一HTTP请求的一部分进行流式传输,与静态骨架一起加载,这样就不需要额外的网络往返。

// app/cart.tsx
import { cookies } from 'next/headers'

export default function ShoppingCart() {
  const cookieStore=cookies()
  const session=cookieStore.get('session')
  return ...
}

为了获得最细粒度的静态骨架,可能需要添加额外的 <Suspense /> 边界。然而,如果今天已经在使用 loading.js,那么这是一个隐式的 <Suspense /> 边界,因此不需要更改即可生成静态骨架。

即将到来

部分预渲染正在积极开发中,将在即将发布的次要版本中分享更多更新。

元数据改进

在页面内容从服务端流式传输之前,需要先向浏览器发送关于视口、颜色方案和主题等重要元数据。

确保这些meta标签与初始页面内容一起发送可以提供流畅的用户体验,防止由于更改主题颜色或视口变化而导致页面闪烁或布局偏移。

在 Next.js 14 中,将阻塞和非阻塞的元数据解耦。只有一小部分元数据选项是阻塞的,希望确保非阻塞的元数据不会阻止部分预渲染页面提供静态骨架。

以下元数据选项现已弃用,并将在未来的主要版本中从元数据中删除:

  • viewport:设置视口的初始缩放和其他属性
  • colorScheme:设置视口的支持模式(亮/暗)
  • themeColor: 设置视口周围的浏览器界面应该呈现的颜色

从 Next.js 14 开始,使用新的选项 viewport 和 generateViewport 来替换这些选项。所有其他元数据选项保持不变。

Next.js Learn 课程

在 Next.js Learn 上发布了全新的免费课程。本课程教授:

  • Next.js App Router
  • 样式和 Tailwind CSS
  • 优化字体和图像
  • 创建布局和页面
  • 在页面之间导航
  • 设置 Postgres 数据库
  • 使用服务端组件获取数据
  • 静态和动态渲染
  • 流媒体
  • 部分预渲染(可选)
  • 添加搜索和分页
  • 数据变更
  • 错误处理
  • 改善无障碍环境
  • 添加身份验证
  • 添加元数据

其他更新

  • [重大变更] 现在 Node.js 最低版本要求为 18.17
  • [重大变更] 移除了 next-swc 构建的 WASM 目标
  • [重大变更] 放弃支持 @next/font,转而支持 next/font
  • [重大变更] 将 ImageResponse 导入从 next/server 更改为 next/og
  • [重大变更] next export 命令已弃用,推荐使用 output: 'export'
  • [弃用] next/image 的 onLoadingComplete 已弃用,推荐使用 onLoad
  • [弃用] next/image 的 domains 已弃用,推荐使用 remotePatterns
  • [功能] 可以启用更详细的关于获取缓存的日志记录
  • [改进] 基本 create-next-app 应用的函数大小减小了 80%

最后

一行代码,可能会创造出下一个让人惊叹的产品;
一个创新,可能会开启一个全新的科技时代;
一份初心,可能会影响到无数人的生活;
无论是在大公司工作,还是在小团队奋斗;
无论是资深的程序员,还是刚刚入行的新手;
每个人的代码,都有力量改变世界。

创作不易,喜欢的老铁们加个关注,点个赞,打个赏,后面会不定期更新干货和技术相关的资讯,速速收藏,谢谢!你们的一个小小举动就是对小编的认可,更是创作的动力。

创作文章的初心是:沉淀、分享和利他。既想写给现在的你,也想贪心写给 10 年、20 年后的工程师们,现在的你站在浪潮之巅,面对魔幻的互联网世界,很容易把一条河流看成整片大海。未来的读者已经知道了这段技术的发展历史,但难免会忽略一些细节。如果未来的工程师们真的创造出了时间旅行机器,可以让你回到现在。那么小编的创作就是你和当年工程师们的接头暗号,你能感知到他们在这个时代的键盘上留下的余温。