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

前端实现模块懒加载

通常对于无规则长列表带来的加载耗时长、性能差的问题,首先想到的方案就是通过滚动位置判断当前模块是否进入视图中,来判断模块是否加载。这样有两个弊端:
1. 要预先知道每个模块的准确高度。通常情况下这个高度的是动态的,难以在初始状态下获取所有模块的高度
2. 要实时计算滚动位置,来判断模块是否进去视图

利用交叉观察器IntersectionObserver API的特性,可以自动"观察"元素是否可见,Chrome 51+ 已经支持。在react中的具体实现demo如下:

在父组件中声明

const intersectionEntriesMapRef = useRef<WeakMap<Element, (isIntersecting:boolean) => void>>(new WeakMap([]));
// IntersectionObserver实例
const intersectionObserverRef = useRef<IntersectionObserver>(new IntersectionObserver(entries => {entries.forEach(({ target, isIntersecting }) => {intersectionEntriesMapRef.current.get(target)?.(isIntersecting);});})
);

实例化子组件的时候传入intersectionObserverRef、intersectionEntriesMapRef

<ChildComintersectionObserverRef={intersectionObserverRef}intersectionEntriesMapRef={intersectionEntriesMapRef}contentDefaultHeight={283}...
/>

通过contentDefaultHeight对子模块的高度进行预估

子模块ChildCom中监听加载,获取准确高度,并通过observe挂载在intersectionObserverRef上

const [contentShow, setContentShow] = useState(false);
// 子模块内容区域dom绑定
const contentWrapRef = useRef<HTMLDivElement>(null);
// 子模块内容区域高度缓存
const contentHeightRef = useRef<number>(contentDefaultHeight ?? 0);useEffect(() => {const _contentWrapRef = contentWrapRef.current;const _intersectionObserverRef = intersectionObserverRef?.current;intersectionEntriesMapRef?.current?.set(_contentWrapRef, isIntersecting => {setContentShow(isIntersecting);isIntersecting &&requestAnimationFrame(() => {contentHeightRef.current = _contentWrapRef?.offsetHeight;});});_intersectionObserverRef?.observe(_contentWrapRef);return () => {_intersectionObserverRef?.unobserve(_contentWrapRef);};
}, []);return (<div ref={contentWrapRef}>{contentShow ? <div>你的模块内容</div> : <></>}</div>
);

http://www.mrgr.cn/news/12976.html

相关文章:

  • 有哪些内部知识库类似钉钉,满足企业多样化需求?
  • Oracle 11g数据库与某个表的最新一笔记录进行关联
  • go国内源设置
  • 16岁激活交学费银行卡需要本人实名电话卡,线下营业厅不给办,怎么办?
  • 自动化01:认识接线端子
  • docker0: iptables: No chain/target/match by that name问题解决
  • git如何将多个提交合并为一个提交
  • Linux网络
  • Maven基本使用
  • 本地化云桌面系统环境VMware horizon搭建
  • Zotero打开后所有文献及笔记都消失了
  • Spring Boot使用拦截器(Interceptor)
  • 黑神话悟空无法登录服务器怎么办
  • 数据库系统 第28节 数据库迁移 案例分析
  • iOS 苹果健康-睡眠
  • 3D工艺大师:精准助力医疗设备远程维修
  • Redis key的过期时间和永久有效
  • 2024华为性格测试机考真题丨不会有人OD机试满分结果挂在性格测试上了吧?
  • golang RSA 解密前端jsencrypt发送的数据时异常 crypto/rsa: decryption error 解决方法
  • Linux的log日志排查