日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
從Next.js看企業(yè)級框架的SSR支持

本文轉(zhuǎn)載自微信公眾號「前端向后」,作者黯羽輕揚(yáng)  。轉(zhuǎn)載本文請聯(lián)系前端向后公眾號。 

網(wǎng)站的建設(shè)成都創(chuàng)新互聯(lián)專注網(wǎng)站定制,經(jīng)驗(yàn)豐富,不做模板,主營網(wǎng)站定制開發(fā).小程序定制開發(fā),H5頁面制作!給你煥然一新的設(shè)計(jì)體驗(yàn)!已為木托盤等企業(yè)提供專業(yè)服務(wù)。

 一.Next.js 簡介

The React Framework for Production

面向生產(chǎn)使用的 React 框架(廢話)。提供了好些開箱即用的特性,支持靜態(tài)渲染/服務(wù)端渲染混用、支持 TypeScript、支持打包優(yōu)化、支持按路由預(yù)加載等等:

Next.js gives you the best developer experience with all the features you need for production: hybrid static & server rendering, TypeScript support, smart bundling, route pre-fetching, and more. No config needed.

其中,完善的靜態(tài)渲染/服務(wù)端渲染支持讓 Next.js 在 React 生態(tài)中獨(dú)樹一幟

二.核心特性

如果說 Next.js 只做了一件事,那就是預(yù)渲染(Pre-rendering):

By default, Next.js pre-renders every page. This means that Next.js generates HTML for each page in advance, instead of having it all done by client-side JavaScript.

具體的,預(yù)渲染分為兩種方式:

  • SSG(Static Site Generation):也叫 Static Generation,在編譯時(shí)生成靜態(tài) HTML
  • SSR(Server-Side Rendering):也叫 Server Rendering,用戶請求到來時(shí)動(dòng)態(tài)生成 HTML

與 SSR 相比,Next.js 更推崇的是 SSG,因?yàn)槠湫阅軆?yōu)勢更大(靜態(tài)內(nèi)容可托管至 CDN,性能提升立竿見影)。因此建議優(yōu)先考慮 SSG,只在 SSG 無法滿足的情況下(比如一些無法在編譯時(shí)靜態(tài)生成的個(gè)性化內(nèi)容)才考慮 SSR、CSR

P.S.CSR、SSR 等更多渲染模式,見前端渲染模式的探索

圍繞核心的預(yù)渲染功能,延伸出了一系列相關(guān)支持,如:

  • 路由(文件規(guī)范、API):多頁面的基礎(chǔ)
  • 頁面級預(yù)渲染、代碼拆分:順理成章
  • 增量靜態(tài)生成:針對大量頁面的編譯時(shí)預(yù)渲染(即靜態(tài)生成)策略
  • 按路由預(yù)加載:錦上添花
  • 國際化(結(jié)合路由):錦上添花
  • 集成 Serverless 函數(shù):錦上添花
  • 自動(dòng) polyfill、自定義head標(biāo)簽:友情贈(zèng)送

此外,還提供了一些通用場景支持:

  • 開箱即用(0 配置)
  • TypeScript
  • CSS module、Sass
  • Fast Refresh(可靠的 Hot Reload 支持)
  • 用戶真實(shí)數(shù)據(jù)收集分析(頁面加載性能、體驗(yàn)評分等)
  • 帶默認(rèn)優(yōu)化的Image組件

三.路由支持

Next.js 提供了兩種路由支持,靜態(tài)路由與動(dòng)態(tài)路由

靜態(tài)路由

靜態(tài)路由通過文件規(guī)范來約定,pages目錄下的js文件都認(rèn)為是路由(每個(gè)靜態(tài)路由對應(yīng)一個(gè)頁面文件),例如:

 
 
 
 
  1. pages/index.js → / 
  2. pages/blog/index.js → /blog 
  3. pages/blog/first-post.js → /blog/first-post 
  4. pages/dashboard/settings/username.js → /dashboard/settings/username 

動(dòng)態(tài)路由

類似的,動(dòng)態(tài)路由也要在pages目錄下創(chuàng)建文件,只是文件名有些不同尋常:

 
 
 
 
  1. pages/blog/[slug].js → /blog/:slug (/blog/hello-world) 
  2. pages/[username]/settings.js → /:username/settings (/foo/settings) 
  3. pages/post/[...all].js → /post/* (/post/2020/id/title) 

路徑中變化的參數(shù)通過getStaticPaths來填充:

 
 
 
 
  1. // pages/posts/[id].js 
  2. export async function getStaticPaths() { 
  3.   return { 
  4.     // 必須叫paths,值必須是數(shù)組 
  5.     paths: [{ 
  6.       // 每一項(xiàng)必須是這個(gè)形式 
  7.       params: { 
  8.         // 必須含有id 
  9.         id: 'ssg-SSR' 
  10.       } 
  11.     },{ 
  12.       params: { 
  13.         id: 'pre-rendering' 
  14.       } 
  15.     }], 
  16.     fallback: false 
  17.   } 

進(jìn)一步傳遞給getStaticProps按參數(shù)獲取數(shù)據(jù),并渲染頁面:

 
 
 
 
  1.  props: { 
  2.       postData 
  3.     } 
  4.   } 
  5.  
  6. // 渲染頁面 
  7. export default function Post({ postData }) { 
  8.   return ( 
  9.      
  10.        
  11.         {postData.title} 
  12.        
  13.       
     
  14.         {postData.title} 
  15.          
  16.            
  17.         
 
  •          
  •        
  •      
  •   ) 
  • 可以理解為先創(chuàng)建一個(gè)工廠 page(例如pages/[路由參數(shù)1]/[路由參數(shù)2].js),接著getStaticPaths填充路由參數(shù),getStaticProps({ params })根據(jù)參數(shù)請求不同數(shù)據(jù),最后數(shù)據(jù)進(jìn)入頁面組件開始預(yù)渲染:

    四.SSG 支持

    最簡單,同時(shí)性能也最優(yōu)的預(yù)渲染方式就是靜態(tài)生成(SSG),把組件渲染工作完全前移到編譯時(shí):

    1. (編譯時(shí))獲取數(shù)據(jù)
    2. (編譯時(shí))渲染組件,生成 HTML

    將生成的 HTML 靜態(tài)資源托管到 Web 服務(wù)器或 CDN 即可,兼具 React 工程優(yōu)勢與 Web 極致性能

    那么首先要解決如何獲取數(shù)據(jù)的問題,Next.js 的做法是將頁面依賴的數(shù)據(jù)集中管理起來:

     
     
     
     
    1. // pages/index.js 
    2. export default function Home(props) { ... } 
    3.  
    4. // 獲取靜態(tài)數(shù)據(jù) 
    5. export async function getStaticProps() { 
    6.   // Get external data from the file system, API, DB, etc. 
    7.   const data = ... 
    8.  
    9.   // The value of the `props` key will be 
    10.   //  passed to the `Home` component 
    11.   return { 
    12.     props: ... 
    13.   } 

    其中,getStaticProps只在服務(wù)端執(zhí)行(根本不會(huì)進(jìn)入客戶端 bundle),返回的靜態(tài)數(shù)據(jù)會(huì)傳遞給頁面組件(上例中的Home)。也就是說,要求通過getStaticProps提前備好頁面所依賴的全部數(shù)據(jù),數(shù)據(jù) ready 之后組件才開始渲染,并生成 HTML

    P.S.注意,只有頁面能通過getStaticProps聲明其數(shù)據(jù)依賴,普通組件不允許,所以要求將整頁依賴的所有數(shù)據(jù)都組織到一處

    至于渲染生成 HTML 的部分,借助React 提供的 SSR API即可完成

    至此,只要是依賴數(shù)據(jù)有辦法提前獲取到的頁面,理論上都可以編譯生成靜態(tài) HTML,但 2 個(gè)問題也隨之而來:

    • 數(shù)據(jù)可能會(huì)發(fā)生變化,已經(jīng)生成的靜態(tài)頁面需要更新
    • 數(shù)據(jù)量可能會(huì)多到“永遠(yuǎn)”編譯不完

    以電商頁面為例,要把海量商品數(shù)據(jù)全都編譯成靜態(tài)頁面,幾乎是不可能的(或許要編譯一個(gè)世紀(jì)那么長),即便都生成了,商品信息也會(huì)時(shí)不時(shí)地更新,靜態(tài)頁面需要重新生成:

    If your app has a very large number of static pages that depend on data (think: a very large e-commerce site). You want to pre-render all product pages, but then your builds would take forever.

    因此,增量靜態(tài)再生成(Incremental Static Regeneration)應(yīng)運(yùn)而生

    ISR 支持

    對于編譯時(shí)無法窮舉的海量頁面以及需要更新的場景,Next.js 允許運(yùn)行時(shí)再生成(相當(dāng)于運(yùn)行時(shí)靜態(tài)化):

    Incremental Static Regeneration allows you to update existing pages by re-rendering them in the background as traffic comes in.

    例如:

     
     
     
     
    1. export async function getStaticProps() { 
    2.   const res = await fetch('https://.../posts') 
    3.   const posts = await res.json() 
    4.  
    5.   return { 
    6.     props: { 
    7.       posts, 
    8.     }, 
    9.     // 設(shè)置有效期,開啟ISR 
    10.     revalidate: 1, // In seconds 
    11.   } 

    revalidate: 1表示運(yùn)行時(shí)(用戶請求打過來時(shí))嘗試重新生成靜態(tài) HTML,1秒最多重新生成一次

    運(yùn)行時(shí)靜態(tài)生成需要一些時(shí)間(用戶請求等著要 HTML),在此過程中有 3 種選擇:

    • fallback: false:不降級,命中尚未生成靜態(tài)頁面的路由直接 404
    • fallback: true:降級,命中尚未生成靜態(tài)頁面的路由先返回降級頁面(此時(shí)props為空,一般顯示個(gè) loading),靜態(tài)生成 HTML 的同時(shí)會(huì)生成一份 JSON 供降級頁面 CSR 使用,完成之后瀏覽器拿到數(shù)據(jù)(在客戶端填上props),渲染出完整頁面
    • fallback: 'blocking':不降級,并且要求用戶請求一直等到新頁面靜態(tài)生成結(jié)束(實(shí)際上就是 SSR,渲染過程是阻塞的,只是完成之后會(huì)保留結(jié)果 HTML)

    即結(jié)合路由(getStaticPaths)對尚未生成的頁面進(jìn)行降級,例如:

     
     
     
     
    1. // pages/index.js 
    2. import { useRouter } from 'next/router' 
    3.  
    4. function Post({ post }) { 
    5.   const router = useRouter() 
    6.  
    7.   // 渲染降級頁面 
    8.   if (router.isFallback) { 
    9.     return 
      Loading...
       
    10.   } 
    11.  
    12.   // Render post... 
    13.  
    14. export async function getStaticPaths() { 
    15.   return { 
    16.     paths: [{ params: { id: '1' } }, { params: { id: '2' } }], 
    17.     // (頁面級)降級策略,true表示遇到尚未生成的先給個(gè)降級頁,生成完畢后客戶端自動(dòng)更新過來 
    18.     fallback: true, 
    19.   } 

    P.S.具體見Incremental Static Regeneration、以及The fallback key

    然而,并非所有場景都能愉快地在編譯時(shí)靜態(tài)生成。典型的,如果組件依賴的數(shù)據(jù)是動(dòng)態(tài)的,顯然無法在編譯時(shí)預(yù)先取得數(shù)據(jù),靜態(tài)生成就無從談起了

    五.SSR 支持

    對于編譯時(shí)無法生成靜態(tài)頁面的場景,就不得不考慮 SSR 了:

    區(qū)別于 SSG getStaticProps,Next.js 提供了 SSR 專用的getServerSideProps(context):

     
     
     
     
    1. // pages/index.js 
    2. export async function getServerSideProps(context) { 
    3.   const res = await fetch(`https://...`) 
    4.   const data = await res.json() 
    5.  
    6.   if (!data) { 
    7.     return { 
    8.       notFound: true, 
    9.     } 
    10.   } 
    11.  
    12.   return { 
    13.     props: {}, // will be passed to the page component as props 
    14.   } 

    同樣用來獲取數(shù)據(jù),與getStaticProps最大的區(qū)別在于每個(gè)請求過來時(shí)都執(zhí)行,所以能夠拿到請求上下文參數(shù)(context)

    六.總結(jié)

    圍繞預(yù)渲染如何獲取數(shù)據(jù)的問題,Next.js 探索出了別致的路由支持和精巧的 SSG、SSR 支持。不僅如此,Next.js 還提供了魚和熊掌可以兼得的混用支持,不同渲染模式結(jié)合起來到底有多厲害,且看下篇分解

    參考資料

    • Pages
    • Data Fetching
    • Create a Next.js App:教程有點(diǎn)意思
    • vercel/next-learn-starter:示例 Demo

    原文鏈接:https://mp.weixin.qq.com/s/bS9GHni4ecnz9UFi9RD24Q


    標(biāo)題名稱:從Next.js看企業(yè)級框架的SSR支持
    路徑分享:http://www.dlmjj.cn/article/cogggej.html