React前后端同构防止重复渲染
什么叫前后端同构?为了解决某些问题(比如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] )方法执行时,会执行以下步骤:
在上面这个过程成中,步骤2完成后即为完成 react 的首屏渲染。结合 checksum机制步骤3有可能不会执行。 当组件状态发生变更时( setState() 生命周期函数被调用)或者 父组件渲染时(父组件的 render() 方法被调用),当前组件的 render() 方法都会被执行,都有可能会导致虚拟dom变更,但是这些变更和首屏渲染没任何关系了。 React前后端同构首屏渲染了解了同构和首屏渲染,就好理解如何解决首屏不重复渲染的问题了。 首先服务端渲染完之后会有一个 checksum 值写在根元素的属性上: 这个 checksum是根据服务端生成的HTML内容哈希计算得到的。 然后在浏览器加载完所有的js文件之后,开始执行前面介绍的ReactDOM.render( element,[callback] ) 初始化渲染的三个步骤。当执行完第二步生成虚拟dom后,react 会根虚拟dom用相同的算法计算一个哈希值,如果和 checksum 一致则认为服务器已经完成渲染,不会再执行第三步。 如果 checksum 比对不一致,在 开发环境和 测试环境 会在浏览器console中输出以下警告内容: 生产环境不会输出任何警告。 同构渲染的内容就这么多,原理其实蛮简单的,无非就是保证DOM一致。但是结合代码分片、异步加载、服务端调接口异步组装数据等等功能后,如何保证服务端和浏览器端第一次渲染的dom一致还得花不少功夫。不过原理清楚了,事情总能办成。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |