小说网站建设方案书ppt模板,如室设计网站,php网站cms,重庆网址前言#xff1a; 在一个表格中#xff0c;需要展示100条数据#xff0c;当每条数据里面需要承载的内容很多#xff0c;需要渲染的元素也很多的时候#xff0c;容易造成页面加载的速度很慢#xff0c;不能给用户提供很好的体验时#xff0c;懒加载是优化页面加载速度的方… 前言 在一个表格中需要展示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} // controllerdiv style{{width: 100%, height: 200px}}{第${item}个元素}/div/LazyBuilder}): null}/div)}
}
初次加载 滚动后