首页 > 其他分享 >React请求机制优化思路

React请求机制优化思路

时间:2023-08-18 09:48:00浏览次数:46  
标签:请求 渲染 js React 组件 思路 data 加载

说起数据加载的机制,有一个绕不开的话题就是前端性能,很多电商门户的首页其实都会做一些垂直的定制优化,比如让请求在页面最早加载,或者在前一个页面就进行预加载等等。随着react18的发布,请求机制这一块也是被不断谈起,并且在后续其实也给出了明确的方向。

假如我们页面中有三个组件C1、C2、C3依次嵌套,每个组件中有对应的请求F1、F2、F3,通常大多数人会使用useeffect和state变量来实现数据流的获取,这样就意味着必须在组件加载时才能发起请求,所有数据获取都发生在组件的生命周期中,如下图所示,我们可以将这种获取数据的方式称作瀑布流渲染,但是这种方式有一个问题是,在这种方法中,组件之间的数据获取是按顺序进行的,这实际上意味着它们彼此阻塞,如果组件的层级嵌套很深的话,就会导致页面的加载时间特别长。

render then fetch.png

为了阻止组件间数据获取的这种顺序阻塞,另一种方法就是在组件加载前可以使用Promise.all获取所有的请求数据,这样在组件加载时就已经获取到所有的数据了。这种方式解决了组件加载顺序阻塞彼此数据流获取的问题,但是也产生了一个新的问题,在请求完成之前页面都会是空白的。

先请求再渲染.png

基于第二种先请求后渲染的方式,还可以使用Suspense将请求和渲染并行化,Suspense 可以使得组件可以“等待”某些操作结束后,再进行渲染。而这种方式如果要用到实际项目中,还需要考虑C1、C2、C3对应的请求写在哪里,如果写在组件中,那么加载还是慢的。如果拆分出来,就需要考虑文件拆分、code splitting等工程化问题。

边请求边渲染.png

在认真的分析了以上三种方式以后,发现各有优劣,同时基于上述方案,我也提供一个请求优化的思路,首先将请求的JS单独拆分出来打一个文件request.js,在html头部引入request.js并使用async属性让脚本并行执行(如下代码所示),这样既可以保证我们的请求在最开始就能发出,也能不阻塞后续React代码打包的js文件的执行,相当请求和渲染的代码在并行执行。

// html头部引入request.js
<script async src="/js/request.js"></script>

在发送完请求之后,需要将返回的数据注入到React组件中,这部分怎么注入呢?简单的代码示例如下:

// request.js 中请求部分 evt是发布订阅模式的一个实例
window.InitData = {
    data: null,
    on: (msg, fn) => evt.on(msg, e => fn(e)),
    emit: (msg, data) => evt.emit(msg, data),
};

fetch().then(rs => {
    InitData.data = rs;
    InitData.emit("init_data", rs);
    return rs;
});

// index.js react代码逻辑

…….

useEffect(() => {
	if (InitData.data !== null) {
	    // 这里已经获取到了请求的返回值
		doSomething();
	} else {
		InitData.on("init_data", (data) => {			
		    // 利用发布订阅模式获取到数据
			doSomething();
		});
	}
}, []);

…….

总体思路就是在html中最先加载单独打包出来的请求文件并加入async属性使脚本并行执行,将返回的数据挂载到window下或者利用发布订阅模式将数据注入到react组件中。这样其实类似于边请求边渲染的模式,利用提前请求来减少加载的时间。后续也是希望能用工程化的方式去解决数据的请求机制。

未来的话在开发时肯定是更倾向于边请求边渲染的这种模式,在React的官网中也有说到未来计划让Suspense 处理更多的场景,包括获取数据等等,在新发布的React18中Suspense也是支持了服务端渲染,包括近期开源的remix也都在优化请求机制能够让应用更快的加载。也欢迎有兴趣的小伙伴一起来讨论和实践。

作者:京东零售 梁峰峰

来源:京东云开发者社区

标签:请求,渲染,js,React,组件,思路,data,加载
From: https://www.cnblogs.com/Jcloud/p/17639566.html

相关文章

  • 一次完整的HTTP请求所经历的7个步骤
    一次完整的HTTP请求所经历的7个步骤HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤:1.建立TCP连接在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建Internet,即著名的TCP/IP......
  • 浅谈加密容器取证思路---以EnFSMP为例
    软件介绍EnFSMP这个工具可以帮助生成一个加密容器,并挂载磁盘。相比于VC、TC,它的优势是不需要指定虚拟磁盘的大小。相反的,它要求的是一个文件夹,在文件夹中生成一个xml配置文件,虚拟磁盘中的文件会以加密后的形式保存在这个文件夹中。虚拟磁盘挂载后,在此电脑的显示中,总容量和可......
  • React面试1
    1.什么是虚拟DOM?虚拟DOM是真实DOM在内存中的表示,ul的表示形式保存在内存中,并且与实际的DOM同步,这是一个发生在渲染函数被调用和元素在屏幕上显示的步骤,整个过程被称为调和2.类组件和函数组件之间的区别是什么?类组件可以使用其他特性,如状态和生命周期钩子,并且他有this函数组件只......
  • Asp.net区分请求来自PC端还是APP端
    区别请求来自于APP还是PC端,主要是通过客户端传递的User-Agent来做判断的。User-Agent来自于请求头Header,如下图两种方式:来自于PC请求来自于APP请求代码获取User-Agent的值......
  • Python实现自定义请求头消息headers
    使用python爬虫爬取数据的时候,经常会遇到一些网站的反爬虫措施,一般就是针对于headers中的User-Agent,如果没有对headers进行设置,User-Agent会声明自己是python脚本,而如果网站有反爬虫的想法的话,必然会拒绝这样的连接。而修改headers可以将自己的爬虫脚本伪装成浏览器的正常访问,来......
  • [React Typescript] Discriminated Tuples in Custom Hooks
    import{useEffect,useState}from"react";exporttypeResult<T>=|["loading",undefined?]|["error",Error]|["success",T];exportconstuseData=<T,>(url:string):Result<T>=>......
  • 通过iptables将http请求从A服务器转发到B服务器
    1、准备服务器、终端使用docker的容器来模拟所需的服务器、终端。dockerfile如下:FROMcentos:centos7asiptables-testRUNyuminstall-yiptables-services&&yuminstall-ytcpdumpdocker-compose.yml如下:version:"2.7"services:work0:build:.host......
  • 一文了解 history 和 react-router 的实现原理
    我们是袋鼠云数栈UED团队,致力于打造优秀的一站式数据中台产品。我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值。本文作者:霜序前言在前一篇文章中,我们详细的说了[email protected]升级到@6.x需要注意的问题以及变更的使用方式。react-router版本更新非......
  • flask请求响应
    1请求所有的web请求:都有请求对象和响应对象(java,go,python)每个web框架都会有一个请求框架都会有一个响应框架django:request(每个请求都有一个request)flask:request全局的但也是每个请求一个request新手三件套eg:fromflaskimportFlask,render_template,requestapp......
  • flask 处理大量请求
    Flask,一个用Python编写的轻量级Web应用框架,由于其简洁、易用、灵活,以及强大的扩展性,被广大开发者所喜爱。在实际应用中,我们经常会遇到需要处理大量请求的场景,比如高并发的Web服务器、API接口等。本文将介绍如何使用Flask来处理大量请求。使用多线程或多进程为了提高程序的并发性......