浅谈React前后端同构防止重复渲染


Posted in Javascript onJanuary 05, 2018

什么叫前后端同构?

为了解决某些问题(比如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 值写在根元素的属性上:

浅谈React前后端同构防止重复渲染

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

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

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

浅谈React前后端同构防止重复渲染

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

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

Javascript 相关文章推荐
Extjs学习笔记之五 一个小细节renderTo和applyTo的区别
Jan 07 Javascript
js 居中漂浮广告
Mar 21 Javascript
基于JQuery的Pager分页器实现代码
Jul 17 Javascript
jquery创建一个新的节点对象(自定义结构/内容)的好方法
Jan 21 Javascript
jquery uploadify 在FF下无效的解决办法
Sep 26 Javascript
angularJS结合canvas画图例子
Feb 09 Javascript
jQuery图片加载显示loading效果
Nov 04 Javascript
node.js实现的装饰者模式示例
Sep 06 Javascript
微信小程序开发背景图显示功能
Aug 08 Javascript
vuejs实现ready函数加载完之后执行某个函数的方法
Aug 31 Javascript
vue与bootstrap实现简单用户信息添加删除功能
Feb 15 Javascript
原生JS forEach()和map()遍历的区别、兼容写法及jQuery $.each、$.map遍历操作
Feb 27 jQuery
使用vue实现grid-layout功能实例代码
Jan 05 #Javascript
详解为Bootstrap Modal添加拖拽的方法
Jan 05 #Javascript
JS交互点击WKWebView中的图片实现预览效果
Jan 05 #Javascript
Vue组件的使用教程详解
Jan 05 #Javascript
基于three.js编写的一个项目类示例代码
Jan 05 #Javascript
js中this对象用法分析
Jan 05 #Javascript
Node中使用ES6语法的基础教程
Jan 05 #Javascript
You might like
德劲1107的电路分析与打磨
2021/03/02 无线电
PHP如何抛出异常处理错误
2011/03/02 PHP
php strnatcmp()函数的用法总结
2013/11/27 PHP
WordPress开发中的get_post_custom()函数使用解析
2016/01/04 PHP
CodeIgniter扩展核心类实例详解
2016/01/20 PHP
Win7环境下Apache连接MySQL提示连接已重置的解决办法
2017/05/09 PHP
让焦点自动跳转
2006/07/01 Javascript
jquery nth-child()选择器的简单应用
2010/07/10 Javascript
javascript复制粘贴与clipboardData的使用
2014/10/16 Javascript
JS实现从网页顶部掉下弹出层效果的方法
2015/08/06 Javascript
jQuery实现图片文字淡入淡出效果
2015/12/21 Javascript
JavaScript实现iframe自动高度调整和不同主域名跨域
2016/02/27 Javascript
jQuery使用eraser.js插件实现擦除、刮刮卡效果的方法【附eraser.js下载】
2017/04/28 jQuery
Angularjs实现数组随机排序的方法
2018/10/02 Javascript
js取0-9随机取4个数不重复的数字代码实例
2019/03/27 Javascript
[04:11]2014DOTA2国际邀请赛 CIS遗憾出局梦想不灭
2014/07/09 DOTA
[05:29]2014DOTA2国际邀请赛 赛后专访:LGDNewbee顺利过关
2014/07/13 DOTA
Python中使用摄像头实现简单的延时摄影技术
2015/03/27 Python
python实现爬虫统计学校BBS男女比例之多线程爬虫(二)
2015/12/31 Python
详解Python操作RabbitMQ服务器消息队列的远程结果返回
2016/06/30 Python
Python如何通过subprocess调用adb命令详解
2017/08/27 Python
浅谈numpy库的常用基本操作方法
2018/01/09 Python
Python 3 判断2个字典相同
2019/08/06 Python
Python操作qml对象过程详解
2019/09/26 Python
python语言的优势是什么
2020/06/17 Python
在tensorflow以及keras安装目录查询操作(windows下)
2020/06/19 Python
CSS3实现复选框动画特效示例代码
2016/09/27 HTML / CSS
深入研究HTML5实现图片压缩上传功能
2016/03/25 HTML / CSS
Michael Kors美国官网:美式奢侈生活风格的代表
2016/11/25 全球购物
全球地下的服装和态度:Slam Jam
2018/02/04 全球购物
学校司机岗位职责
2013/11/14 职场文书
学生会主席就职演讲稿
2014/01/14 职场文书
银行员工辞职信范文
2014/01/20 职场文书
2014年学习全国道德模范事迹思想汇报
2014/09/15 职场文书
2019年员工旷工保证书!
2019/06/28 职场文书
redis 解决库存并发问题实现数量控制
2022/04/08 Redis