前後端同構渲染:當客戶端請求一個包含React元件頁面的時候,服務端首先回應輸出這個頁面,客戶端和服務端有了第一次互動。然後,如果載入元件的過程需要向服務端發出Ajax請求等,客戶端和服務端又進行了一次交互,這樣,耗時相對較長。前後端同構渲染可以在頁面初次載入時把所有地方渲染好一次性回應給客戶端。
本文主要跟大家分享react前後端同構渲染,小編覺得蠻不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧,希望能幫助大家。
實作方式:保證套件管理工具和模組依賴方式一致
套件管理工具-npm管理,保證前後端都使用同一個相容套件
模組依賴方式-webpack,確保前後端都採用commonjs的依賴方式,確保程式碼可以互相依賴
服務端如何渲染:
##react全家桶:react、react-router、redux
react 和reactDOM
react-router
app.use(async (ctx, next) => { match({ location: ctx.originalUrl, routes }, callback) // 渲染完成之后,调用 callback 回调 // 将 组件 renderToString 返回前端即可 })對於前端來說,其實也是處理的上面這些邏輯,不過它被很好的封裝在元件中,我們只需要寫好聲明式的路由,這一切就可以隨著url 的變化自動發生。
redux
前端透過取得初始狀態,產生跟後端徐然完成後一模一樣的store,就可以保證前後端渲染資料的一致性,以確保前後端產生的dom結構一致。
最佳化結果:
可維護性差的問題:同構應用可以進行大量的程式碼公用,包括工具方法、常數、頁面元件和redux 的大部分邏輯等,可重複使用性大大提高;首屏效能、SEO 等
處理過程:
<p id="root">@@@</p> ###以上,當客戶端發出首次請求,服務端渲染出元件的html內容放@@@這個位置,然後服務端再渲染出類似這樣的js程式碼段把元件最終渲染到DOM上。也就是說,renderApp方法其實就是在渲染元件。 2、而為了直接呼叫renderApp方法,必須讓renderApp方法成為window下的方法
window.renderApp = function(){ReactDOM.render(...)}3、服務端取出index.html,渲染出佔位符的內容,取代佔位符,並一次回應給客戶端案例#檔案結構
browser.js(在这里把渲染组件的过程赋值给window.renderApp) bundle.js(把browser.js内容bundle到这里) Component.js(组件在这里定义) express.js(服务端) index.html(同构直出的页面) package.jsonindex.html,直出頁面放上佔位符
<!doctype html> <html> <head> <meta charset="UTF-8"> <title>Untitled Document</title> </head> <body> <p id="root">@@@</p> <script src="bundle.js"></script> ### </body> </html>Component.js,在這裡定義元件
var React = require('react'); var ReactDOM = require('react-dom'); var Component = React.createClass({ clickHandler: function(){ alert(this.props.msg) }, render: function(){ return React.createElement('button', {onClick: this.clickHandler}, this.props.msg) } }) module.exports = Component;browser.js,把元件渲染過程賦值給window物件
#
var React = require('react'); var ReactDOM = require('react-dom'); var Component = React.createFactory(require('./Component')); window.renderApp = function(msg){ ReactDOM.render(Component({msg: msg}), document.getElementById('root')); }
可以通过来触发组件的渲染。稍后,在服务端会把这段代码渲染出来。
express.js,服务端
以上,需要直出的页面有了占位符,定义了组件,并把渲染组件的过程赋值给了window对象,服务端现在要做的工作就是:生成组件的html和渲染组件的js,放到直出页面index.html的占位符位置。
var express = require('express'); var React = require('react'); var ReactDOMServer = require('react-dom/server'); var fs = require('fs'); var Component = React.createFactory(require('./Component')); //原先把文件读出来 var BUNDLE = fs.readFileSync('./bundle.js',{encoding:'utf8'}); var TEMPLATE = fs.readFileSync('./index.html',{encoding:'utf8'}); var app = express(); function home(req, res){ var msg = req.params.msg || 'Hello'; var comp = Component({msg: msg}); //@@@占位符的地方放组件 var page = TEMPLATE.replace('@@@', ReactDOMServer.renderToString(comp)); //###占位符的地方放js page = page.replace('###', '<script>renderApp("'+msg+'")</script>') res.send(page); } //路由 app.get('', home); app.get('/bundle.js', function(req, res){ res.send(BUNDLE); }) app.get('/:msg', home); app.listen(4000);
package.json中的配置
"scripts": { "start": "watchify ./browser.js -o ./bundle.js" },
启动方式
运行:npm start
运行:node express.js
浏览:localhost:4000
相关推荐:
以上是react前後端同構渲染實例分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!