最近在一个资讯项目中使用了Next.js服务端渲染,体验了服务端渲染的速度。首屏直出,渲染速度666,在服务端渲染没有前后端分离的时候,前端简单写个HTML模板,后端处理通过Php、Java等各种模板引擎将静态页面转化为动态模板进行渲染。当时是服务端渲染。但这很麻烦。历史的车轮滚滚向前。在单页应用时代,后端只提供接口,不再负责模板处理。后来为了解决SEO的问题和首屏渲染的问题,再也回不去前后端不分离的时代了,所以是前端er选择的路,而我们跪下也要下去,Vue的Nuxt.js,React的Next.js等SSR框架应运而生。我们通常广泛使用Vue和React在客户端进行渲染。服务器返回一个空的HTML模板,然后在内部加载JS,生成并操作Dom,最后由浏览器渲染页面。经过这样一系列的操作,首屏加载会慢很多。另外,由于是空页面,爬虫无法识别,不利于SEO。在浏览器中右击源代码,可以看到页面是一个空的HTML。服务端渲染(SSR),服务器直接返回HTML,浏览器即可显示,无需等待JavaScript完成下载执行后再显示内容。不仅渲染速度大大加快,而且更有利于搜索引擎的抓取。到密集的HTML标签。优点更快的首屏加载速度更友好的SEO缺点增加维护成本项目部署比单页应用复杂Next.js基本上使用路由系统pages目录路由Next.js路由系统是基于文件路径的自动映射文件将被自动处理成路由,所以通常我们只将页面路由文件放在pages下,其他组件不要放在pages目录下。比如在pages目录下创建了login.js和register.js,那么路由就对应/login和/register。同样,多级路由的处理也类似。比如在pages下创建user目录,在user下创建login和register文件。/user/login对应登录文件,/user/register对应注册文件。Next.js的路由系统让我们不再需要关心路由,合理的在页面中创建目录。动态路由Next.js也支持动态路由。文件前带[param],如pages/post/[pid].js,会匹配发帖人详情页/post/pid。预定义的API路由优先于动态API路由pages/post/create.js,将匹配/post/createpages/post/[pid].js`,将匹配/post/1,但不会匹配/post/创建路由跳转传递参数next提供了两个方法,分别是导航路由next/link和programmaticnext/routerLinkhref是必填属性,可以传递对象程序化导航next/router与reacthooks中的useHistory相同import{useRouter}from'next/router'constrouter=useRouter()//:1router.push(`/article/${c.queueId}`)//:2router.push({pathname:'/publish',query:{contentId:c.contentId,status:active}})路由参数获取Next.js只能通过query传递参数,不能通过params。useRouter或getServerSideProps方法都可以获取查询参数import{useRouter}from'next/router'const{query}=useRouter()query.cid//:获取cid参数。这个动态路由的参数可以通过查询得到。也可以通过getServerSideProps方法中的params获取router.push(`/article/${c.queueId}`)。cssNext.js支持CssModule和Css-in-JS,两者都有自己的样式隔离。Next.js的动态导入也支持与React客户端相同的ES2020import()语法来实现导入。在React单页项目中,Webpack在解析这种语法时会自动拆分代码。在Next.js中,还可以使用next/dynamic动态导入组件,这些组件会在客户端延迟加载。通过动态导入,可以让一些不需要在服务端渲染的组件使用动态。constBreadCrumb=dynamic(()=>import('@/components/ui/BreadCrumb'))服务器请求getServerSidePropsexportasyncfunctiongetServerSideProps(context){return{props:{},//将作为props传递给页面组件}}getServerSideProps主要是用来请求服务端的数据,比如我们列表的首屏数据,我们可以把列表下一页的数据放到客户端去获取。上下文参数包含路由参数等对象。由于getServerSideProps是在服务器端发起的请求,相关的日志信息只能在终端看到,在Network面板是看不到包含控制台信息的请求。getServerSideProps返回数据后,Next.js会将数据写入HTML源码,即window.__NEXT_DATA__.props,从而将数据传输到客户端。客户端有这些数据,比如可以持有window.__NEXT_DATA__.props中的数据,初始化React组件的props等。在控制台输入__NEXT_DATA__,就可以看到Next.js在页面中封装了哪些数据。其他完全兼容最新版本的React17。Links使用Link避免程序化导航,有利于SEO。Next.js自带Image组件,自动优化图片,大大提升用户体验。可以自定义文档页面404页、500页等。当Next.js捕获到错误时,无论是接口错误还是代码运行时错误,Next.js服务都会在内部进行转换并抛出500异常。官方文档Server-sideRenderingFrequentlyAskedQuestions最后总结一下Next.js使用中遇到的问题,欢迎各位侠客补充。UseEffect的注意点服务端渲染时,无法获取屏幕、元素宽高等尺寸信息。不要让元素的显示依赖useEffect中的设备宽高和dom位置的计算。useEffect(()=>{//:错误示例//:服务端渲染时获取不到设备宽度deviceWidth,所以isDesktop的值不会改变deviceWidth>960&&(isDesktop=true),[])return(<>{isDesktop?(pc
):null}>)是响应式页面,HeaderBar组件在pc端显示,m端不显示,如何处理?在客户端渲染的情况下,判断设备类型即可。但是在服务端渲染的时候,去哪里判断设备类型呢?使用效果?里面没法判断。有两种选择:使用客户端渲染。使用next/dynamic动态导入HeaderBar组件,这样HeaderBar组件会在客户端渲染,而其他元素仍然在服务端渲染。仍然使用服务器端渲染。通过css的媒体查询在m侧的HeaderBar上display:none也是一种解决方法。