当前位置: 首页 > news >正文

React中使用LazyBuilder实现页面懒加载方法二

前言:

        在一个表格中,需要展示100条数据,当每条数据里面需要承载的内容很多,需要渲染的元素也很多的时候,容易造成页面加载的速度很慢,不能给用户提供很好的体验时,懒加载是优化页面加载速度的方法之一。

策略:
        前端在接受到api返回的数据的时候,可以先根据数据总的条数进行遍历,给每一项初始化简单的dom进行渲染占位,通过IntersectionObserver对每一项元素进行监听,当初始dom出现在页面视口的时候,需要替换掉初始dom,渲染真实dom。这样可以实现:在初始dom出现在视口内时,替换掉初始dom,渲染真实dom,并取消对该dom的监听,实现只需加载一次,首次加载多少个真实dom,取决于可视区域跟初始dom的高度

React中使用LazyBuilder实现页面懒加载方法一

与方法一不同之处:

方法一:元素出现在可视区域内,即渲染真实dom,一旦消失在可视区域内,即渲染初始dom

方法二:元素只要出现在可视区域内一次,即渲染真实dom,并且取消对该dom的监听,只需加载一次

LazyBuilder.jsx
import React, { Component, createRef } from "react";
class LazyBuilder extends Component {static defaultProps = {initComponent: null,initHeight: null,controller: null,className: null,style: null,}/*** @param {Object} props* @param {JSX.Element} [props.initComponent] - 默认组件* @param {Number} [props.initHeight] - 组件高度* @param {LazyController} [props.controller] - LazyController*/constructor(props) {super(props);this._ref = createRef();this.controller = this.props.controller instanceof LazyController ? this.props.controller : new LazyController();this.state = {isLoading: true,initStyle: {width: "100%",height: props.initHeight},key: `lazy_${Math.random().toString(16).slice(2)}`,}}componentDidMount() {// 页面初始化时,对所有元素进行绑定监听this.controller.observe(this._ref.current, this.updateShowElement.bind(this));}// 组件销毁时componentWillUnmount() {const { autoDispose } = this.props;if (autoDispose && this.controller.size() === 0) {this.controller.dispose();return;}this.controller.unobserve(this._ref.current);}updateShowElement = () => {// 元素出现在视口以内this.setState({isLoading: false,initStyle: null,});}render () {const { children, initComponent } = this.props;const { isLoading, initStyle } = this.state;const className = ["lazy-builder-item", this.props.className].filter(item => typeof item === "string").join("\s");return (<div id={this.state.key} ref={this._ref} className={className} style={Object.assign({}, initStyle, this.props.style)}>{isLoading ? initComponent : children}</div>);}
}class LazyController {constructor(){// 定义map来存储所有的dom项this._map = new Map();// IntersectionObserver 对每一项元素进行监听this.observer = new IntersectionObserver((entries) => {for (const entry of entries) {// isIntersecting: true - 出现在视口    false - 隐藏(视口以外)if (entry.isIntersecting) {const updateShowElement = this._map.get(entry.target);if (typeof updateShowElement === "function") {updateShowElement()}this.unobserve(entry.target);}}});}// 观察指定DOMobserve = (target, callback) => {if (this.observer && !this.has(target)) {this._map.set(target, callback);this.observer.observe(target);}}// 取消对指定DOM的观察unobserve = (target) => {if (this.observer && this.has(target)) {this.observer.unobserve(target);this._map.delete(target);}}// 判断一个DOM是否正在被观察has = (target) => {return this._map.has(target);}// 返回正在观测中的DOM数量size = () => {return this._map.size();}// 停止对所有DOM的观测并销毁IntersectionObserver实例dispose = () => {if (this.observer == null) {throw new Error("observer未初始化");}this._map.clear();this.observer.disconnect();this.observer = null;}
}export {LazyBuilder,LazyController,
}

Cp.jsx

export default class  Cp extends Component {constructor(props){super(props)// 创建controllerthis.controller = new LazyController();this.state = {// 模拟数据dataList: new Array(100).fill().map((item, index) => index + 1)}}componentWillUnmount() {this.controller.dispose();}render(){const {dataList} = this.statereturn (<div>{Array.isArray(dataList) && dataList.length > 0? dataList.map((item, index) => {return <LazyBuilder key={index}initHeight={200} // 初始dom高度controller={this.controller} // controller><div style={{width: '100%', height: '200px'}}>{`第${item}个元素`}</div></LazyBuilder>}): null}</div>)}
}

初次加载:

滚动后:

相关文章:

React中使用LazyBuilder实现页面懒加载方法二

前言&#xff1a; 在一个表格中&#xff0c;需要展示100条数据&#xff0c;当每条数据里面需要承载的内容很多&#xff0c;需要渲染的元素也很多的时候&#xff0c;容易造成页面加载的速度很慢&#xff0c;不能给用户提供很好的体验时&#xff0c;懒加载是优化页面加载速度的方…...

安全测试:史上最全的攻防渗透信息收集方法、工具!

信息收集的意义 信息收集对于渗透测试前期来说是非常重要的。正所谓&#xff0c;知己知彼百战不殆&#xff0c;信息收集是渗透测试成功的保障&#xff0c;只有我们掌握了目标网站或目标主机足够多的信息之后&#xff0c;才能更好地进行渗透测试。 信息收集的方式可以分为两种…...

minio2023版本安装对象存储文件迁移

一、环境 minio版本&#xff1a;minio-20230320201618.0.0.x86_64.rpm 二、安装 将下载好的rpm包放在文件夹下&#xff0c;然后cd到该目录 sudo rpm -ivh minio-20230320201618.0.0.x86_64.rpm 三、启动 1、minio的位置 which minio cd /usr/local/bin 2、启动 &#xff08;可…...

###C语言程序设计-----C语言学习(7)#(调试篇)

前言&#xff1a;感谢您的关注哦&#xff0c;我会持续更新编程相关知识&#xff0c;愿您在这里有所收获。如果有任何问题&#xff0c;欢迎沟通交流&#xff01;期待与您在学习编程的道路上共同进步。 一. 程序调试 1.程序调试介绍&#xff1a; 程序调试是软件开发过程中非常重…...

腾讯云Linux(OpenCloudOS)安装tomcat9(9.0.85)

腾讯云Linux(OpenCloudOS)安装tomcat9 下载并上传 tomcat官网 https://tomcat.apache.org/download-90.cgi 下载完成后上传至自己想要放置的目录下 解压文件 输入tar -xzvf apache-tomcat-9.0.85.tar.gz解压文件&#xff0c;建议将解压后的文件重新命名为tomcat,方便后期进…...

动态添加字段和注解,形成class类,集合对象动态创建Excel列

一.需求 动态生成Excel列&#xff0c;因为Excel列是通过类对象字段注解来添加&#xff0c;在不确定Excel列数的情况下&#xff0c;就需要动态生成列&#xff0c;对应类对象字段也需要动态生成&#xff1b; 二.ByteBuddy字节码增强动态创建类 1.依赖 <dependencies><…...

Python爬虫---Scrapy框架---CrawlSpider

CrawlSpider 1. CrawlSpider继承自scrapy.Spider 2. CrawlSpider可以定义规则&#xff0c;再解析html内容的时候&#xff0c;可以根据链接规则提取出指定的链接&#xff0c;然后再向这些链接发送请求&#xff0c;所以&#xff0c;如果有需要跟进链接的需求&#xff0c;意思就是…...

关机恶搞小程序

1. system("shutdown")的介绍 当system函数的参数是"shutdown"时&#xff0c;它将会执行系统的关机命令。 具体来说&#xff0c;system("shutdown")的功能是向操作系统发送一个关机信号&#xff0c;请求关闭计算机。这将触发操作系统执行一系列…...

《HTML 简易速速上手小册》第9章:HTML5 新特性(2024 最新版)

文章目录 9.1 HTML5 新增标签和属性9.1.1 基础知识9.1.2 案例 1&#xff1a;创建一个结构化的博客页面9.1.3 案例 2&#xff1a;使用新的表单元素创建事件注册表单9.1.4 案例 3&#xff1a;创建一个具有高级搜索功能的搜索表单 9.2 HTML5 表单增强9.2.1 基础知识9.2.2 案例 1&a…...

计算机网络之NAT

NAT&#xff08;网络地址转换&#xff0c;Network Address Translation&#xff09;是一种网络技术&#xff0c;用于在一个网络与另一个网络之间重新映射IP地址。NAT最常见的应用是在家庭和小型办公室的路由器中&#xff0c;用于将私有&#xff08;内部&#xff09;IP地址转换为…...

SQL - 数据操作语句

SQL - 数据操作语句 文章目录 SQL - 数据操作语句数据操作语言-DML1 新增2 修改3 删除4 清空 数据类型1 数值类型2 字符串类型3 日期时间类型 数据操作语言-DML 概念&#xff1a; DML&#xff08;Data Manipulation Language&#xff09;, 数据操作语言。对数据表数据的增、删…...

【Python笔记-设计模式】单例模式

一、说明 单例是一种创建型设计模式&#xff0c;能够保证一个类只有一个实例&#xff0c; 并提供一个访问该实例的全局节点。 (一) 解决问题 维护共享资源&#xff08;数据库或文件&#xff09;的访问权限&#xff0c;避免多个实例覆盖同一变量&#xff0c;引发程序崩溃。 …...

Java使用io流生成pdf文件

首先生成pdf和正常请求接口一样&#xff0c;直接写~ Controller层&#xff1a; 第一个注解&#xff1a;最顶层增加 Controller 注解&#xff08;控制器&#xff09;不多讲了 直接加上。 第二个注解&#xff1a;最顶层增加 CrossOrigin 注解此注解是为了浏览器请求的时候防…...

STL-priority_queue

文档 目录 1.关于priority_queued1的定义 2.priority_queue的使用 1.关于priority_queued1的定义 1. 优先队列是一种容器适配器&#xff0c;根据严格的弱排序标准&#xff0c;它的第一个元素总是它所包含的元素中最大的。 2. 此上下文类似于堆&#xff0c;在堆中可以随时插入元…...

SpringBoot基于注解形式配置多数据源@DS

TOC() 1.引入依赖 <!-- dynamic-datasource 多数据源--><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.2</version></dependency>2.配置…...

华清远见作业第三十四天——C++(第三天)

思维导图&#xff1a; 题目&#xff1a; 设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。 代码&#…...

Shell中正则表达式

1.正则表达式介绍 1、正则表达式---通常用于判断语句中&#xff0c;用来检查某一字符串是否满足某一格式 2、正则表达式是由普通字符与元字符组成 3、普通字符包括大小写字母、数字、标点符号及一些其他符号 4、元字符是指在正则表达式中具有特殊意义的专用字符&#xff0c…...

Flutter Canvas 属性详解与实际运用

在Flutter中&#xff0c;Canvas是一个强大的绘图工具&#xff0c;允许我们以各种方式绘制图形、文字和图像。了解Canvas的属性是开发高度定制化UI的关键。在本篇博客中&#xff0c;我们将深入探讨Flutter中Canvas的一些重要属性&#xff0c;并展示它们在实际应用中的使用。 1.…...

Django配置websocket时的错误解决

基于移动群智感知的网络图谱构建系统需要手机app不断上传数据到服务器并把数据推到前端标记在百度地图上&#xff0c;由于众多手机向同一服务器发送数据&#xff0c;如果使用长轮询&#xff0c;则实时性差、延迟高且服务器的负载过大&#xff0c;而使用websocket则有更好的性能…...

(免费分享)springboot,vue在线考试系统

springboot 在线考试系统 前后端分离 一、项目简介 基于SpringBoot的在线考试系统 二、技术实现 后台框架&#xff1a;SpringBoot&#xff0c;mybatis-plus UI界面&#xff1a;Vue、ElementUI、Axios、Node.js&#xff08;前后端分离&#xff09; 数据库&#xff1a;MySQ…...

力扣HOT100(30)两两交换链表中的节点

链表的交换要注意 “链表不断链”。前驱和后继都要连着迭代法&#xff08;必学死磕&#xff01;O (n) 时间&#xff0c;O (1) 空间&#xff09;1. 为什么必须用虚拟头节点&#xff1f;因为交换后链表的头节点会变&#xff01; 比如示例 1 中&#xff0c;原来的头是 1&#xff0…...

销售怎么通过各种方法获取电话号码

第一种就是那个用爬虫电话号码&#xff0c;然后再打电话给客户。第二种是在别人的挪车电话看车挪车电话&#xff0c;然后再打电话找客户。第三就是。扫楼一顿顿的扫&#xff0c;第四就是这个那种商店&#xff0c;一个个的去问陌拜地推一个个的问店子要不要贷款&#xff0c;去问…...

美团外卖mtgsig与waimai_sign双层签名逆向解析

1. 这不是“爬虫教程”&#xff0c;而是一份反向工程现场笔记你搜到这篇内容&#xff0c;大概率正卡在某个调试窗口前&#xff1a;抓包看到mtgsig和waimai_sign两个参数像两堵墙&#xff0c;无论怎么改请求头、换UA、清缓存&#xff0c;返回永远是{"code":403,"…...

学术写作创新突破!2026全流程AI论文工具精选指南

2026 年 AI 论文写作工具已进入全流程闭环 学术合规时代&#xff0c;千笔 AI&#xff08;综合评分 99 分&#xff09;中文学术场景标杆&#xff1b;Grammarly Academic与Elicit为英文论文写作首选&#xff1b;按需求匹配度 - 数据可信度 - 成本承受力三维模型选型&#xff0c;…...

独立站内容分层:一层给 SEO,一层给 GEO

你的内容在喂两个完全不同的"阅读者" 你的博客文章&#xff0c;从来都不只有一个读者。 传统认知里&#xff0c;独立站内容的读者只有两类&#xff1a;真人访客和搜索引擎爬虫。SEO 优化的一切工作&#xff0c;本质上都是在讨好后者&#xff0c;顺带服务前者。 但…...

【数据结构与算法】数据结构基础——栈和队列

目录栈和队列1. 栈1.1 栈的概念1.2 栈的实现方式分析1.3 栈的实现1.3.1 栈的初始化与销毁1.3.2 入栈与出栈1.3.3 栈的判空与有效元素个数1.3.4 栈顶元素1.4 栈的扩展1.4.1 两栈共享空间2. 队列2.1 队列的概念2.2 队列的实现方式分析2.3 队列的实现2.3.1 队列的初始化与销毁2.3.…...

【python】ImportError: DLL load failed while importing QtWidgets: 找不到指定的程序。重新安装后搞定

文章目录前言一、PyQt6引用后报错二、使用步骤总结前言 想做个好看的界面&#xff0c;引用了PyQt6&#xff0c;却产生了新问题。 pip install pyqt6-tools&#xff0c;优先做这个动作进行修复。 一、PyQt6引用后报错 python里引用&#xff1a; from PyQt6.QtWidgets import…...

Go开发者必备:circuitbreaker API全解析与最佳实践指南 [特殊字符]

Go开发者必备&#xff1a;circuitbreaker API全解析与最佳实践指南 &#x1f680; 【免费下载链接】circuitbreaker Circuit Breakers in Go 项目地址: https://gitcode.com/gh_mirrors/circ/circuitbreaker 作为一名Go开发者&#xff0c;你是否经常遇到远程服务调用失败…...

从科研图表到商业报表:如何用Matplotlib的legend()提升你的图表专业度?

从科研图表到商业报表&#xff1a;如何用Matplotlib的legend()提升你的图表专业度&#xff1f; 在数据驱动的决策时代&#xff0c;图表不仅是科研论文中的证据载体&#xff0c;更是商业汇报中的说服工具。我曾见证一位生物统计学家将同一组临床试验数据呈现给三种不同受众&…...

Claude Code用户告别封号与Token焦虑,无缝切换至Taotoken平台

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Claude Code用户告别封号与Token焦虑&#xff0c;无缝切换至Taotoken平台 对于依赖Claude Code进行编程辅助的开发者而言&#xff…...