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

虚拟滚动;懒加载;高并发组件

虚拟滚动的实现

思路:它只渲染当前可视区域内的元素,而不是整个列表滚动时计算出应该显示哪些元素

原生JS

class VirtualScroll {constructor(container, items, itemHeight, renderItem) {this.container = container;this.items = items;this.itemHeight = itemHeight;this.renderItem = renderItem;this.visibleItemCount = Math.ceil(container.clientHeight / itemHeight);this.totalHeight = items.length * itemHeight;this.init();}init() {// 设置容器高度以保持正确滚动条this.container.style.height = `${this.totalHeight}px`;// 创建内容容器this.content = document.createElement('div');this.container.appendChild(this.content);// 初始渲染this.render();// 添加滚动事件监听this.container.addEventListener('scroll', () => this.render());}render() {const scrollTop = this.container.scrollTop;const startIndex = Math.floor(scrollTop / this.itemHeight);const endIndex = Math.min(startIndex + this.visibleItemCount + 1, // +1 防止滚动时出现空白this.items.length);// 计算内容偏移量const offsetY = startIndex * this.itemHeight;// 渲染可见项let html = '';for (let i = startIndex; i < endIndex; i++) {html += this.renderItem(this.items[i], i);}this.content.innerHTML = html;this.content.style.transform = `translateY(${offsetY}px)`;}
}// 使用示例
const container = document.getElementById('scroll-container');
const items = Array.from({ length: 10000 }, (_, i) => `Item ${i + 1}`);
const itemHeight = 50;const virtualScroll = new VirtualScroll(container,items,itemHeight,(item, index) => `<div style="height: ${itemHeight}px; border-bottom: 1px solid #eee;">${item}</div>`
);

vue

<template><RecycleScrollerclass="scroller":items="items":item-size="50"key-field="id"v-slot="{ item }"><div class="item">{{ item.text }}</div></RecycleScroller>
</template><script>
import { RecycleScroller } from 'vue-virtual-scroller';
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css';export default {components: {RecycleScroller},data() {return {items: Array.from({ length: 10000 }, (_, i) => ({id: i,text: `Item ${i + 1}`}))};}
};
</script><style>
.scroller {height: 500px;
}
.item {height: 50px;border-bottom: 1px solid #eee;
}
</style>

懒加载的实现

原理:延迟加载,例如图片:第一次只显示10张,滚动时请求显示20张,累加的

图片懒加载实现

原生JS

1. 使用原生HTML loading="lazy"属性
<img src="placeholder.jpg" data-src="actual-image.jpg" loading="lazy" alt="示例图片">
2. 使用Intersection Observer API
document.addEventListener("DOMContentLoaded", function() {const lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));if ("IntersectionObserver" in window) {const lazyImageObserver = new IntersectionObserver(function(entries, observer) {entries.forEach(function(entry) {if (entry.isIntersecting) {const lazyImage = entry.target;lazyImage.src = lazyImage.dataset.src;lazyImage.classList.remove("lazy");lazyImageObserver.unobserve(lazyImage);}});});lazyImages.forEach(function(lazyImage) {lazyImageObserver.observe(lazyImage);});} else {// 回退方案lazyImages.forEach(function(lazyImage) {lazyImage.src = lazyImage.dataset.src;});}
});
3. 滚动事件监听实现(兼容旧浏览器)
function lazyLoad() {const images = document.querySelectorAll('img[data-src]');const windowHeight = window.innerHeight;images.forEach(img => {const imgTop = img.getBoundingClientRect().top;if (imgTop < windowHeight + 100) { // 提前100px加载img.src = img.dataset.src;img.removeAttribute('data-src');}});
}// 初始加载
lazyLoad();// 滚动事件节流
window.addEventListener('scroll', throttle(lazyLoad, 200));function throttle(func, wait) {let timeout;return function() {if (!timeout) {timeout = setTimeout(() => {func();timeout = null;}, wait);}};
}

 vue

1.使用动态导入
const LazyComponent = () => import('./HeavyComponent.vue');new Vue({components: {LazyComponent}
});2. 结合路由的懒加载
const router = new VueRouter({routes: [{path: '/heavy',component: () => import('./views/HeavyView.vue')}]
});3. 基于视口的组件懒加载
<template><div ref="container"><component v-if="isVisible" :is="loadedComponent" /><div v-else>加载中...</div></div>
</template><script>
export default {props: {component: {type: Promise,required: true}},data() {return {isVisible: false,loadedComponent: null};},mounted() {const observer = new IntersectionObserver(([entry]) => {if (entry.isIntersecting) {this.loadComponent();observer.unobserve(this.$refs.container);}},{ threshold: 0.1 });observer.observe(this.$refs.container);},methods: {async loadComponent() {this.loadedComponent = (await this.component).default;this.isVisible = true;}}
};
</script>

高并发组件 

 

相关文章:

  • Java与Kotlin在Android开发中的全面对比分析
  • Python Cookbook-6.8 避免属性读写的冗余代码
  • TCP粘包拆包全攻略:Netty实战解决高并发通信难题
  • AKM旭化成微电子全新推出能量收集IC“AP4413系列”
  • iOS/Android 使用 C++ 跨平台模块时的内存与生命周期管理
  • kvm网卡发现的采集信息脚本COLT_CMDB_KVM_NETDISC.sh
  • ViewPager FragmentPagerAdapter在系统杀死应用后重建时UI不刷新的问题
  • 河北省大数据应用创新大赛样题
  • 大模型——快速部署和使用 Deep Research Web UI
  • SOLID 原则在单片机环境下的 C 语言实现示例,结合嵌入式开发常见场景进行详细说明
  • [吾爱出品] 【键鼠自动化工具】支持识别窗口、识图、发送文本、按键组合等
  • 基于AI应用创业IDEA:使用百度搜索开放平台的MCP广场智能推荐MCPServices服务
  • java使用CMU sphinx语音识别
  • Java代理讲解
  • 多层级的对象如何修改、或json格式
  • 回溯算法理论基础
  • Verilog 语法 (二)
  • 小刚说C语言刷题——1565成绩(score)
  • element-ui tabs 组件源码分享
  • 品融电商:以全域增长方法论,解码2025情绪消费新机遇
  • 主播说联播丨六部门出台新政!来华买买买,实惠多多多
  • 人民日报头版:上海纵深推进浦东高水平改革开放
  • 当智驾成标配,车企暗战升级|2025上海车展
  • 云南省委常委、组织部部长刘非任浙江省委常委、杭州市委书记
  • 第六次“太空会师”,神舟二十号3名航天员顺利进驻中国空间站
  • 导演汪俊:与孙俪默契合作,还原“蛮好的人生”