React SSR 的实现

这是我参与更文挑战的第8天,活动详情查看:更文挑战

image.png

再看react ssr 之前,我们先来看一个使用react ssr 实现的应用,感受一下它飞一般的渲染速度 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](ReactDOMServer.renderToString();
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

npm i react-helmet
复制代码

Yarn

yarn add react-helmet
复制代码

??‍♀️?简单示例

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>
    );
  }
};
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享