最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React SSR樣式及SEO的實(shí)踐

 更新時(shí)間:2018年10月22日 14:48:04   作者:Lac  
這篇文章主要介紹了React SSR樣式及SEO的實(shí)踐,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

前一篇主要記錄了一下SSR配置以及結(jié)合Redux的使用。這里簡(jiǎn)單說(shuō)一下React SSR中樣式處理和更優(yōu)雅的SEO

SSR樣式

在React客戶端渲染,添加樣式很容易。寫一個(gè)css樣式文件,在對(duì)應(yīng)組件中引用。標(biāo)簽上通過(guò)className這個(gè)屬性調(diào)用對(duì)應(yīng)樣式就萬(wàn)事Ok了。當(dāng)然我們需要在webpack中配置loader來(lái)解析css文件。一般的配置如下(使用css modules):

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

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

那么SSR也這樣行嗎~

yarn dev

跑一下服務(wù),發(fā)現(xiàn)命令行報(bào)這個(gè)錯(cuò)誤:

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

ReferenceError: window is not defined

原因在于服務(wù)器端渲染哪里有window對(duì)象,哪里有DOM啊。我們是通過(guò)虛擬DOM。renderToString這個(gè)方法生成出來(lái)的html字符串。stackoverflow搜了一下發(fā)現(xiàn)了isomorphic-style-loader這個(gè)專門用于同構(gòu)的style-loader。

話不多少搞起來(lái)??蛻舳说膚ebpack配置不需要變更還是使用css-loader+style-loader。服務(wù)器端就使用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一下,不報(bào)錯(cuò)了但是會(huì)閃一下屏。禁用掉js發(fā)現(xiàn)server端生成的html并沒(méi)有樣式,當(dāng)客戶端JS接管程序之后才會(huì)有樣式出現(xiàn)。這樣的體驗(yàn)相當(dāng)糟糕。

當(dāng)然我們確實(shí)沒(méi)有向服務(wù)器端生成的HTML添加style標(biāo)簽。

現(xiàn)在服務(wù)器返給我們的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>
 `

這時(shí)我們想到了context這個(gè)玩意。在server端render之前。我們?cè)O(shè)置一個(gè)

let context = {
 css: []
}

我們還知道在服務(wù)端渲染的時(shí)候有this.props.staticContext這樣一個(gè)props拿到我們?cè)O(shè)置context。另外isomorphic-style-loader提供給我們了

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

添加這樣一段代碼:

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

這樣樣式就存儲(chǔ)在context這個(gè)變量的css數(shù)組中咯,改造一下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>
  `

萬(wàn)事👌,當(dāng)然我們可以進(jìn)一步優(yōu)化,把componentWillMount所做的事情提出來(lái)搞一個(gè)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} />
  }
 }
}

這樣簡(jiǎn)單的封裝一個(gè)HOC,之后涉及樣式的時(shí)候直接通過(guò)withStylesHOC包裹一下就好。例如一個(gè)結(jié)合Redux的Home組件:

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

SSR-SEO

費(fèi)大力氣通過(guò)一個(gè)node中間層去實(shí)現(xiàn)首屏的SSR,除開首屏速度之外,就是SEO這一大塊了,對(duì)于一個(gè)商業(yè)網(wǎng)站來(lái)講真的很重要。

SEO(Search Engine Optimization)– 通過(guò)一些技術(shù)手段讓網(wǎng)站在搜索引擎的排名盡量靠前一點(diǎn)。由于客戶端渲染出來(lái)的網(wǎng)站只有<div id='root'>這樣的html節(jié)點(diǎn)。大多數(shù)搜索引擎分析不出來(lái)網(wǎng)站上有什么。SSR直接渲染出來(lái)HTML,這樣對(duì)搜索引擎就友好了很多。

SSR中的SEO

這里我們使用github上的一個(gè)庫(kù)react-helmet首先需要在對(duì)應(yīng)的頁(yè)面組件中引入react-helmet,就可以在Helmet標(biāo)簽內(nèi)自由添加title、meta咯

// Home.jax
import { Helmet } from 'react-helmet'
class Home extends Component {
 render() {
  return (
   <Fragment>
    <Helmet>
     <title>SRR-Home</title>
     <meta name='description' content='this is a home Component' />
    </Helmet>
     ...
     ...
   </<Fragment>>
  )
 }
}

之后按照readme所說(shuō)的。在server端這樣處理

ReactDOMServer.renderToString(<Handler />);
const helmet = Helmet.renderStatic();

并在返回的html字符串中 ${helmet.title.toString()} ${helmet.meta.toString()}進(jìn)行填充

<html>
 <head>
  ${helmet.title.toString()}
  ${helmet.meta.toString()}
  <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>

重新跑一下 搞定!

當(dāng)然SSR-SEO絕不這么簡(jiǎn)單。僅僅在頁(yè)面上添加head標(biāo)簽內(nèi)加上title 和meta標(biāo)簽影響是有限的。8102年的搜索爬蟲已經(jīng)不單單去匹配title和 description,而是全穩(wěn)的匹配(也就是說(shuō)title和descript有影響但是影響很?。┧阉髋老x會(huì)把整個(gè)網(wǎng)站所有的文本收集起來(lái)進(jìn)行分析。

那么如何做好SEO

題外話順便說(shuō)一下如何做好SEO。一個(gè)網(wǎng)站無(wú)非三大塊內(nèi)容,文字、多媒體、鏈接。要做到的是文字的原創(chuàng)性,圖片的原創(chuàng)性以及高清度還有站內(nèi)鏈接盡量和站內(nèi)內(nèi)容相關(guān)。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • ReactNative?狀態(tài)管理redux使用詳解

    ReactNative?狀態(tài)管理redux使用詳解

    這篇文章主要介紹了ReactNative?狀態(tài)管理redux使用詳解
    2023-03-03
  • react項(xiàng)目中@路徑簡(jiǎn)單配置指南

    react項(xiàng)目中@路徑簡(jiǎn)單配置指南

    這篇文章主要給大家介紹了關(guān)于react項(xiàng)目中@路徑簡(jiǎn)單配置的相關(guān)資料,文中還介紹了React配置@路徑別名的方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • 使用React Native創(chuàng)建以太坊錢包實(shí)現(xiàn)轉(zhuǎn)賬等功能

    使用React Native創(chuàng)建以太坊錢包實(shí)現(xiàn)轉(zhuǎn)賬等功能

    這篇文章主要介紹了使用React Native創(chuàng)建以太坊錢包,實(shí)現(xiàn)轉(zhuǎn)賬等功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-07-07
  • React中useState原理的代碼簡(jiǎn)單實(shí)現(xiàn)

    React中useState原理的代碼簡(jiǎn)單實(shí)現(xiàn)

    要實(shí)現(xiàn)useState的背后原理,則需要深入了解狀態(tài)是如何在函數(shù)組件的渲染周期中保持和更新的,本文將通過(guò)一段代碼簡(jiǎn)單闡述useState鉤子函數(shù)的實(shí)現(xiàn)思路,希望對(duì)大家有所幫助
    2023-12-12
  • React組件傳參方式你了解嗎

    React組件傳參方式你了解嗎

    眾所周知?,在業(yè)務(wù)開發(fā)中,無(wú)論用的什么框架,首先要熟悉項(xiàng)目搭建,路由配置和組件通信,所以我們今天要探究的就是React中組件通信的幾種方式,快跟隨小編一起學(xué)習(xí)起來(lái)吧
    2024-03-03
  • React之使用useState異步刷新的問(wèn)題

    React之使用useState異步刷新的問(wèn)題

    這篇文章主要介紹了React之使用useState異步刷新的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • react?component?function組件使用詳解

    react?component?function組件使用詳解

    這篇文章主要為大家介紹了react?component?function組件的使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 深入淺析React中diff算法

    深入淺析React中diff算法

    React 最為核心的就是 Virtual DOM 和 Diff 算法,diff算法的基礎(chǔ)是Virtual DOM,接下來(lái)通過(guò)本文給大家介紹React中diff算法的相關(guān)知識(shí),對(duì)React中diff算法感興趣的朋友跟隨小編一起學(xué)習(xí)下吧
    2021-05-05
  • React網(wǎng)絡(luò)請(qǐng)求發(fā)起方法詳細(xì)介紹

    React網(wǎng)絡(luò)請(qǐng)求發(fā)起方法詳細(xì)介紹

    在編程開發(fā)中,網(wǎng)絡(luò)數(shù)據(jù)請(qǐng)求是必不可少的,這篇文章主要介紹了React網(wǎng)絡(luò)請(qǐng)求發(fā)起方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-09-09
  • React性能debug場(chǎng)景解決記錄

    React性能debug場(chǎng)景解決記錄

    這篇文章主要為大家介紹了React性能debug場(chǎng)景解決記錄,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05

最新評(píng)論

隆子县| 太保市| 普安县| 河南省| 甘孜| 马边| 尼勒克县| 涟水县| 崇左市| 武山县| 博白县| 延安市| 英吉沙县| 昭苏县| 马龙县| 永宁县| 普洱| 三台县| 邛崃市| 丹棱县| 界首市| 鹰潭市| 巴林左旗| 青浦区| 玉龙| 尉氏县| 辽阳市| 旬邑县| 柳江县| 江源县| 同德县| 平武县| 沙河市| 罗山县| 新民市| 修文县| 花莲市| 梅州市| 精河县| 黄浦区| 许昌县|