资讯专栏INFORMATION COLUMN

干货实例:什么是React服务端渲染?

Jason_Geng / 1784人阅读

摘要:今天分享一篇公司大佬的文章,非常厉害的大神崇拜脸,讲讲服务端渲染。服务端渲染,它到底用了什么原理呢服务端渲染原理服务端渲染的方式有很多,主流的服务端语言为使用渲染。

富婆来报道,今天想问题想不出来,随手抓了一下头发,没想到啊没想到,我那浓(mei)密(sheng)茂(ji)盛(gen)的秀发又少了好几根,一定要改掉这个想不出来问题就揪头发的坏习惯。今天分享一篇公司大佬的文章,非常厉害的大神(崇拜脸),讲讲react服务端渲染。

React服务端渲染

写过React组件的同学都知道,React组件一般是基于浏览器端使用js渲染的。它所生成的Dom结构都是后期由js计算生成。如下图,我们可以看到页面源文件中id为root中的dom结构实际是空的。但实际在element元素中,已经可以看到Dom树的生成了。

客户端渲染DOM结构图

服务端渲染DOM结构图

React服务端渲染(简称SSR),也就是在服务器端直接渲染React组件,使用户在首屏便能感受到Dom树的存在,在页面html文件生成的同时,Dom结构也就存在了。用户看到的源文件即为图2。
那么为什么要使用服务端渲染呢?客户端渲染不是更能减轻服务端负担吗?我们来看下

为什么要使用服务端渲染

简单了解了React-SSR,那么我们使用服务端渲染的目的主要是为了解决如下几大难题:

1.搜索引擎优化(seo)

因React组件采用js在浏览器中渲染,实际搜索引擎爬虫爬到的数据也就是图一中的没有DOM结构的数据。,及其不友好,如图1。

2.可以解决首屏白屏问题

Js渲染的组件需要消耗性能,故在性能较差的终端中,浏览器端渲染组件所消耗的时间就会比较长。在浏览器执行js渲染组件时,对用户而言,就是所谓的白屏。

开启服务端渲染前

开启服务端渲染后

开启前后script计算时间对比


如果你的项目存在上面的问题,而又不想抛弃React组件,可以尝试使用React服务端渲染。
服务端渲染,它到底用了什么原理呢?

服务端渲染原理

服务端渲染的方式有很多,主流的服务端语言为使用nodejs渲染。下图为简单原理图:

服务端渲染简单流程图

简单概括就是这三步骤:
1.客户端发起请求
2.Nodejs服务器分析页面数据结构并渲染React组件
3.客户端展示html

实例解说

下面我们来看下具体实例,实例是基于express的React服务端组件渲染实例。Express提供页面以及中间层的API(点击tab切换调用的接口)服务,Webpack实现服务端和客户端的React组件打包。

界面预览

总共包含一个页面、两个组件。其中组件一、二均能将首屏数据返回,同时在客户端重新执行react组件渲染。

首屏DOM结构

实例地址:(这是一个express_react_ssr脚手架)
https://github.com/webqdtalk/...

运行环境

Nodejs:6.9.0 不限于此版本
Webpack:3.5.2 不限于此版本
Package.json及相关说明

这是Package.json:

{
  "name": "react-express-ssr",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "webpack --progress && node ./bin/www"
  },
  "dependencies": {
    "axios": "^0.18.0",  //实现组件中ajax请求
    "babel-core": "^6.24.0", //打包react组件
    "babel-loader": "^6.4.1", //打包react组件
    "babel-preset-es2015": "^6.24.0",//打包react组件
    "babel-preset-react": "^6.23.0",//打包react组件
    "cookie-parser": "~1.4.3", //express依赖
    "css-loader": "^0.23.1",  //express依赖
    "debug": "~2.6.9", //express依赖
    "ejs": "~2.5.7", //express依赖
    "express": "~4.16.0", //express依赖
    "extract-text-webpack-plugin": "^2.1.0",//打包scss文件依赖
    "http-errors": "~1.6.2",//express依赖
    "morgan": "~1.9.0",//express依赖
    "node-sass": "^4.5.1", //打包scss文件依赖
    "react": "^16.8.6",//打包react组件
    "react-dom": "^16.8.6",//打包react组件,
    "sass-loader": "^6.0.3",//打包scss文件依赖
    "style-loader": "^0.13.0",//打包scss文件依赖
    "webpack": "^3.5.2" //打包react组件
  },
  "devDependencies": {
    "babel-preset-env": "^1.7.0",
    "babel-register": "^6.26.0"
  }
}
Clone项目后,直接在根目录执行npm i 安装完成后运行npm start并打开浏览器访问localhost:3000就可以访问了。

重要模块说明

页面入口文件配置
当执行npm start并访问localhost:3000后,express入口文件app.js中引入了server/index.js

App.js

服务端路由如何实现

Express提供router方法

router.get("/urlpath", function(req, res, next) {
    const html=ReactDOMServer.renderToStaticMarkup();
    res.render(‘pageejs’, { title:"服务端渲染",content: html });
});
如何实现服务端渲染

Webpack入口文件:server/index.js中引入了components中的组件,并执行ReactDOMServer.renderToStaticMarkup方法,将组件在服务端渲染为页面DOM结构字符串,再由express提供页面服务,在ejs模板中输出。图四中的两个api接口是为了点击tab时请求数据用。下图为ejs模板文件。

Server/index.js

Views/index.ejs

服务端和客户端如何打包组件?

Webpack配置如下:

Webpack.config.js

客户端渲染的入口文件为/components/app.js,也包含了服务端的入口文件,保证了服务端和客户端使用同一套组件输出,同时也保证在服务端渲染结束后,客户端组件能够继续正常运转。

Components/app.js

服务端渲染的入口文件为components/index.js,如下图中可以看到此入口文件中引用了两个额外的组件:swichtab和ssrplugin,就跟纯前端渲染的react组件基本一致!

Components/index.js


客户端打包组件后输出在public/main.css和public/index.js,在视图文件views/index.ejs中引用实现客户端渲染。

实践过程的注意点

1.express无法执行import 导致报错。

解决方案:
npm i babel-register --save
同时在bin/www中配置babel-register

require("babel-register")({
  presets: ["env"]
});

2.服务端渲染css或者scss文件时报错

解决方案:
因服务端直接运行css或者scss等文件会导致语法报错,故在实际组件中,需要对require的scss文件进行容错或者动态按需加载。

try{
    require("./index.scss")  //因服务端渲染不需要scss文件,但webpack仍会处理scss文件,打包scss会出错,此处需要作为容错处理或按需加载
}catch(e){
    console.log(e.message);
}

服务端渲染虽好,但是对项目的改造影响还是比较大的,改造需谨慎评估~

你懂的!!!

如有不对的地方,欢迎各位斧正!

欢迎关注我的公众号,大家一起交流,Web前端Talk

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/109362.html

相关文章

  • 干货分享: 如何在 React 框架中使用SpreadJS

    摘要:作者葡萄城控件最好的功能之一就是能够在不同的框架中使用它。本文将演示如何在简单的页面中使用编译器将与快速结合。这只是和的基本使用,但可以轻松扩展。自面世以来,备受华为中通中国民航飞行学院中国平安中国能建浪潮等国内知名企业客户青睐。 作者:葡萄城控件SpreadJS最好的功能之一就是能够在不同的框架中使用它。本文将演示如何在简单的Web页面中使用Babel JavaScript编译器将S...

    Lin_R 评论0 收藏0
  • 【腾讯Bugly干货分享】React 移动 web 极致优化

    摘要:数据管理及性能优化统一管理数据这一部份算是重头戏吧。重复渲染导致卡顿这套的东西在家校群页面上用得很欢乐,以至于不用怎么写都没遇到过什么性能问题。但放到移动端上,我们在列表页重构的时候就马上遇到卡顿的问题了。列表页目前的处理办法是将值换成。 本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57908... 最近一个季度...

    suosuopuo 评论0 收藏0
  • 插拔式 SPA 应用架构实现方案

    摘要:插拔式应用架构方案和传统前端架构相比有以下几个优势业务模块分布式开发,代码仓库更易管理。 showImg(https://segmentfault.com/img/remote/1460000016053325?w=2250&h=1500); 背景 随着互联网云的兴起,一种将多个不同的服务集中在一个大平台上统一对外开放的概念逐渐为人熟知,越来越多与云相关或不相关的中后台管理系统或企业级...

    Cciradih 评论0 收藏0
  • 拒绝Redux文档“毒害” 一个项目告诉你Redux最新真正哲学

    摘要:之前分享过几篇关于技术栈的原创文章解析前端架构学习复杂场景数据设计干货总结打造单页应用一个项目理解最前沿技术栈真谛一个工程实例今天进一步剖析一个实际案例移动网页版。目前面临的问题在于提高产品的各方面性能体验。 之前分享过几篇关于React技术栈的原创文章: 解析Twitter前端架构 学习复杂场景数据设计 React Conf 2017 干货总结1: React + ES next ...

    YuboonaZhang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<