关于javascript:Nextjs与React服务端渲染

9次阅读

共计 3159 个字符,预计需要花费 8 分钟才能阅读完成。

最近在一个资讯类的我的项目中用了 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 目录上面。比方在 pages 目录上面创立了 login.js 和 register.js,那么路由就对应 /login 和 /register。
  • 同样,多级路由也是相似的解决。例如在 pages 下创立了 user 目录,user 下创立 login 和 register 文件。/user/login 对应 login 文件,/user/register 对应 register 文件。
    Next.js 的路由零碎使咱们不必再去关怀路由,正当在 pages 建设目录。

动静路由

  • Next.js 也反对反对动静路由,在文件前携带 [param],例如 pages/post/[pid].js,会匹配到海报详情页面 /post/pid。
  • 预约义的 API 路由优先于动静 API 路由

    • pages/post/create.js,将匹配 /post/create
    • pages/post/[pid].js`,将匹配 /post/1, 但不匹配 /post/create

路由跳转与传参

next 提供了两种形式,别离是导航式路由 next/link 和 编程式 next/router

  1. Link

    href 为必须属性,可传递对象

    <Link href="/about?name=jackylin">
    
    <Link href={{pathname: '/article', query: { type: active} }}>
  2. 编程式导航 next/router

    和 react hooks 中的 useHistory 用法一样

    import {useRouter} from 'next/router'
    const router = useRouter()
    //: 1
    router.push(`/article/${c.queueId}`)
    //: 2
    router.push({
    pathname: '/publish',
        query: {
          contentId: c.contentId,
          status: active
        }
    })

    路由参数获取

    Next.js 只能通过 query 来传递参数,不能应用 params。
    useRouter 或 getServerSideProps 办法内都能够拿到 query 参数

import {useRouter} from 'next/router'
const {query} = useRouter()
query.cid //: 获取 cid 参数

这种动静路由的参数通过 query 能够获取到,在 getServerSideProps 办法内也能够通过 params 获取
router.push(`/article/${c.queueId}`)

css

Next.js 反对 Css Module 和 Css-in-JS 这两种形式,二者自带款式隔离。

动静导入

Next.js 同样反对和 React 客户端一样的 ES2020 import() 语法来实现导入,在 React 单页面我的项目外面,Webpack 解析到该语法时会主动进行代码宰割。在 Next.js 外面,还能够应用 next/dynamic 来动静导入组件,它们将在客户端懒加载。通过动静导入,对于一些不须要在服务端渲染的组件能够应用 dynamic 来解决。

const BreadCrumb = dynamic(() => import('@/components/ui/BreadCrumb'))

服务端申请 getServerSideProps

export async function getServerSideProps(context) {
  return {props: {}, // will be passed to the page component as props
  }
}
  • getServerSideProps,次要用于在服务端申请数据,比方咱们列表的的首屏数据,像列表下一页的数据咱们则能够放到客户端去获取。context 参数外面蕴含路由参数等对象。
  • 因为 getServerSideProps 是在服务端进行的申请,所以相干的 log 信息在终端能力看到,Network 面板外面是看不到申请状况包含 console 信息。
  • getServerSideProps 返回数据后,Next.js 会把这些数据写到 HTML 源 码外面,即 window.__NEXT_DATA__.props,这样就实现了把数据传送到客户端,客户端有了这些数据,比方能够拿着 window.__NEXT_DATA__.props 外面的数据初始化 React 组件的 props 等。在 console 里输出 __NEXT_DATA__, 你就能看到 Next.js 在页面中封装了什么数据。

其它

  • 全面兼容最新 React 17 版本
  • 链接跳转应用 Link,防止应用编程式导航,有利于 SEO。
  • Next.js 自带 Image 组件,主动优化图像,极大改善用户体验。
  • 能够自定义 document 页面 404 页面、500 页面等。当 Next.js 捕捉到谬误时,不论是接口谬误还是代码运行时的谬误,Next.js 服务外部会对立转化并抛出 500 异样。
  • 官网文档

服务端渲染常见问题

最初呢总结一下 Next.js 应用中遇到的问题,欢送各路侠客补充。

useEffect 的留神点

服务端渲染时拿不到屏幕、元素宽低等尺寸信息,不要让元素的显示依赖于 useEffect 外面的设施宽高、dom 地位计算。

useEffect(() => {
    //: 谬误示例
    //: 服务端渲染的时候拿不到设施宽度 deviceWidth 所以 isDesktop 的值不会扭转
    deviceWidth > 960 && (isDesktop = true)
, [])

return (
    <>
      {isDesktop ? (<div>pc</div>) : null}
    </>
)

一个响应式的页面,pc 端显示 HeaderBar 组件,m 端不显示,如何解决?

在客户端渲染的状况下,判断一下设施类型即可。然而在服务端渲染,在哪里判断设施类型呢?useEffect?不能在外面判断。

计划有二:

  1. 采纳客户端渲染的解决形式。应用 next/dynamic 动静导入 HeaderBar 组件,这样 HeaderBar 组件将在客户端进行渲染,其它元素仍然还是在服务端进行渲染。
  2. 仍然采纳服务端渲染的解决形式。通过 css 的媒体查问,在 m 端对 HeaderBar 进行 display:none,这也是一种解决方法。
正文完
 0