精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

午夜精品福利一区二区蜜股av | 成人无遮挡免费网站视频在线观看| 日本亚洲三级在线| 久久精品久久久久久国产 免费| 三级黄色片播放| 国产美女高潮在线观看| 欧美激情一区在线| 成人91视频| 国产免费www| 欧美精品aa| 亚洲人成电影网站色www| 欧美丝袜在线观看| 国产99在线观看| 中文字幕一区视频| 久久婷婷人人澡人人喊人人爽| 欧美特级黄色片| 精品999网站| 最近2019中文字幕mv免费看 | 欧美这里只有精品| 风间由美一区| 成人免费视频视频在线观看免费 | 欧美少妇激情| 性做久久久久久久久| 亚洲国产婷婷香蕉久久久久久99| 国产91免费看| 国产一区二区免费视频| 国产97免费视| 亚洲影视一区二区| 国产精品激情电影| 中文字幕日韩欧美在线视频| 日本中文字幕精品| 福利一区二区三区视频在线观看| 亚洲一区二区三区视频在线播放| 日韩欧美视频一区二区| 蜜桃在线一区二区| 国产乱色国产精品免费视频| 国产精品久久久久久久久久免费 | 无码精品视频一区二区三区| 精品一区二区在线视频| 日韩av不卡在线| 日韩人妻无码一区二区三区99| 亚洲区综合中文字幕日日| 亚洲人在线观看| 亚洲国产果冻传媒av在线观看| 欧美成人精品午夜一区二区| 在线不卡a资源高清| 国产一二三四在线视频| 最新欧美电影| 色综合久久88色综合天天免费| 很污的网站在线观看| 久草在线资源站资源站| 一区二区三区免费在线观看| 欧美三级午夜理伦三级老人| 麻豆tv入口在线看| 亚洲欧洲国产专区| 波多野结衣激情| 精品孕妇一区二区三区| 国产精品久久久久久久久晋中 | 日本天堂影院在线视频| 99久久国产综合精品女不卡| 国产精品一码二码三码在线| 国产亚洲精品久久久| 亚洲自拍第三页| 国产精品视频首页| 日韩一区和二区| 人妻互换一二三区激情视频| 动漫视频在线一区| 亚洲精品国产精品乱码不99按摩 | 最近中文字幕2019免费| 999精品久久久| 国产精品麻豆久久| 美日韩精品免费观看视频| 久久精品这里只有精品| 狠狠爱www人成狠狠爱综合网| 欧美精品18videos性欧| 成年免费在线观看| 日韩国产在线观看一区| 国产女人18毛片水18精品| 国产精品无码在线播放| 国产sm精品调教视频网站| 国产乱码精品一区二区三区日韩精品| 女人18毛片一区二区三区| 91视频com| 在线观看欧美亚洲| 人人超在线公开视频| 欧美日韩精品在线视频| 网站一区二区三区| 亚洲精品aⅴ| 亚洲另类图片色| www.黄色com| 一区二区自拍| 国产欧美精品久久久| 亚洲av永久无码国产精品久久| www.日韩高清| 韩国亚洲精品| 欧美在线欧美在线| 国产精品-色哟哟| 波波电影院一区二区三区| 日本不卡在线观看| 在线看三级电影| 日韩欧美国产成人| 91亚洲一区二区| 天堂综合网久久| 色琪琪综合男人的天堂aⅴ视频| 欧美成人手机视频| 日本美女一区二区| 国产精品视频福利| 午夜毛片在线| 欧美性猛交99久久久久99按摩| 欧美大尺度做爰床戏| 伊色综合久久之综合久久| 精品亚洲一区二区三区四区五区| 精品少妇一区二区三区密爱| 99pao成人国产永久免费视频| 国产精品手机播放| 香港三日本三级少妇66| 亚洲免费资源在线播放| 日韩视频免费在线播放| 北条麻妃在线一区二区免费播放| 在线播放国产一区二区三区| 99精品视频99| 国产成人亚洲综合色影视| 日韩欧美三级一区二区| 中文不卡1区2区3区| 日韩无一区二区| 蜜桃av免费在线观看| 午夜亚洲视频| 国产精品视频免费一区| 操你啦在线视频| 欧美视频在线一区| caopeng视频| 一本色道精品久久一区二区三区| 亚洲999一在线观看www| 69视频在线| 欧美在线|欧美| 欧美老熟妇乱大交xxxxx | 亚洲一区999| 国产成人一区二区三区影院在线| 国产馆精品极品| 一区二区三区日韩视频| 高清电影一区| 粉嫩av一区二区三区四区五区 | 欧美黄网在线观看| 欧美三级电影网址| 中文字幕综合在线| 老熟妇一区二区三区啪啪| 久久天天做天天爱综合色| 久久久久久久中文| 女同久久另类99精品国产| 久久久久久久久久久免费 | 日韩久久不卡| av亚洲一区二区三区| 亚洲品质视频自拍网| 一级片中文字幕| av激情亚洲男人天堂| 欧美这里只有精品| 久久99精品久久久久久欧洲站| 欧美高跟鞋交xxxxxhd| 亚洲精品国产suv一区| 亚洲电影第三页| 国产麻豆剧传媒精品国产av| aa级大片欧美三级| 久草一区二区| 成人视屏在线观看| 色婷婷综合久久久久中文字幕1| 中文字幕人妻丝袜乱一区三区| 国产精品麻豆久久久| 日韩av片专区| 黄色成人精品网站| 久久99欧美| 欧美××××黑人××性爽 | 翡翠波斯猫1977年美国| 91福利在线尤物| 亚洲欧洲免费视频| 一区不卡在线观看| 一区二区激情小说| 日韩片在线观看| 欧美一级二级三级区| 国产成人午夜99999| 免费高清一区二区三区| 动漫av一区| 奇米成人av国产一区二区三区| 免费在线观看一级毛片| 欧美自拍偷拍一区| 中文字幕在线观看2018| 成人激情文学综合网| 成人在线免费播放视频| 91成人国产| 久久国产精品亚洲va麻豆| 一呦二呦三呦精品国产| 久久资源免费视频| 午夜影院免费视频| 91麻豆精品久久久久蜜臀| 日本亚洲欧美在线| 中文乱码免费一区二区| 少妇熟女视频一区二区三区| 久久久久看片| 亚洲啊啊啊啊啊| 精品日本12videosex| 91入口在线观看| 免费日韩电影| 欧美日韩国产999| 国产精品一二三区视频| 日韩欧美一级二级| 成人黄色免费网| 午夜亚洲福利老司机| 国产精品久久久久久成人| 成人免费视频免费观看| 欧美在线aaa| 国产日本精品| 久久久无码中文字幕久...| 要久久电视剧全集免费| 高清国产一区| 国产精品成人3p一区二区三区| 日本乱人伦a精品| 美女网站视频在线| www.日本久久久久com.| 男人久久精品| 亚洲国产高清福利视频| 国产露脸国语对白在线| 在线观看国产日韩| 韩国av免费观看| 亚洲另类色综合网站| 在线观看亚洲大片短视频| 91老师国产黑色丝袜在线| 性xxxxxxxxx| 国产呦萝稀缺另类资源| 精品久久久噜噜噜噜久久图片| 亚洲人体大胆视频| 成人短视频在线观看免费| 日韩欧美自拍| 精品无码久久久久国产| 欧美电影在线观看一区| 国产一区视频在线播放| 神马电影网我不卡| 91精品国产成人| 黄页网站在线| 欧美成人一二三| 毛片在线看网站| 最近2019中文字幕大全第二页| 欧美中文在线| 亚洲国内精品在线| 蜜桃视频污在线观看| 欧美v日韩v国产v| 国产叼嘿视频在线观看| 欧美一区二区三区白人| 国产一区二区网站| 欧美精品丝袜久久久中文字幕| 国产精品尤物视频| 91极品美女在线| 国产主播第一页| 欧美亚一区二区| 中文亚洲av片在线观看| 欧美亚洲图片小说| 中文字幕码精品视频网站| 欧美亚洲一区二区在线观看| 国产一级精品毛片| 欧美区视频在线观看| 国产精品福利电影| 欧美一区二区三区不卡| 丁香六月色婷婷| 日韩国产激情在线| 蝌蚪视频在线播放| 在线国产精品播放| 成码无人av片在线观看网站| 欧美成人免费播放| 丁香花视频在线观看| 欧美性在线观看| 丝袜美腿诱惑一区二区三区| 国产激情久久久久| 婷婷丁香久久| 成人在线看片| 亚洲第一福利社区| 日韩精品久久久免费观看| 日韩理论电影大全| 大胆欧美熟妇xx| 午夜一区不卡| 孩娇小videos精品| 国产69精品一区二区亚洲孕妇| 欲求不满的岳中文字幕| 国产色婷婷亚洲99精品小说| 三级黄色免费观看| 亚洲高清视频的网址| 偷拍盗摄高潮叫床对白清晰| 成人1区2区3区| 欧美一区二区精品在线| 蜜臀av免费在线观看| 2020国产精品极品色在线观看| 庆余年2免费日韩剧观看大牛| 日韩精品麻豆| 亚洲xxxx在线| 亚洲男人都懂第一日本| 日韩福利视频| 欧美日韩国产一区精品一区| 国产成人黄色片| 久久se精品一区二区| 国产女人18毛片水真多18| 国产欧美精品一区二区三区四区 | 日韩 欧美 视频| 国产精品综合色区在线观看| 午夜一区二区视频| 91蝌蚪porny成人天涯| 国产激情无码一区二区三区| 懂色av中文一区二区三区天美| 一级片视频网站| 欧美一级生活片| 福利视频在线看| 91国在线精品国内播放| 91麻豆精品一二三区在线| 久久爱av电影| 黄色成人av网站| 中文字幕成人在线视频| 久久你懂得1024| 久久久久久激情| 欧美日韩aaaaaa| 国产日产精品久久久久久婷婷| 久久久久久国产| 亚洲伊人精品酒店| 天堂一区二区三区| 美女国产精品| 亚洲av成人精品一区二区三区| 综合色中文字幕| 小泽玛利亚一区二区三区视频| 日韩av一区二区在线| 色呦呦在线免费观看| 国产在线拍偷自揄拍精品| 国产精品嫩模av在线| 五十路熟女丰满大屁股| 国产精品69久久久久水密桃| 亚洲天堂最新地址| www.亚洲色图.com| 日韩欧美国产成人精品免费| 色哟哟精品一区| 手机看片国产1024| 欧美激情影音先锋| 免费欧美网站| 日本一级淫片演员| 天堂午夜影视日韩欧美一区二区| 亚洲天堂美女视频| 亚洲国产精品久久不卡毛片| 日本视频网站在线观看| 亚洲国产精品高清久久久| 久久不射影院| 国产精品久久亚洲7777| 欧美精品偷拍| 亚洲黄色小说在线观看| 一区二区三区欧美在线观看| 国产ts变态重口人妖hd| 久久夜色精品国产亚洲aⅴ| 色综合视频一区二区三区日韩| 丝袜美腿玉足3d专区一区| 日韩国产一区二| 欧美精品日韩在线| 欧美人动与zoxxxx乱| 老司机av在线免费看| 91精品啪在线观看麻豆免费| 久久久久久久久久久久久久| 亚洲天堂伊人网| 亚洲精品免费在线观看| 国产精品久久综合青草亚洲AV| 精品国产欧美成人夜夜嗨| 精品一区二区三区免费看| 国产亚洲精品久久久久久久| 国产jizzjizz一区二区| 国产在线观看中文字幕| 久久综合图片| 无码熟妇人妻av| 91黄色小视频| av在线首页| 亚洲bt欧美bt日本bt| 欧美成人日韩| 男女一区二区三区| 色婷婷久久久久swag精品| 第一视频专区在线| 国产日韩换脸av一区在线观看| 91久久电影| zjzjzjzjzj亚洲女人| 日韩欧美国产中文字幕| av小片在线| 亚洲aⅴ男人的天堂在线观看| 在线成人av| 少妇无套高潮一二三区| 欧美一区二区三区四区高清| 爱情岛亚洲播放路线| 欧美日韩综合网| 国精品**一区二区三区在线蜜桃 | 欧美大秀在线观看| 成人av婷婷| 午夜激情在线观看视频| 亚洲欧美日韩中文播放| 香蕉视频免费在线看| 国产欧美精品va在线观看| 国产精品久久| 国产123在线| 精品久久久久久久一区二区蜜臀| 综合另类专区| 日本黄xxxxxxxxx100| 久久久国产精品午夜一区ai换脸| 国产伦视频一区二区三区| 亚洲小说区图片区都市|