亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

React SSR樣式及SEO的實踐

2019-11-19 12:39:05
字體:
來源:轉載
供稿:網友

前一篇主要記錄了一下SSR配置以及結合Redux的使用。這里簡單說一下React SSR中樣式處理和更優雅的SEO

SSR樣式

在React客戶端渲染,添加樣式很容易。寫一個css樣式文件,在對應組件中引用。標簽上通過className這個屬性調用對應樣式就萬事Ok了。當然我們需要在webpack中配置loader來解析css文件。一般的配置如下(使用css modules):

module: { rules: [{  test: //.css?$/,  use: ['style-loader', {   loader: 'css-loader',   options: {    importLoader: 1,    modules: true,    localIdentName: '[name]_[local]_[hash:base64:5]'   }  }] }]}

需要先通過css-loader解析css文件,之后再通過style-loader將樣式放在html的style標簽中。

那么SSR也這樣行嗎~

yarn dev

跑一下服務,發現命令行報這個錯誤:

return window && document && document.all && !window.atob;
^

ReferenceError: window is not defined

原因在于服務器端渲染哪里有window對象,哪里有DOM啊。我們是通過虛擬DOM。renderToString這個方法生成出來的html字符串。stackoverflow搜了一下發現了isomorphic-style-loader這個專門用于同構的style-loader。

話不多少搞起來??蛻舳说膚ebpack配置不需要變更還是使用css-loader+style-loader。服務器端就使用css-loader+isomorphic-style-loader了(和style-loader用法一波一樣)

// webpack.server.js module: {  rules: [{   test: //.css?$/,   use: ['isomorphic-style-loader', {    loader: 'css-loader',    options: {     importLoader: 1,     modules: true,     localIdentName: '[name]_[local]_[hash:base64:5]'    }   }]  }] }

配置好了Run一下,不報錯了但是會閃一下屏。禁用掉js發現server端生成的html并沒有樣式,當客戶端JS接管程序之后才會有樣式出現。這樣的體驗相當糟糕。

當然我們確實沒有向服務器端生成的HTML添加style標簽。

現在服務器返給我們的html是這樣的

return `  <html>   <head>    <title>ssr</title>   </head>   <body>    <div id='root' >${ content }</div>    <script>     window.context = {      state: ${ JSON.stringify(store.getState()) }     }    </script>    <script src='/index.js' ></script>   </body>  </html> `

這時我們想到了context這個玩意。在server端render之前。我們設置一個

let context = { css: []}

我們還知道在服務端渲染的時候有this.props.staticContext這樣一個props拿到我們設置context。另外isomorphic-style-loader提供給我們了

_getCss()這個方法??梢栽赟SR過程中拿到樣式。有了這兩個必要條件。我們就可以在每一個用到樣式的Component中通過componentWillMount這個生命周期

添加這樣一段代碼:

componentWillMount () { if (this.props.staticContext) { // 只有服務端渲染時候有this.props.staticContext以及_getCss()  this.props.staticContext.css.push(styles._getCss()) }}

這樣樣式就存儲在context這個變量的css數組中咯,改造一下server端的html輸出代碼:

const cssStr = context.css.length ? context.css.join('/n') : '' return `   <html>    <head>     <title>ssr</title>     <style>${cssStr}</style>    </head>    <body>     <div id='root' >${content}</div>     <script>      window.context = {       state: ${JSON.stringify(store.getState())}      }     </script>     <script src='/index.js' ></script>    </body>   </html>  `

萬事👌,當然我們可以進一步優化,把componentWillMount所做的事情提出來搞一個HOC(高階組件)。

withStylesHOC.js

import React, { Component} from 'react'export default (DecoratedComponent, styles) => { return class NewComponent extends Component {  componentWillMount () {   if (this.props.staticContext) {    this.props.staticContext.css.push(styles._getCss())   }  }  render () {   return <DecoratedComponent {...this.props} />  } }}

這樣簡單的封裝一個HOC,之后涉及樣式的時候直接通過withStylesHOC包裹一下就好。例如一個結合Redux的Home組件:

export default connect(mapState, mapDispatch)(withStyle(Home, styles))

SSR-SEO

費大力氣通過一個node中間層去實現首屏的SSR,除開首屏速度之外,就是SEO這一大塊了,對于一個商業網站來講真的很重要。

SEO(Search Engine Optimization)亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

91久久嫩草影院一区二区| 一区二区三区 在线观看视| 欧美色视频日本高清在线观看| 国产丝袜一区二区三区免费视频| 91社区国产高清| 国产成人小视频在线观看| 中文.日本.精品| 韩国精品美女www爽爽爽视频| 91久久嫩草影院一区二区| 欧美激情女人20p| 久久久久久国产精品久久| 国产欧美精品日韩精品| 国产精品成人久久久久| 欧美亚洲午夜视频在线观看| 日韩一区av在线| 日韩在线观看av| 91国产精品视频在线| www.国产一区| 国产精品日韩欧美综合| 热久久免费视频精品| 亚洲精品资源美女情侣酒店| 日韩免费视频在线观看| 久久久久久久久久国产精品| 亚洲国产一区二区三区四区| 亚洲一区二区三区四区在线播放| 中文字幕亚洲二区| 国产精品影片在线观看| 久久久久久有精品国产| 亚洲男人天堂2023| 欧美劲爆第一页| 色综合老司机第九色激情| 国产精品久久二区| 中文字幕欧美在线| 日韩欧美成人免费视频| 国产精品99导航| 国产日韩精品在线观看| 97婷婷涩涩精品一区| 欧美激情中文网| 成人性生交xxxxx网站| 精品亚洲永久免费精品| 国产成人精品电影| 国产精品高潮粉嫩av| 国产精品美女久久| 国产日韩欧美一二三区| 国产视频在线观看一区二区| 亚洲欧洲午夜一线一品| 国产亚洲日本欧美韩国| 欧美在线观看日本一区| 国产在线播放91| 久久久久亚洲精品成人网小说| 久久国产精品久久精品| 国产成人精品午夜| 国产一区二区美女视频| 午夜精品久久久久久99热软件| 欧美在线视频观看免费网站| 欧美激情在线观看视频| 中文字幕最新精品| 欧美巨乳在线观看| 国产精品第二页| 国产精品三级美女白浆呻吟| 日韩一区二区三区国产| 日韩欧美在线第一页| 亚洲在线第一页| 国产亚洲欧洲黄色| 精品无人区太爽高潮在线播放| 一区二区福利视频| 欧美色道久久88综合亚洲精品| 91精品国产综合久久香蕉922| 午夜免费在线观看精品视频| 亚洲成人精品视频| 九九精品在线视频| 日本久久久久久| 美女啪啪无遮挡免费久久网站| 国产成人一区二区三区小说| 一个人看的www欧美| 中文字幕亚洲欧美日韩2019| 视频直播国产精品| 欧美日韩性生活视频| 亚洲国产天堂久久国产91| 青青久久av北条麻妃黑人| 国产精品青青在线观看爽香蕉| 欧美大片在线免费观看| 成人亚洲激情网| 热99精品只有里视频精品| 国产精品久久久久久久天堂| 国产精品久久久久久久久久尿| 姬川优奈aav一区二区| 欧美精品国产精品日韩精品| 欧美国产精品人人做人人爱| 国产欧美精品日韩精品| 国产成人精品久久二区二区91| 久久久噜噜噜久久久| 国产精品一区二区三区成人| 夜夜狂射影院欧美极品| 日韩国产高清视频在线| 26uuu久久噜噜噜噜| 最新中文字幕亚洲| 亚洲精品网站在线播放gif| 欧美裸体xxxx| 国产午夜精品麻豆| 亚洲最大av在线| 国产91热爆ts人妖在线| 91av在线影院| 日韩精品福利网站| 日韩黄在线观看| 一区二区在线免费视频| 国产精品视频永久免费播放| 日韩欧美一区视频| 亚洲电影免费在线观看| 国产一区香蕉久久| 欧美日本高清视频| www.久久久久| 日韩中文字幕精品视频| 欧美国产视频一区二区| 97视频在线观看网址| 日本三级韩国三级久久| 亚洲精品中文字幕有码专区| 97视频在线观看视频免费视频| 日韩av大片免费看| 97色在线观看免费视频| 亚洲最大中文字幕| 91精品91久久久久久| 91精品免费久久久久久久久| 性色av一区二区三区在线观看| 日韩中文在线不卡| 欧美黑人巨大xxx极品| 亚洲第一精品电影| 久久九九有精品国产23| 国产亚洲精品久久久久久牛牛| 欧美日韩成人网| 91情侣偷在线精品国产| 精品日本美女福利在线观看| 亚洲最大福利网站| 亚洲视频欧洲视频| 色777狠狠综合秋免鲁丝| 亚洲在线视频福利| 亚洲国产91精品在线观看| 日韩精品福利网站| 日韩美女在线观看一区| 日韩美女视频免费在线观看| 欧美精品少妇videofree| 欧美性xxxxx| 欧美午夜片在线免费观看| 欧美最猛性xxxx| 国产三级精品网站| 亚洲综合日韩在线| 91视频国产精品| 国产精品盗摄久久久| 亚洲免费av电影| 亚洲精品福利在线观看| 亚洲欧美综合精品久久成人| 国产69精品久久久久99| 欧美成人精品h版在线观看| 欧美激情精品久久久久久| 久久福利视频网| 久久韩剧网电视剧| 欧美视频专区一二在线观看| 成人精品一区二区三区| 亚洲欧美中文字幕在线一区| 成人免费福利视频| 韩国三级电影久久久久久| 精品国偷自产在线| 欧美人与性动交| 欧美最猛黑人xxxx黑人猛叫黄|