React SSR 的实现

再看react ssr 之前,我们先来看一个使用react ssr 实现的应用,感受一下它飞一般的渲染速度 https://m.xin.com/ 看过之后我们再来看文章。

📚导读

关于服务端渲染(SSR)、客户端渲染(CSR)和 同构渲染,我在next.js从入门到实战这篇文章中开头有详细的介绍,还不了解这三种渲染方式的可以简单了解一下。

但只实现 SSR 没什么意义,技术上没有任何改进,否则 SPA 技术就不会出现😀。
但是单纯的 SPA 又不够完美,所以最好的方案就是这两种技术和体验的结合。但是要实现两种技术的结合,同时可以最大限度的重用代码(同构),减少开发维护成本,那就需要采用 react 或者 vue 等前端框架和node(ssr)相结合的方式来实现。

如果我们使用react ssr 来实际开发项目,我们就需要一个完整的开发框架,next.js其实就是这种框架,类似的还有nuxt.js。那这种框架的实现原理是什么呢?

📚react ssr 实现原理

在了解react ssr 我们先来看两个概念。

📒虚拟dom

react ssr其中的SSR指的是在服务端渲染组件。而组件可以在服务端渲染的根本原因就是虚拟 DOM,我们一般使用jsx来编写react组件,但其实jsx是一个语法糖,其实我们编写的组件都可以解析为一个个对象。这个对象包含

  • 🎈tag:节点标签名
  • 🎈props:DOM的属性,用一个对象存储键值对
  • 🎈children: 该节点的子节点
    我们有了这个对象,我们就可以轻松的将其转换为我们需要的格式,比如html格式,当然这个转换不需要我们来完成,这个转换react已经帮我们完成了,其本身提供内置方法支持服务端渲染;我们先来具体了解一下同构的概念;

📒同构

同构是将传统的纯服务端直出的首屏优势和SPA的站内体验优势结合起来,以取得最优解的解决方案。

就是服务端把首屏的内容直出,让用户更快的看到页面,然后后面的数据采用js来异步请求和加载。貌似不用react一样可以做到的呀,那为什么还一定要使用react或者vue这种框架来结合ssr呢?

我们知道同构就是指前后端公用一套代码,比如我们的组件可以在服务端渲染也可以在客户端渲染,但都是同一个组件。这也是react本身的优势。我们使用react来写,可以减少我们的代码量,基于react来实现更加方便,高效,因为我们可以使用react + node 来构造

📒结语

其实到这里我们也明白了什么是react ssr , react ssr 就是react 利用自身虚拟dom 的优势,然后通过同构渲染来实现的。react ssr 的核心就是同构,没有同构的 ssr 是没有意义的。

📚react ssr 是如何实现的

我们了解了什么是react ssr ,那么react ssr 是怎么实现的呢,是怎么实现的服务端渲染,html的转换?

为了实现服务端渲染,打造同构应用,react内部实现了相关的API,可以将组件转换为html,可以一起来看一下这ReactDOMServer 这个 api

📒ReactDOMServer

ReactDOMServer 类可以帮我们在服务端渲染组件 - 得到组件的 html 字符串。

该模块有两个方法renderToString 和 renderToStaticMarkup,两个方法都是将组件转换为html格式的,它们的使用方式也是相同的,不同的是renderToStaticMarkup不需要计算,所以性能能高,速度更快。

📚react ssr 如何解决seo tdk支持

对于这个问题,其实有现成的轮子可以使用。它就是react-helmet;
const helmet = Helmet.renderStatic();)。

📒简介

React Helmet是一个HTML文档head管理工具,管理对文档头的所有更改。

📒特点

  • 支持所有有效的head标签: title、 base、 meta、 link、 script、 noscript、 和style。
  • 支持body、 html 和 title 的属性
  • 支持服务端渲染
  • 嵌套组件覆盖重复的head标签更改。
  • 在同一组件中定义时,将保留重复的head标签更改。(支持如”apple-touch-icon”的标签).
  • 支持跟踪DOM更改的回调

📒安装

Npm

1
npm i react-helmet

Yarn

1
yarn add react-helmet

📒💁‍♀️🌰简单示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React from "react";
import {Helmet} from "react-helmet";

class Application extends React.Component {
render () {
return (
<div className="application">
<Helmet>
<meta charSet="utf-8" />
<title>My Title</title>
<link rel="canonical" href="http://mysite.com/example" />
</Helmet>
...
</div>
);
}
};
Kommentare

:D 一言句子获取中...