精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

面試官:說說React服務端渲染怎么做?原理是什么?

開發 前端
在SSR中,我們了解到Server-Side Rendering ,簡稱SSR,意為服務端渲染。指由服務側完成頁面的 HTML 結構拼接的頁面處理技術,發送到瀏覽器,然后為其綁定狀態與事件,成為完全可交互頁面的過程。

[[415238]]

本文轉載自微信公眾號「JS每日一題」,作者灰灰。轉載本文請聯系JS每日一題公眾號。

一、是什么

在SSR中,我們了解到Server-Side Rendering ,簡稱SSR,意為服務端渲染

指由服務側完成頁面的 HTML 結構拼接的頁面處理技術,發送到瀏覽器,然后為其綁定狀態與事件,成為完全可交互頁面的過程

其解決的問題主要有兩個:

  • SEO,由于搜索引擎爬蟲抓取工具可以直接查看完全渲染的頁面
  • 加速首屏加載,解決首屏白屏問題

二、如何做

在react中,實現SSR主要有兩種形式:

  • 手動搭建一個 SSR 框架
  • 使用成熟的SSR 框架,如 Next.JS

這里主要以手動搭建一個SSR框架進行實現

首先通過express啟動一個app.js文件,用于監聽3000端口的請求,當請求根目錄時,返回HTML,如下:

  1. const express = require('express'
  2. const app = express() 
  3. app.get('/', (req,res) => res.send(` 
  4. <html> 
  5.    <head> 
  6.        <title>SSR demo</title> 
  7.    </head> 
  8.    <body> 
  9.        Hello world 
  10.    </body> 
  11. </html> 
  12. `)) 
  13.  
  14. app.listen(3000, () => console.log('Exampleapp listening on port 3000!')) 

然后再服務器中編寫react代碼,在app.js中進行應引用

  1. import React from 'react' 
  2.  
  3. const Home = () =>{ 
  4.  
  5.     return <div>home</div> 
  6.  
  7.  
  8. export default Home 

為了讓服務器能夠識別JSX,這里需要使用webpakc對項目進行打包轉換,創建一個配置文件webpack.server.js并進行相關配置,如下:

  1. const path = require('path')    //node的path模塊 
  2. const nodeExternals = require('webpack-node-externals'
  3.  
  4. module.exports = { 
  5.     target:'node'
  6.     mode:'development',           //開發模式 
  7.     entry:'./app.js',             //入口 
  8.     output: {                     //打包出口 
  9.         filename:'bundle.js',     //打包后的文件名 
  10.         path:path.resolve(__dirname,'build')    //存放到根目錄的build文件夾 
  11.     }, 
  12.     externals: [nodeExternals()],  //保持node中require的引用方式 
  13.     module: { 
  14.         rules: [{                  //打包規則 
  15.            test:   /\.js?$/,       //對所有js文件進行打包 
  16.            loader:'babel-loader',  //使用babel-loader進行打包 
  17.            exclude: /node_modules/,//不打包node_modules中的js文件 
  18.            options: { 
  19.                presets: ['react','stage-0',['env', {  
  20.                                   //loader時額外的打包規則,對react,JSX,ES6進行轉換 
  21.                     targets: { 
  22.                         browsers: ['last 2versions']   //對主流瀏覽器最近兩個版本進行兼容 
  23.                     } 
  24.                }]] 
  25.            } 
  26.        }] 
  27.     } 

接著借助react-dom提供了服務端渲染的 renderToString方法,負責把React組件解析成html

  1. import express from 'express' 
  2. import React from 'react'//引入React以支持JSX的語法 
  3. import { renderToString } from 'react-dom/server'//引入renderToString方法 
  4. import Home from'./src/containers/Home' 
  5.  
  6. const app= express() 
  7. const content = renderToString(<Home/>) 
  8. app.get('/',(req,res) => res.send(` 
  9. <html> 
  10.    <head> 
  11.        <title>SSR demo</title> 
  12.    </head> 
  13.    <body> 
  14.         ${content} 
  15.    </body> 
  16. </html> 
  17. `)) 
  18.  
  19. app.listen(3001, () => console.log('Exampleapp listening on port 3001!')) 

上面的過程中,已經能夠成功將組件渲染到了頁面上

但是像一些事件處理的方法,是無法在服務端完成,因此需要將組件代碼在瀏覽器中再執行一遍,這種服務器端和客戶端共用一套代碼的方式就稱之為「同構」

重構通俗講就是一套React代碼在服務器上運行一遍,到達瀏覽器又運行一遍:

  • 服務端渲染完成頁面結構
  • 瀏覽器端渲染完成事件綁定

瀏覽器實現事件綁定的方式為讓瀏覽器去拉取JS文件執行,讓JS代碼來控制,因此需要引入script標簽

通過script標簽為頁面引入客戶端執行的react代碼,并通過express的static中間件為js文件配置路由,修改如下:

  1. import express from 'express' 
  2. import React from 'react'//引入React以支持JSX的語法 
  3. import { renderToString } from'react-dom/server'//引入renderToString方法 
  4. import Home from './src/containers/Home' 
  5.   
  6. const app = express() 
  7. app.use(express.static('public')); 
  8. //使用express提供的static中間件,中間件會將所有靜態文件的路由指向public文件夾 
  9.  const content = renderToString(<Home/>) 
  10.   
  11. app.get('/',(req,res)=>res.send(` 
  12. <html> 
  13.    <head> 
  14.        <title>SSR demo</title> 
  15.    </head> 
  16.    <body> 
  17.         ${content} 
  18.    <script src="/index.js"></script> 
  19.    </body> 
  20. </html> 
  21. `)) 
  22.  
  23.  app.listen(3001, () =>console.log('Example app listening on port 3001!')) 

然后再客戶端執行以下react代碼,新建webpack.client.js作為客戶端React代碼的webpack配置文件如下:

  1. const path = require('path')                    //node的path模塊 
  2.  
  3. module.exports = { 
  4.     mode:'development',                         //開發模式 
  5.     entry:'./src/client/index.js',              //入口 
  6.     output: {                                   //打包出口 
  7.         filename:'index.js',                    //打包后的文件名 
  8.         path:path.resolve(__dirname,'public')   //存放到根目錄的build文件夾 
  9.     }, 
  10.     module: { 
  11.         rules: [{                               //打包規則 
  12.            test:   /\.js?$/,                    //對所有js文件進行打包 
  13.            loader:'babel-loader',               //使用babel-loader進行打包 
  14.            exclude: /node_modules/,             //不打包node_modules中的js文件 
  15.            options: { 
  16.                presets: ['react','stage-0',['env', {      
  17.                     //loader時額外的打包規則,這里對react,JSX進行轉換 
  18.                     targets: { 
  19.                         browsers: ['last 2versions']   //對主流瀏覽器最近兩個版本進行兼容 
  20.                     } 
  21.                }]] 
  22.            } 
  23.        }] 
  24.     } 

這種方法就能夠簡單實現首頁的react服務端渲染,過程對應如下圖:

在做完初始渲染的時候,一個應用會存在路由的情況,配置信息如下:

  1. import React from 'react'                   //引入React以支持JSX 
  2. import { Route } from 'react-router-dom'    //引入路由 
  3. import Home from './containers/Home'        //引入Home組件 
  4.  
  5. export default ( 
  6.     <div> 
  7.         <Route path="/" exact component={Home}></Route> 
  8.     </div> 

然后可以通過index.js引用路由信息,如下:

  1. import React from 'react' 
  2. import ReactDom from 'react-dom' 
  3. import { BrowserRouter } from'react-router-dom' 
  4. import Router from'../Routers' 
  5.  
  6. const App= () => { 
  7.     return ( 
  8.         <BrowserRouter> 
  9.            {Router} 
  10.         </BrowserRouter> 
  11.     ) 
  12.  
  13. ReactDom.hydrate(<App/>, document.getElementById('root')) 

這時候控制臺會存在報錯信息,原因在于每個Route組件外面包裹著一層div,但服務端返回的代碼中并沒有這個div

解決方法只需要將路由信息在服務端執行一遍,使用使用StaticRouter來替代BrowserRouter,通過context進行參數傳遞

  1. import express from 'express' 
  2. import React from 'react'//引入React以支持JSX的語法 
  3. import { renderToString } from 'react-dom/server'//引入renderToString方法 
  4. import { StaticRouter } from 'react-router-dom' 
  5. import Router from '../Routers' 
  6.   
  7. const app = express() 
  8. app.use(express.static('public')); 
  9. //使用express提供的static中間件,中間件會將所有靜態文件的路由指向public文件夾 
  10.  
  11. app.get('/',(req,res)=>{ 
  12.     const content  = renderToString(( 
  13.         //傳入當前path 
  14.         //context為必填參數,用于服務端渲染參數傳遞 
  15.         <StaticRouter location={req.path} context={{}}> 
  16.            {Router} 
  17.         </StaticRouter> 
  18.     )) 
  19.     res.send(` 
  20.    <html> 
  21.        <head> 
  22.            <title>SSR demo</title> 
  23.        </head> 
  24.        <body> 
  25.        <div id="root">${content}</div> 
  26.        <script src="/index.js"></script> 
  27.        </body> 
  28.    </html> 
  29.     `) 
  30. }) 
  31.  
  32.  
  33. app.listen(3001, () => console.log('Exampleapp listening on port 3001!')) 

這樣也就完成了路由的服務端渲染

三、原理

整體react服務端渲染原理并不復雜,具體如下:

node server 接收客戶端請求,得到當前的請求url 路徑,然后在已有的路由表內查找到對應的組件,拿到需要請求的數據,將數據作為 props、context或者store 形式傳入組件

然后基于 react 內置的服務端渲染方法 renderToString()把組件渲染為 html字符串在把最終的 html進行輸出前需要將數據注入到瀏覽器端

瀏覽器開始進行渲染和節點對比,然后執行完成組件內事件綁定和一些交互,瀏覽器重用了服務端輸出的 html 節點,整個流程結束

參考文獻

  • https://zhuanlan.zhihu.com/p/52693113
  • https://segmentfault.com/a/1190000020417285
  • https://juejin.cn/post/6844904000387563533#heading-14

 

責任編輯:武曉燕 來源: JS每日一題
相關推薦

2024-08-22 10:39:50

@Async注解代理

2024-03-05 10:33:39

AOPSpring編程

2024-02-29 16:49:20

volatileJava并發編程

2024-11-19 15:13:02

2024-08-29 16:30:27

2023-12-27 18:16:39

MVCC隔離級別幻讀

2024-08-12 17:36:54

2025-04-16 00:00:01

JWT客戶端存儲加密令

2025-09-29 01:00:00

2021-06-29 09:47:34

ReactSetState機制

2021-06-30 07:19:36

React事件機制

2024-03-14 14:56:22

反射Java數據庫連接

2024-03-28 10:37:44

IoC依賴注入依賴查找

2024-12-06 07:00:00

2024-07-31 08:28:37

DMAIOMMap

2024-09-20 08:36:43

零拷貝數據傳輸DMA

2024-03-11 18:18:58

項目Spring線程池

2024-03-22 06:56:24

零拷貝技術數據傳輸數據拷貝

2021-05-20 08:34:03

CDN原理網絡

2021-05-06 14:34:12

Webpack熱更新程序
點贊
收藏

51CTO技術棧公眾號

91香蕉视频在线| 日本高清不卡一区二区三区视频| 国产一区日韩一区| 欧美性猛交一区二区三区精品| 91人成网站www| 91网站免费视频| 免费影视亚洲| 国内精品视频666| 亚洲女同精品视频| 国产午夜福利100集发布| 国产免费无遮挡| 九九视频精品全部免费播放| 亚洲亚洲精品在线观看| 国产精品自拍网| 中国美女乱淫免费看视频| 性欧美ⅴideo另类hd| 久久成人免费网站| 国产一区二区三区视频| 1024精品视频| 欧美一区二区公司| 欧美三区不卡| 欧美一二三区在线观看| 亚洲最新在线| 97人妻精品视频一区| 18岁网站在线观看| 91精品人妻一区二区| 丁香花视频在线观看| 国产精品中文字幕日韩精品| 久久精品久久精品亚洲人| 91香蕉视频污版| 精品av中文字幕在线毛片| 国产一区二区精品| 亚洲精品乱码久久久久久金桔影视| 17c丨国产丨精品视频| 国产av一区二区三区| 91超碰国产精品| 91麻豆精品国产91久久久久| 在线免费观看一区二区三区| 一区二区三区日| 久久久久久久久丰满| 777久久久精品| 中文字幕色一区二区| 亚洲最新av网站| 91免费精品| 欧美一级黄色录像| 欧美视频在线第一页| 国产高中女学生第一次| 欧美激情性爽国产精品17p| 日韩欧美成人一区二区| 妞干网视频在线观看| 黑人操亚洲女人| 亚洲视频成人| 亚洲天堂av综合网| 欧美激情第3页| 1区2区在线观看| 成人激情av网| 热门国产精品亚洲第一区在线| 最近中文字幕免费视频| 欧美久久久网站| 亚洲精品视频自拍| 精品国产一区二区三区麻豆小说 | av成人在线观看| 久久久亚洲欧洲日产国码αv| 国产精品成人观看视频国产奇米| 国产极品视频在线观看| 一区中文字幕电影| 欧美性猛交xxxx乱大交蜜桃| 亚洲视频小说| 六月婷婷综合网| 欧美中文字幕| 久久精品一本久久99精品| 91传媒理伦片在线观看| 婷婷激情一区| 一级特黄大欧美久久久| 欧美一区二区高清在线观看| 国产免费一区二区三区最新不卡| 在线成人亚洲| xxxx性欧美| 人妻熟女aⅴ一区二区三区汇编| 日本精品网站| 亚洲地区一二三色| 一区二区三区精品国产| 人妻一区二区三区免费| 精品一区二区在线免费观看| 韩国v欧美v日本v亚洲| 黄大色黄女片18免费| 红杏成人性视频免费看| 欧美三级日韩三级| 欧美色图另类小说| 超黄网站在线观看| 综合久久国产九一剧情麻豆| 欧美日韩国产综合在线| 性欧美一区二区三区| 丝袜美腿亚洲一区二区图片| 欧美福利视频网站| 日本二区三区视频| 日本三级免费观看| 后入内射欧美99二区视频 | 欧美日本视频在线观看| 老司机免费在线视频| 久久综合色婷婷| 国产精品一国产精品最新章节| 在线免费看毛片| 久久精品人人| 777777777亚洲妇女| 劲爆欧美第一页| 亚洲欧美在线专区| 中文字幕亚洲欧美一区二区三区 | 免费观看日批视频| 在线精品一区| 欧美激情视频免费观看| www.超碰在线观看| 久久激情电影| 日韩中文娱乐网| 亚洲午夜精品久久久久久高潮| 日韩系列在线| 亚洲精品久久久久中文字幕欢迎你 | 国产一区清纯| 久久成人18免费网站| 呻吟揉丰满对白91乃国产区| 蜜桃成人av| 亚洲老头同性xxxxx| 亚洲一区二区在线免费| 99re8这里有精品热视频8在线 | 久久人人爽国产| 久久久久久国产精品视频| 中文一区一区三区免费在线观看| 精品国偷自产在线视频99| 久久视频中文字幕| 欧洲xxxxx| 免费日本一区二区三区视频| 国产精品色噜噜| 一区二区精品国产| 成人免费在线| 一区二区不卡在线视频 午夜欧美不卡在| 色一情一乱一乱一区91| a级网站在线播放| 亚洲情趣在线观看| 日韩中文字幕亚洲精品欧美| 色呦呦在线观看视频| 亚洲成人免费视频| 免费看日本毛片| sis001欧美| 欧美日韩久久久| 一级 黄 色 片一| 国产精品毛片视频| 亚洲欧美国产日韩天堂区| 久操视频在线观看免费 | 色狠狠久久av五月综合| 青青草免费在线| 中文字幕精品一区 | 欧美久久综合| 26uuu日韩精品一区二区| 天天干天天操天天操| 久久99九九99精品| 成人在线视频电影| 欧美在线一卡| 亚洲视频一二三| 成人福利电影精品一区二区在线观看| 97激碰免费视频| 欧美一区二区三区不卡视频| 蜜臀久久久99精品久久久久久| 亚洲va久久久噜噜噜久久天堂| 天堂在线资源网| 国产精品麻豆一区二区| 成人小视频在线观看免费| 一区二区精品伦理...| 欧美色偷偷大香| 亚洲啪av永久无码精品放毛片 | 免费在线成人| 国产有码在线一区二区视频| 日本高清视频免费观看| 国产精品美女久久久久久久| 日本精品久久久久久久久久| aaaa欧美| 精品偷拍各种wc美女嘘嘘| 中国美女黄色一级片| 亚洲视频播放| 亚洲淫片在线视频| 国产精品一二三区视频| 亚洲午夜久久久久中文字幕久| 男女男精品视频站| 好吊妞视频这里有精品| 日韩视频欧美视频| 亚洲欧美一二三区| av亚洲精华国产精华| 国产精品美女在线播放| 色婷婷综合久久久中字幕精品久久| 欧美成人a∨高清免费观看| 日本一级免费视频| 夜久久久久久| 国产66精品久久久久999小说| 男人在线资源站| 福利视频导航一区| 亚洲成a人无码| 欧美成人自拍| 国产极品jizzhd欧美| 婷婷五月综合激情| 亚洲一区二区三区四区的| 性欧美在线视频| 欧美一区二区三| 欧美在线免费看| 日本毛片在线观看| 亚洲午夜久久久久久久久电影网 | 欧美成人资源| 日韩电影网在线| 精品在线视频观看| 国产福利精品一区二区| 中文字幕中文字幕99| 国产一区精品福利| 在线精品高清中文字幕| 无码人妻精品一区二区蜜桃色欲| 9色porny自拍视频一区二区| 免费的一级黄色片| 日韩精品一区二区三区中文字幕| 久久精品中文字幕免费mv| 欧美不卡视频一区发布| 嫩草影院一区二区三区| 26uuu另类欧美| 成人在线观看黄| 免费欧美一区| 国产精品久久久久久av| 日本在线视频站| 欧美日韩另类国产亚洲欧美一级| 欧美偷拍一区二区三区| 日本中文字幕一区二区视频| 偷拍视频一区二区| jizz久久久久久| www.欧美精品| 精品乱子伦一区二区| 亚洲免费观看在线观看| 无码国产精品久久一区免费| 在线看片一区| 久久久影院一区二区三区| 国产精品扒开腿做爽爽爽视频软件| 亚洲欧洲中文天堂| 中文字幕在线播出| 最新久久zyz资源站| 一卡二卡三卡四卡五卡| 在线观看视频日韩| 青青草原成人| 成人免费观看49www在线观看| 欧美国产日韩视频| 五月婷婷六月激情| 91成人在线精品| 国产在线观看免费视频软件| 国产精品18久久久久久vr| 亚洲日本在线a| 日本在线视频www色| 伊人久久影院| 国产成人拍精品视频午夜网站| 91电影在线播放| 欧美大胆人体bbbb| 精品国产一区二区三区四| 中文字幕国产精品一区二区| 久久久久久国产精品日本| 国产麻豆综合| 大桥未久一区二区三区| 欧美美女黄色| 国产欧美精品一区二区三区介绍| 色呦呦在线播放| 亚洲人成网站777色婷婷| 国产麻豆免费视频| 欧美日韩国产区| 三级黄色录像视频| 久久亚洲一级片| 奇米777在线视频| 首页亚洲欧美制服丝腿| 国产在线无码精品| 精品国产精品国产偷麻豆| 91手机在线观看| 3d性欧美动漫精品xxxx软件| 九九久久精品一区| 成年人在线观看视频| 精品乱人伦小说| 中文字幕在线播放日韩| 精品久久久中文| 久久久久久视频| 国产色爱av资源综合区| 在线中文字日产幕| 麻豆91在线播放| 欧美韩国日本在线| 国产精品九九| 精品日韩在线播放| 日本在线电影一区二区三区| 精品不卡一区二区三区| 久久爱www.| 国产有码在线一区二区视频| xx欧美视频| 97精品久久久| 污视频网站在线免费| 色妞色视频一区二区三区四区| 欧美日本网站| 亚洲国产天堂久久综合网| 国产女主播福利| 欧美绝品在线观看成人午夜影视| 免费的毛片视频| 欧美女子与性| 午夜av区久久| 久久精品www| 亚洲色图制服诱惑| 91av手机在线| 国产精品久久午夜| 国产黄a三级三级| 国产精品免费视频网站| 国产精品密蕾丝袜| 久久精品网站免费观看| 国产又爽又黄无码无遮挡在线观看| 成人免费视频网站在线观看| 色综合久久久无码中文字幕波多| 国产麻豆精品视频| 亚洲一区二区福利视频| 免费欧美日韩国产三级电影| 中文字幕网av| 蜜臀精品久久久久久蜜臀| 少妇激情一区二区三区| 免费亚洲电影在线| 天天操天天干天天做| 久久er精品视频| 久久精品国产露脸对白| 国产一区二区在线影院| 韩国三级hd中文字幕有哪些| 国产高清亚洲一区| 中国免费黄色片| 91污在线观看| 深爱五月激情网| 日本一区二区免费在线观看视频 | 欧美激情资源网| 亚洲精品成人av久久| 国产精品久久久久久久久快鸭| 中文字幕在线观看二区| 中文字幕一区二区三区乱码在线| 中文字幕美女视频| 亚洲在线免费播放| 日韩免费av片| 色综合色综合色综合色综合色综合| 国产精品国产三级国产专区52| 色婷婷精品大视频在线蜜桃视频| 亚洲av人无码激艳猛片服务器| 欧美人牲a欧美精品| 亚洲av综合色区无码一二三区 | 欧洲一级在线观看| 一区二区三欧美| 成人黄视频在线观看| 日韩欧美在线免费| 久久精品丝袜高跟鞋| 免费看成人哺乳视频网站| 一区二区精品国产| 韩日视频一区| 一级黄色香蕉视频| 国产一区二区三区四 | 久久久亚洲高清| 日韩在线一卡二卡| 午夜精品影院在线观看| 天堂免费在线视频| 日韩天堂在线观看| 可以在线观看的av网站| www.亚洲成人| av资源在线播放| 国产精品视频在线播放| 在线综合色站| 相泽南亚洲一区二区在线播放| 欧美激情性爽国产精品17p| 精品久久久久久久无码| 成人福利视频在线| 日韩亚洲欧美中文字幕| 无吗不卡中文字幕| 一级特黄特色的免费大片视频| 亚洲第一偷拍网| 男人影院在线观看| 欧美一级在线亚洲天堂| 香蕉大人久久国产成人av| 日本一区二区三区精品视频| 亚洲视频福利| 三级av免费观看| 久久蜜桃av一区精品变态类天堂| 欧美成人aaa片一区国产精品| 色婷婷av一区二区三区大白胸| 亚洲春色一区二区三区| 中文字幕久热精品在线视频| 黄色激情在线播放| 动漫一区二区在线| 911精品美国片911久久久| 91香蕉视频污版| 久久综合五月天婷婷伊人| 免费毛片在线播放免费| 欧美喷水一区二区| 国产一级免费在线观看| 性日韩欧美在线视频| 日韩中文字幕| 最近中文字幕免费mv| 秋霞成人午夜伦在线观看| 国产亚洲色婷婷久久99精品91| 亚洲精品中文字幕乱码三区| 在线观看亚洲国产| 揄拍成人国产精品视频| 欧美黄色网页| 欧美乱偷一区二区三区在线| 99国内精品| 怡红院一区二区|