领先的互联网解决方案提供商!

深圳 : 0755-2101 0201 广州 : 020-8092 8113 东莞 : 0769-3326 0066 <<<全国分公司
  • 网站建设
  • SEO推广
  • 客户案例
  • 联系我们
  • 扫描添加微信

    30秒获取报价:

    提交您的电话,免费赠送一年维护及关键词排名

  • 联系人*
  • 手机号*
  • 为什么服务端渲染首屏渲染快?(对比客户端首屏渲染)

    您现在的位置:首页 > 新闻中心 > 网站开发
    作者:http://www.xkwl.net网站建设SEO 发布于:2019-4-16 10:59:29 点击量:

    文章概要:

    【redux】详解react/redux的服务端渲染:页面性能与SEO目录亟待解决的疑问为什么服务端渲染首屏渲染快?(对比客户端首屏渲染)为什么服务端渲染有利于SEO?(对比客户端渲染)服务端渲染的具


    详细内容:

    【redux】详解react/redux的服务端渲染:页面性能与SEO

    目录

    • 亟待解决的疑问

      • 为什么服务端渲染首屏渲染快?(对比客户端首屏渲染)

      • 为什么服务端渲染有利于SEO?(对比客户端渲染)

    • 服务端渲染的具体的代码

      • 如何理解两个渲染过程?(ReactDOMServer.renderToString和 reactDOM.render的联系)

      • 为什么要把state(redux)从服务端传到客户端?

    • 解决服务端渲染代码中的“痛点”

      • 在node环境运行ES6语法和JSX语法——babel-core/register的使用

      • 使发送到客户端的页面能访问打包后的bundle.js—— webpack.output.publicPath的使用 

    • 参考资料:文章标题,作者和链接(按先后顺序)

     

    正文

        回到顶部

    亟待解决的疑问

    为什么服务端渲染首屏渲染快?(对比客户端首屏渲染)

      react客户端渲染的一大痛点就是首屏渲染速度慢问题,因为react是一个单页面应用,大多数的资源需要在首次渲染前就加载好,这较大程度地拖慢了首屏渲染速度。有一些方式能够较好地解决这个问题:   1.webpack的按需加载(代码分割)http://www.css88.com/doc/webpack2/guides/code-splitting/ (这与本篇文章没有太大关系,所以我只丢链接) 2.我们这篇文章提到的react/redux的服务端渲染   客户端渲染,服务端渲染具体的渲染过程的比较:

     

    无论是客户端渲染,服务端渲染,它们都包含三个主体过程: a:下载JS/CSS代码 b:请求数据 c:渲染页面 客户端渲染:a -> b ->c (a,b,c都在客户端进行) 服务端渲染:b -> c ->a (b,c在服务端进行,最后的a在客户端进行)   服务端渲染改变了a,b,c三个过程的执行顺序和执行方   为什么服务端渲染首屏渲染快   1.相比于客户端首屏渲染,服务端首屏渲染不需要在客户端下载JS/CSS代码请注意我说的是“首屏”),客户端接受服务端内容的时候,接受到的已经是完整的可视页面 2.服务端在内网请求数据(拉取数据),数据响应速度是很快的,而对于客户端渲染,外网http请求开销大,且受到具体的网络环境的限制   两个注意要点:“首屏”“可视”   上面我在服务端首屏渲染中,强调了两个词:“首屏”“可视” 1.服务端只做首屏的渲染,后续的渲染过程都移交客户端处理,这是为了减少服务器的负担 (这个首屏渲染不需要在客户端下载JS代码) 2.服务端渲染的是“可视”页面,没错,就是字面意思,这个页面就“只是用来看的”,没有具体的交互功能!!,因为我们的JS代码还没下载好呀,而当具体的JS代码在客户端下载好并执行后,这个页面才具有了完整的交互功能   更详细的资料:Node直出理论与实践总结(详细:https://github.com/joeyguo/blog/issues/8)   上文中描述的客户端渲染和服务端渲染,实际上对应了两种Web构建模式:前后分离模式和直出模式   模式一:前后分离模式(对应客户端渲染)

     

    模式二:直出模式(对应服务端渲染)

     

          最后对用服务端做react的首屏渲染做个比喻:在一场接力赛跑里,第一棒(首屏渲染)是尤为重要的,所以教练让一位健壮敏捷的小伙(服务端)来接,而当这位小伙把棒交给下一位选手后(客户端),他的任务(首屏渲染)也就结束了,而所有剩下的工作都交给这下一位伙伴去做了。   (体育差,可能比喻得不太好,见谅~~)  

    为什么服务端渲染有利于SEO?(对比客户端渲染)

      原因很简单,因为客户端渲染全部依赖于虚拟DOM,而搜索引擎爬不到虚拟DOM主要是国内搜索引擎   为了直观地表述这一点,让我们看服务端渲染/客户端渲染下demo的源代码吧!这是我下面将要展示的demo的截图:

     

    这是客户端渲染时候的源代码:

     

    没错,在根div节点下一点HTML都看不到!这会让国内的搜索引擎非常苦恼,因为搜不到 但是当使用服务端做首屏渲染的时候它的源代码就变成了这样:

     

    这样搜索引擎就能搜到啦!(具体代码下面介绍)   是不是搜索引擎都爬不到虚拟DOM呢?NO!!   国外谷歌可以,雅虎可以,BING可以,Duck Duck Go可以 国内百度不可以。。。   具体看这篇文章:SEO vs. React: Web Crawlers are Smarter Than You Think (https://medium.freecodecamp.org/seo-vs-react-is-it-neccessary-to-render-react-pages-in-the-backend-74ce5015c0c9) 放一下文章中爬虚拟DOM的截图: 这是BING: 这是雅虎:    这是百度         综上,在国内做react产品,服务端首屏渲染还是很重要滴~~   回到顶部

    服务端渲染的具体的代码

      我们的src目录由三部分组成:common,client和server,利用express框架开启服务器   展开后:   它们间的关系如下:

     

    【注意】client和server部分的代码是本文着重要讲解的部分,common的部分就一笔带过了   好,先放我们的代码:   common部分:   action/index.js :   复制代码

    export const increment = () => {   return { type:'INCREMENT' } }   export const decrement = () => {   return { type:'DECREMENT' } }

    复制代码

     

    Reducer/index.js :    复制代码

    import { combineReducers } from 'redux'   const initState = { number:0 } const counterReducer = (state = initState, action) => { const { number } = state switch (action.type) {    case 'INCREMENT':      return { number:number + 1}    case 'DECREMENT':      return { number:number - 1}    default:      return state    } }   export default combineReducers({ counterReducer })

    复制代码

     

    store/index.js :    复制代码

    import { createStore } from 'redux' import reducer from '../reducer'   export default (preloadedState={}) => {   const store = createStore(     reducer,     preloadedState    )     return store }

    复制代码

     

    containner/index.js :    复制代码

    import React from 'react' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' import ComponentApp from '../component' import * as NumberActions from '../action'   const mapStateToProps = state => {    return { number:state.counterReducer.number } }   const mapDispatchToProps = dispatch => {    return bindActionCreators(NumberActions,dispatch) } export default connect(mapStateToProps, mapDispatchToProps)(ComponentApp)

    复制代码

     

    component/index.js :    复制代码

    import React from 'react'   class ComponentApp extends React.Component{   render () {     const { number, increment, decrement } = this.props     return (       
             

    {number}

             增1         减1       
            )        }  }    export default ComponentApp

    复制代码

     

    server部分:   server/server.js :    复制代码

    import React from 'react''path''react-dom/server''react-redux''../common/store''../common/container'     express = require("express" webpackDevMiddleware = require("webpack-dev-middleware" webpack = require("webpack" webpackConfig = require('../../webpack.config.js' app = compiler =  //链接 https://webpack.js.org/guides/development/#webpack-dev-middleware = (html, preloadState) => `                                                                                    React App                                         ${html}
                                                           ` = (req, res) => const store = const html = ReactDOMServer.renderToString(                                     const preloadState =   app.listen(3000, (error) =>

    复制代码

     

      server/index.js :  

    // 确保在node环境下能编译es6(es2015)和JSX(react)的语法 require('babel-core/register')({   presets: ['es2015', 'react'] }) require('./server')

     

     

    client部分:    复制代码

    import React from 'react' import ReactDOM from 'react-dom' import { Provider } from 'react-redux' import createStore from '../common/store' import App from '../common/container'   // 取得服务端发送过来的初始化state const initialState = window.__INITIAL_STATE__ // 初始化store const store = createStore(initialState) // reactDOM渲染 ReactDOM.render(           ,   document.getElementById('root') )

    复制代码

     

      【注意】: 1.对express框架不太熟悉的同学可看一下express的文档http://www.expressjs.com.cn/4x/api.html 2.我上面的例子和redux官方文档的例子大致相同,更详细的介绍请看这里:http://redux.js.org/docs/recipes/ServerRendering.html   demo如下,点击按钮让数字加一或减一 【注意】采用客户端渲染和服务端渲染demo无大差异,区别在于首屏渲染的速度(服务端渲染要快)   React/redux服务端渲染的整体思路:

     

    【注意】最后客户端渲染的时候,因为服务端已经做了首屏渲染,所以这里不再重复渲染页面,而只挂载监听器,具体请看下面:  

    如何理解两个渲染过程?(ReactDOMServer.renderToString和 reactDOM.render的联系)

    一开始让我感到疑惑的就是这两个过程,因为单从代码上看似乎我们做了两次重复的渲染,但实际上却并不是这样。   renderToString会将虚拟DOM转化成一段带有“标记”(markup)的HTML字符串,“标记”包括 id和校验和两部分,见下图:   这段HTML字符串发送到客户端后,在调用ReactDOM.render()时候,将根据校验和(data-react-checksum)判断是否需要重新render:   1.校验和相同,只挂载事件监听器,不重新render 2.校验和不同,重新render   这告诉我们:当服务端/客户端共用APP的虚拟DOM的前提下,是不会有冗余的重渲染的   react文档原文: Render  a React element to its initial HTML. This should only be used on the  server. React will return an HTML string. You can use this method to  generate HTML on the server and send the markup down on the initial  request for faster page loads and to allow search engines to crawl your  pages for SEO purposes.   If  you call ReactDOM.render() on a node that already has this  server-rendered markup, React will preserve it and only attach event  handlers, allowing you to have a very performant first-load experience.  

    为什么要把state(redux)从服务端传到客户端?

    保证前后端数据的一致性   回到顶部

    解决服务端渲染代码中的“痛点”

    在node环境运行ES6语法和JSX语法——babel-core/register的使用

    在做服务端渲染的时候,让我蛋疼的莫过于在server.js中,babel-loader插件和.babelrc文件失效了   我原本配置了.babelrc文件和wepack的babel-loader插件,可它们是针对浏览器环境的,在node环境下失效了,换而言之,我遭遇了无法在我的server.js中使用ES6语法和JSX语法的问题。   服务端ES6语法编译失败(注:这是在配好了.babelrc文件和wepack的babel-loader插件前提下发生的)

     

    服务端JSX语法(react)编译失败

     

    所以我在server.js中加了这一段代码:  

    require('babel-core/register')({    presets: ['es2015', 'react'] })

      然后,编译成功!

     

    【注意】redux官方文档里还有其他的解决方法,原理类似,想了解更多请看redux官方文档http://redux.js.org/docs/recipes/ServerRendering.html  

    使发送到客户端的页面能访问打包后的bundle.js—— webpack.output.publicPath的使用 

    webpackDevMiddleware中的publicPath参数要和webpack.output.publicPath中的参数保持一致   例如: 这是我在webpack.config.js中的output参数:(关键在于publicPath)  

    output:{   filename:'bundle.js',   path:path.join(__dirname,'dist'),   publicPath: '/static' }

     

     

    这是我在server.js中的webpackDevMiddleware中的publicPath参数相关代码:  

    var webpackConfig = require('../../webpack.config.js'); // 省略其他内容 app.use(webpackDevMiddleware(compiler, { publicPath:webpackConfig.output.publicPath // Same as `output.publicPath` in most cases. }));

        然后我们在输出的HTML页面中就可以通过指定的'/static目录去访问被webpack打包后的bundle.js文件了

     

     


    上一篇: 关于数据库字段的值大小写不敏感的问题
    下一篇: 【免费网站诊断】本地编辑任务采集数据功能的使用 相关文章:
    2019-04-17 【万词霸屏】-中国万词霸屏网络科技有限公司
    2019-04-17 万词霸屏软件总部公司-
    2019-04-17 【千城千站】seo优化系统源码有jsp的吗?免费吗
    2019-04-16 天蝎做网站建网站信宜网,石狮seo,宝山网站建设,南安百度推广,伊春网站建设,延安百度推广,沧州百度代理,
    2019-04-16 【六安做网站】SEO全揭秘,这里独一份,适合各阶段人群
    2019-04-16 【楼恒伟】SEO优化需要积累那些资源?
    2019-04-16 【梧州网站优化】如何让seo优化的“伪原创”出神入化!
    2019-04-16 【诸城做网站】从0开始,SEO优化算法的点点滴滴
    2019-04-16 【下拉关键词负面】 这几类人适合学网站优化做seo工作
    2019-04-16 【itme图片收录网】做SEO优化应该如何分析竞争对手的网站?
    2019-04-16 【南安seo】网站如何将seo结合营销做推广?
    2019-04-16 【医院网站优化】火车采集器中文分词效果测试
    2019-04-16 【莱芜seo】火车采集器中英文翻译测试
    2019-04-16 【免费网站设计】外部编程插件管理
    2019-04-16 【郴州seo】火车采集器工具箱
    2019-04-16 【岳阳seo】数据库发布配置管理
    2019-04-16 【肇庆seo】数据库发布模块编辑器特性及窗体预览
    2019-04-16 【怎样优化网站】Web在线发布配置管理特性及窗体预览
    2019-04-16 【河北网站seo】Web在线发布模块编辑器特性及窗体预览
    2019-04-16 【咸阳seo】获取查看网页源代码,HTTP模拟提交工具特性及窗体预览
    相关分类:
  • 公司新闻
  • 常见问题
  • 行业新闻
  • 网站推广
  • 网站推广
  • 网站建设
  • 推广常识
  • IT教程
  • SEO优化
  • 网站开发
  • 客户案例
  • 解决方案
  • CMS
  • 其他城市分类:

    天河seo网站推广公司

    龙华做建网站百度推广优化公司

    宝安网站建设-宝安网站推广SEO优化公司-宝安做建网站公司

    南山网站建设-南山网站推广百度优化公司-南山做建网站的公司

    【钟祥地区】钟祥网站建设-钟祥SEO网站推广-钟祥做建网站网络公司

    龙岗SEO-龙岗网站推广公司-龙岗关键词seo优化排名公司

    广州白云花都网站建设SEO优化推广

    万词霸屏-万词霸屏招商代理加盟

    北京seo-北京网站推广优化公司

    上海网站推广优化seo公司-上海关键词百度排名公司

    天津seo-天津百度关键词优化排名-天津网站推广公司

    重庆网站推广优化公司-重庆seo优化排名

    合肥seo-安徽合肥芜湖蚌埠阜阳淮南网站推广seo公司

    福州SEO-厦门网站推广-泉州百度优化公司

    莆田seo-漳州网站推广公司-宁德三明南平龙岩seo优化

    佛山seo-中山网站推广-珠海网络推广公司-佛山网站优化

    惠州江门汕头湛江seo网站推广优化公司

    广东肇庆茂名揭阳梅州清远网站seo推广公司-赠送企业网站!

    阳江韶关河源seo公司-云浮汕尾潮州网站推广优化公司

    台山阳春顺德网站推广公司-惠东博罗海丰开平陆丰seo优化公司

    南宁seo-南宁网站推广公司

    柳州桂林玉林梧州seo公司-专业网站推广优化

    贵州seo-贵阳网站推广-西部seo优化公司

    甘肃网站推广公司- 兰州seo优化

    海南seo-海口网站推广-三亚seo公司

    黑龙江网站推广公司-哈尔滨seo

    河南网站seo公司优化推广服务地区:许昌平顶山安阳焦作商丘开封濮阳周口信阳驻马店漯河!

    宁夏银川SEO-吴忠石嘴山中卫固原网站推广优化公司!

    内蒙古 呼和浩特包头赤峰鄂尔多斯-专业seo优化网站推广公司!

    青海seo-西宁网站推广优化公司

    青岛网络推广-青岛seo-青岛网站优化服务企业!

    烟台网站推广优化-潍坊seo公司-临沂淄博济宁seo-待客户如家人!

    山东泰安聊城威海枣庄德州seo公司

    齐鲁网站seo推广优化服务城市:日照东营菏泽滨州莱芜章丘垦利诸城寿光龙口

    山西seo-太原SEO-太原网站推广公司

    临汾大同seo-运城晋中seo公司-长治网络推广公司

    西安seo-西安网络推广-西安seo优化公司

    渭南汉中SEO-榆林延安安康SEO优化公司

    四川地区网站seo优化推广排名城市:宜宾自贡乐山泸州达州内江遂宁攀枝花眉山广安

    新疆SEO-乌鲁木齐seo-新疆网站推广优化公司

    曲靖大理网络推广-红河玉溪seo公司-丽江文山网站优化

    杭州seo-杭州网络推广公司-杭州百度优化-杭州网站关键词优化排名

    宁波seo-宁波seo优化公司

    温州seo-温州网站推广-温州百度优化公司

    提交您的电话,免费赠送一年维护及关键词排名

  • 联系人*
  • 手机号*
    1. 首页
    2. 网站建设
    3. 网站推广
    4. 软件开发
    5. 案例展示
    6. 关于我们
    7. 联系我们

      扫码添加微信咨询

    Copyright 2008-2018 深圳市信科网络科技有限公司 Shenzhen Sinco Network Co., Ltd 严禁抄袭模仿本站 违者依法追究责任! 粤ICP备14083186号-3

  • 深圳公司
    电话 : 0755-2101 0201
    手机 : 136 3165 7619
    地址 : 深圳市龙华新区东环一路旭日大厦ll08室
  • 广州分公司
    电话 : 020-8092 8113
    手机 : 135 3988 3715
    地址 : 广州市海珠区宝岗大道268号中新大厦1912
  • 东莞分公司
    电话 : 0769-3331 9353
    手机 : 137 1719 8162
    地址 : 东莞市南城区鸿福路83号曼哈顿广场2409
  • 武汉分公司
    电话 : 027-8355 8661
    手机 : 182 4491 9118
    地址 : 武汉市东西湖区金银湖路18号财富大厦30E
  • 上海分公司
    电话 : 021-3113 7661
    手机 : 132 6719 9217
    地址 : 上海市闸北区江场西路299弄中铁广场堡尼大厦2131
  • 拨打电话
  • 添加微信
  • QQ咨询