Web开发

首页 » 常识 » 问答 » 我看Nextjs一个更现代的海王
TUhjnbcbe - 2024/7/5 17:25:00

作者:狼叔

Next.js是一个用于生产环境的React应用框架(官方介绍:TheReactFrameworkforProduction),使用它可以快速上手开发React应用(enablesyoutobuildsuperfastandextremelyuser-friendlystaticwebsites,),而不需要花很多时间和精力去折腾各种开发工具。所谓的用于生产环境,是指功能和稳定性足够,有大量的实际应用案例。

在整理编辑大人给的《狼书(卷3):Node.js高级技术》修订版,给next.js一个明确观点:"整体来看,Next.js在Node.jsWeb开发领域是一个非常优秀的SSR框架,其众多优秀特性,外加Blitzjs这种周边生态,对于开箱即用的项目来说是极好的。从架构的角度,笔者以为Next.js是过度设计,从商业的角度,我认同Next.js的做法,易用性应该是开发领域最该重视的核心。"

之所以给出这样一个观点,是基于下面5个方面总结出来的。

next.js是什么?有哪些优点?为啥狼叔觉得它看起来像一个海王?

对比cra,umi和next.js,它们之间的差异是什么?

next.js生态除了vercel,还有rust和blitzjs,你都了解吗?

实现一个框架有哪4方面的思考?

在服务端渲染领域,对比next.js和ykfe/ssr,有何异同?

内容有点多,大家需要有点耐心。

1、Next是什么?

针对上面的点评,还需要明确一下next.js的介绍要点,不冲突

基于React,支持csr、ssr、isr、ssg等渲染或用于渲染的生成方式

支持ssr,但只是next.js的一个场景而已

next.js是Nodeweb领域优秀的ssr框架,这只是其一,其实年之后,next.js也开始支持serverless了

搭配vercel部署,对serverless支持极好

开箱即用,简单易用

下面看一下next的基本特性,如下。

简单汇总一下。

基础页面,数据获取,布局,国际化等,都已经是前端领域最佳实践了,这点上umi和next几乎一模一样。各种优化手段,图片,字体,脚本等,基本上都是最潮最新的好东西。

文件即路由,从rubyonrails开始,前端也借鉴了,umi大概也是借鉴了next的。ykfe/ssr也是借鉴了的。

自动按页面拆分代码,其实是webpack做的事儿,NextJS将每个页面单独打包,打开首页时会加载应用基础代码和首页代码,其它页面代码只会在打开时才去加载,这对于大型应用来说非常有用。

静态页面导出,可以将整个NextJS应用导出为一个静态网站,完美的JamStack

CSS-in-JS,内置了styled-jsx方案,样式写法遵循标准,并且样式作用域局限于组件内部而不是全局,避免了组件之间样式互相影响。

在今天,习惯Umi类脚手架和react开发的人,基本上会认为这些是标配,事实上,我们是需要感谢next.js团队的开拓之功的。

1.1、易用极致

nextjs很明显选择易用性,像一个海王一样,太懂用户的心了。所以它也是for企业,小客户和个人开发者的通用方案,从基础框架,到发布运维都帮你解决了,是极为方便的技术,以致于很多人都把它作为第一梯队的选择。

早期的next.js写法是非常简单的,就只有getInitialProps一个静态方法。

functionPage(props){returndiv{props.name}/div}Page.getInitialProps=async(ctx)={returnPromise.resolve({name:Egg+React+SSR})}exportdefaultPage

在egg-react-ssr技术调研期,我们分别看了next.js和easywebpack。

easywebpack在使用上,我不认可使用egg的worker来做。easy-team的方案本地开发采用了在Node中启动webpack编译bundle的方案,将服务端bundle打包在内存中,agent进程通过memory-fs提供的api来读取文件内容,并且通过worker与agent进程的通信,来让worker进程可以获取到文件的字符串内容。然后采用了Node的runInNewContextapi,类似于eval的方式去执行js字符。

next.js写法上是完美的。将请求方法抽取成静态方法,可以复用。另外在服务端渲染,先执行请求方法,是最高效的方式,比Biglet用的对象方法好。

在打包构建方面,本项目本地开发采用的方案为直接将服务端bundle打包到本地硬盘,通过webpack--watch的方式,来实现更新,同时本地开发的时候每次加载之前清空requirebundle的缓存保证刷新后server端的内容与client端一致。结合webpack-dev-server,上手难度低,实现代码更少。

为了适应更多的渲染细化场景,基于getInitialProps都能完成,但next又进行了拆分,让每个写法都有特定的应用场景。好处是用的人简单,缺点是增加学习成本。

除了核心特性上,做了渲染场景的细化外,next还做了非常多的易用性上的小心思,大家讨论最多的,大概就是image了。下面是山月在知乎上写的关于nextimage的体验。

内置ImageProxy,对图片进行转换、压缩,使得图片体积最小化。并配合图片懒加载与srcset一系列关于图片优化的小点子优化网络体验Next团队宣传地也颇为实在

Inordertouseimagesonwebpagesinaperformantwayalotofaspectshavetobeconsidered:size,weight,lazyloading,andmodernimageformats.

举一个栗子,如果你使用了一张pxxpx的PNG图片,放到了pxxpx的小方格里。那么next.js将会做以下操作优化性能。

内置Proxy服务把它压缩成px与px两张图,大幅度压缩体积

内置Proxy服务把它转成webp,一个体积更小的图片格式(比jpg小30%的体积)

内置Proxy服务把它转成75%压缩质量的webp,一个更小的体积与几乎无肉眼可见的图片质量变化

懒加载,看不到图片不加载

按需加载(不像Gatsby那样需要在部署项目前耗费大量精力去压缩图片)

由于内置Proxy运行时处理,可支持非本域名上的图片处理

优点说完了,这里说一下它的缺点吧

无法利用LongTermCache,浏览器二次加载时图片速度慢,使CDN也无法性能最大化

小图片无法内置为DataURI,大量的小图片将造成多次HTTP请求影响性能,比如我的这个网站:开发者武器库

无法支持多分辨率屏幕

CPU,如果部署在Vercel可以利用它的服务器资源做缓存服务,如果自部署处理图片需要消耗CPU。但这个也不算很缺点,只是引入了复杂状态,国内可以利用Ali_OSS或公司共有ImageProxy做图片缓存服务自定义一个loader,详见文档

1
查看完整版本: 我看Nextjs一个更现代的海王