react前后端如何同构,防止重复渲染

author author     2022-09-17     762

关键词:

首先解释React前后端同构、React首屏渲染的概念。然后通过这2个概念解决服务端渲染完成后浏览器端重复渲染的问题。

什么叫前后端同构?

为了解决某些问题(比如SEO、提升渲染速度等)react 提供了2个方法在服务端生成一个HTML文本格式的字符串。在得到了这个HTML格式的字符串之后,通常会将其组装成一个页面直接返回给用户的浏览器。

到这里,服务端的活已经干完了,然后就是浏览器这边干活。

浏览器拿到HTML文本后,立刻进行渲染将内容呈现给用户。然后加载页面所需的 .js 文件,然后执行 JavaScript 脚本,然后开始初始化 react 组件…………

到这里问题就来了。react 初始化组件后会执行组件内所有 render () 方法,然后生成虚拟DOM的树形结构,然后在适当的时候将虚拟dom写到浏览器的真实dom中。因为 react 总是根据虚拟dom来生成真实dom,所以最后会把服务器端渲染好的HTML全部替换掉。

上面这个事情说不是问题确实也不是问题,无非就是用户看到页面然后“闪现”一下。说是问题还真是个问题,产品会拿着这毛病从用户体验的角度在各种场合和你死磕半个月。磕累了你索性把服务端渲染关了,然后运营又拿着SEO的问题准备和你开始撕逼了。

聪明如 Facebook 的工程师当然想到了这些问题,所以他们在ReactDOMServer.renderToString(element) 方法中提供了一个 checksum 机制。

关于 checksum 官网 并没有太多介绍,但是国内外的各路博客介绍了不少。我一直想找 react 开发者关于这个机制的介绍一直没找到……。

前后端同构就是保证前端和后端的dom结构一致,不会发生重复渲染。react 使用 checksum 机制进行保障。

什么叫React首屏渲染?

简单的说就是 react 在浏览器内存中第一次生成的虚拟 dom 树。切记是虚拟 dom ,而不是浏览器的dom。

了解 react 的应该知道,所有 react 组件都有一个 render() 方法(如果使用function方式编写的组件会把function里的所有代码都塞到 render() 方法中去)。当ReactDOM.render( element, container, [callback] )方法执行时,会执行以下步骤:

1. 所有组件的会先进行初始化(es6执行构造函数)。
2. 所有组件的 render () 方法会被调用一次,完成这个过程后会得到一颗虚拟的 dom 树。
3. react 会将虚拟dom转换成浏览器dom,完成后调用组件的 componentDidMount() 方法告诉你已经装载到浏览器上了。

在上面这个过程成中,步骤2完成后即为完成 react 的首屏渲染。结合 checksum 机制步骤3有可能不会执行。

当组件状态发生变更时( setState() 生命周期函数被调用)或者 父组件渲染时(父组件的 render() 方法被调用),当前组件的 render() 方法都会被执行,都有可能会导致虚拟dom变更,但是这些变更和首屏渲染没任何关系了。

React前后端同构首屏渲染

了解了同构和首屏渲染,就好理解如何解决首屏不重复渲染的问题了。
首先服务端渲染完之后会有一个 checksum 值写在根元素的属性上:
技术分享

这个 checksum 是根据服务端生成的HTML内容哈希计算得到的。

然后在浏览器加载完所有的js文件之后,开始执行前面介绍的 ReactDOM.render( element, container, [callback] ) 初始化渲染的三个步骤。当执行完第二步生成虚拟dom后,react 会根虚拟dom用相同的算法计算一个哈希值,如果和 checksum 一致则认为服务器已经完成渲染,不会再执行第三步。

如果 checksum 比对不一致,在 开发环境 和 测试环境 会在浏览器console中输出以下警告内容:
技术分享

生产环境不会输出任何警告。

同构渲染的内容就这么多,原理其实蛮简单的,无非就是保证DOM一致。但是结合代码分片、异步加载、服务端调接口异步组装数据等等功能后,如何保证服务端和浏览器端第一次渲染的dom一致还得花不少功夫。不过原理清楚了,事情总能办成。


vue服务端渲染同构渲染(代码片段)

...渲染。2014年起又兴起了同构渲染,号称是未来,集成了前后端渲染的优点,当真如此?我们先明确 查看详情

React JS 同构渲染

】ReactJS同构渲染【英文标题】:ReactJSisomorphicrender【发布时间】:2016-08-0201:49:18【问题描述】:ReactJS、原始Flux、react-router、nodeJS、socket.io一切都是最新的。如果我在浏览器中关闭javascript,则只会呈现静态代码。在服务器端渲染... 查看详情

vue.js前后端同构方案之准备篇——代码优化

作者:王鹤导语目前Vue.js的火爆不亚于当初的React,本人对写代码有洁癖,代码也是艺术。此篇是准备篇,工欲善其事,必先利其器。我们先在代码层面进行优化,对我们完成整个技术架构是起到基础作用的。此准备篇是独立的... 查看详情

React Relay 和服务器端渲染

...1211:05:19【问题描述】:我一直在开发一个使用react构建的同构应用程序,并且我已经阅读了有关使用Relay.js和GraphQL进行客户端-服务器交互的信息。我一直在想,在使用Relay.js时,特别是在使用react的服务器端渲染和同构应用程序... 查看详情

没有通量的同构 react.js

】没有通量的同构react.js【英文标题】:isomorphicreact.jswithoutflux【发布时间】:2016-08-1718:18:44【问题描述】:我是react.js的新手。我想制作同构react.js组件。我想知道是否可以在没有通量模式的情况下制作它?现在我的组件很少,... 查看详情

前后端分离及react的一些研究

...对英才网企业线前端不断的完善过程中,我们尝试进行了前后端分离,引入Node环境、以及在使用React的过程中,自行开发DOM渲染框架,解决React兼容低版本IE的问题,在这个过程中,我们有了一些经验和体会,希望本文对您有所... 查看详情

如何防止 react 重新渲染整个组件?

】如何防止react重新渲染整个组件?【英文标题】:Howtopreventreactfromre-renderingthewholecomponent?【发布时间】:2017-06-0509:44:26【问题描述】:我从here改编了以下组件定义,如下所示。但是,与示例不同,每次我在组件上移动鼠标时都... 查看详情

如何防止在 React 中使用钩子重新渲染页面?

】如何防止在React中使用钩子重新渲染页面?【英文标题】:HowcanIpreventre-renderingofthepagewithhooksinReact?【发布时间】:2019-10-1723:53:58【问题描述】:我试图为这个特定问题找到解决方案,但我可以找到它......在新的这个,我有这个... 查看详情

React 限制渲染次数以防止无限循环...重新渲染次数过多

...omanyre-renders【发布时间】:2021-12-2518:38:11【问题描述】:如何避免无限循环问题?渲染以下组件时出现错误:重新渲染过多。React限制了渲染的数量以防止无限循环。?TeamContent.js多次重新渲染,如何在加载时 查看详情

如何防止重新渲染 react-redux

】如何防止重新渲染react-redux【英文标题】:howtopreventre-renderreact-redux【发布时间】:2021-05-0320:41:09【问题描述】:在类别组件中,我从每个类别中渲染一个随机图像。我还为每个图像添加了一个onClick事件。当点击图片时,它会... 查看详情

React(性能):如何防止每次状态更改时出现不必要的渲染? [复制]

】React(性能):如何防止每次状态更改时出现不必要的渲染?[复制]【英文标题】:React(Performance):Howtopreventunwantedrenderingoneachstatechange?[duplicate]【发布时间】:2020-10-0206:49:54【问题描述】:这个问题严重影响了我的表现。在每次... 查看详情

使用 setInterval 时如何防止 React 重新渲染整个组件

】使用setInterval时如何防止React重新渲染整个组件【英文标题】:HowtopreventReactfromre-renderingthewholecomponentwhenusingsetInterval【发布时间】:2019-12-0507:52:44【问题描述】:我正在开发一个应用播放器。见下图:进度条必须显示当前时间... 查看详情

如何使用 REACT 防止组件在动画中重新渲染(更新)

】如何使用REACT防止组件在动画中重新渲染(更新)【英文标题】:Howtopreventcomponentre-render(update)insideanimationswithREACT【发布时间】:2019-10-2909:17:21【问题描述】:在过去的几天里,我一直在为React使用不同的动画库,试图找到在... 查看详情

使用react的static方法实现同构以及同构的常见问题(代码片段)

...,issue,共同进步1.我们服务端渲染数据从何而来1.1怎样写出同构的组件服务端生成HTML结构有时候并不完好。有时候不借助js是不行的。比方当我们的组件须要轮询服务器的数据接口,实现数据与服务器同步的时候就显得非常重要。... 查看详情

如何防止我的功能组件使用 React 备忘录或 React 钩子重新渲染?

】如何防止我的功能组件使用React备忘录或React钩子重新渲染?【英文标题】:HowcanIpreventmyfunctionalcomponentfromre-renderingwithReactmemoorReacthooks?【发布时间】:2019-07-2314:56:06【问题描述】:当hiddenLogo改变值时,组件被重新渲染。我希... 查看详情

React:如何防止在`map`中重新渲染子组件?

】React:如何防止在`map`中重新渲染子组件?【英文标题】:React:Howtopreventre-renderingchildcomponentsin`map`?【发布时间】:2020-06-1702:48:14【问题描述】:我试图将问题归结为一个尽可能简单的例子:我们有一个子组件列表,每个子组件... 查看详情

如何进行前后端分离

参考技术A在不使用vue,react,anglar这类的框架的情况下,前后端分离应该如何做?需求是这样:前端写html页面(非单页面应用),index.html首页about.html关于我们newslist.html新闻列表newsdetail.html新闻详情productlist.html产品列表productdetail.... 查看详情

后端渲染实践——看掘金社区是如何实践的

...前端应用。而这些优质开源框架的普及、多端业务统一、前后端分离的需求让越来越多的架构设计将大部分业务逻辑写在了前端。 但是,纯前端产品也有着它的问题。上述的几个前端框架都支持了后端渲染的功能,从而融合... 查看详情