​​【面试题】后端返回十万条数据前端怎么处理?vue实现虚拟列表

简介: vue实现虚拟列表

一.前言

想必大家在面试的时候会经常被问到后端一下返回十万条数据前端怎么进行处理,二面问。这是一个有关项目优化的问题。前面我写了一篇关于时间分片(数据分割)和滚动触底加载的文章,在这我就不写了,感兴趣的大家可以去看看,有源码,很详细。

二.为嘛这个面试题的答案是虚拟列表?

首先遇到这种大数据处理,肯定想到的是数据懒加载,那就是虚拟列表、时间分片、滚动加载,当然最常用的方法是分页,但是产品经理他不想让你这么干,最近项目优化用到这个方案,详细总结一下

    时间分片:通过定时器在规定时间内更新数据,数据是一种伪实时性的,给人一种感觉是实时更新,其实不是,因为你定时器时间跟websocket推送数据的时间间隔不一样。而且时间分片约到后面页面越卡,真实项目经验。

    滚动条触底加载:通过监听滚动条时间,只要触底就进行调接口返回数据。一下返回十万条数据真渲染不出来,而且你不能一触底就调接口,这样也是耗费性能的,所以滚动条触底加载只适合少量数据

    虚拟列表:只对可见区域的数据进行渲染,对非可见区域的数据只做缓存,不渲染。以此来减少性能消耗,提高用户体验。它是长列表的一种优化方案。性能可以说是数据懒加载中的最优化方案。

三.虚拟列表的实现思路(重点:面试过程中就这么回答)

1.首先你得写一个div,这个div得固定高度。通过css的overflow属性使其允许纵向y轴滚动。
2.计算可视区域内可以显示的数据条数。可以用可视区域的高度除以一条数据的高度。
3.监听滚动条,当滚动条滚动时计算出被卷起的数据的高度。
4.计算这个可视区域内数据的起始索引值,也就是第一条数据的下标。通过滚动条卷起的高度除以单条数据的高度,这块可能大家一下反应不过来,起始坐标最开始是0对吧。卷起的高度除以单条数据的高度是不是就是卷起的数据的数量,那么他的索引值是不是就是数据的数量。假如被卷起四条数据,那么第五条数据索引值是不是四。
5.计算区域结束数据的索引。通过起始索引加上可视区域显示的数据条数
6.截取数据渲染到可视区域。从起始索引截取到结束索引。
7.计算起始索引在整个列表中的偏移位置并设置到列表上,因为每次都不可能滚动到整条数据上。
这样一个基本的虚拟列表就有了,当然大家可以根据需求做一些性能优化,比如防抖节流,如果用户一直快速滚动问题。

四.小demo.(代码+注释)


<template>
    <div :style="{ height: `${contentHeight}px` }" class="content_box" @scroll="scroll">
        <!--这层div是为了把高度撑开,让滚动条出现,height值为所有数据总高-->
        <div :style="{
   
    'height': `${
     
     itemHeight * (listAll.length)}px`, 'position': 'relative' }">
            <!--可视区域里所有数据的渲染区域-->
            <div :style="{
   
    'position': 'absolute', 'top': `${
     
     top}px` }">
                <!--单条数据渲染区域-->
                <div v-for="(item, index) in showList" :key="index" class="item">
                    {
   
   {
   
    item }}
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
   
   
    name: "list",
    data () {
   
   
        return {
   
   
            listAll: [],  //所有数据
            showList: [],  //可视区域显示的数据
            contentHeight: 500,  //可视区域高度
            itemHeight: 30,      //每条数据所占高度
            showNum: 0,  //可是区域显示的最大条数
            top: 0, //偏移量
            scrollTop: 0,  //卷起的高度
            startIndex: 0,  //可视区域第一条数据的索引
            endIndex: 0,  //可视区域最后一条数据后面那条数据的的索引,因为后面要用slice(start,end)方法取需要的数据,但是slice规定end对应数据不包含在里面
        }
    },
    methods: {
   
   
        //构造10万条数据
        getList () {
   
   
            for (let i = 0; i < 100000; i++) {
   
   
                this.listAll.push(`我是bug天选之子的第${
     
     i}数据呀`)
            }
        },
        //计算可视区域数据
        getShowList () {
   
   
            this.showNum = Math.ceil(this.contentHeight / this.itemHeight);  //可视区域最多出现的数据条数,值是小数的话往上取整,因为极端情况是第一条和最后一条都只显示一部分
            this.startIndex = Math.floor(this.scrollTop / this.itemHeight);   //可视区域第一条数据的索引
            this.endIndex = this.startIndex + this.showNum;   //可视区域最后一条数据的后面那条数据的索引
            this.showList = this.listAll.slice(this.startIndex, this.endIndex)  //可视区域显示的数据,即最后要渲染的数据。实际的数据索引是从this.startIndex到this.endIndex-1
            const offsetY = this.scrollTop - (this.scrollTop % this.itemHeight);  //在这需要获得一个可以被itemHeight整除的数来作为item的偏移量,这样随机滑动时第一条数据都是完整显示的
            this.top = offsetY;
        },
        //监听滚动事件,实时计算scrollTop
        scroll () {
   
   
            this.scrollTop = document.querySelector('.content_box').scrollTop;  //element.scrollTop方法可以获取到卷起的高度
            this.getShowList();
        }
    },
    mounted () {
   
   
        this.getList();
        this.scroll();
    }
}
</script>

<style scoped>
.content_box {
   
   
    overflow: auto;
    /*只有这行代码写了,内容超出高度才会出现滚动条*/
    width: 700px;
    border: 1px solid red;
}

/*每条数据的样式*/
.item {
   
   
    height: 30px;
    padding: 5px;
    color: #666;
    box-sizing: border-box;
}
</style>

```

运行效果:
8.1.png

相关文章
|
5天前
|
JavaScript 前端开发 算法
前端优化之超大数组更新:深入分析Vue/React/Svelte的更新渲染策略
本文对比了 Vue、React 和 Svelte 在数组渲染方面的实现方式和优缺点,探讨了它们与直接操作 DOM 的差异及 Web Components 的实现方式。Vue 通过响应式系统自动管理数据变化,React 利用虚拟 DOM 和 `diffing` 算法优化更新,Svelte 通过编译时优化提升性能。文章还介绍了数组更新的优化策略,如使用 `key`、分片渲染、虚拟滚动等,帮助开发者在处理大型数组时提升性能。总结指出,选择合适的框架应根据项目复杂度和性能需求来决定。
|
12天前
|
前端开发 JavaScript 安全
在vue前端开发中基于refreshToken和axios拦截器实现token的无感刷新
在vue前端开发中基于refreshToken和axios拦截器实现token的无感刷新
49 4
|
7天前
|
前端开发 JavaScript API
2025年前端框架是该选vue还是react?有了大模型-例如通义灵码辅助编码,就不用纠结了!vue用的多选react,react用的多选vue
本文比较了Vue和React两大前端框架,从状态管理、数据流、依赖注入、组件管理等方面进行了详细对比。当前版本和下载量数据显示React更为流行,但Vue在国内用户量增长迅速。Vue 3通过组合式API提供了更灵活的状态管理和组件逻辑复用,适合中小型项目;React则更适合大型项目和复杂交互逻辑。文章还给出了选型建议,强调了多框架学习的重要性,认为技术问题已不再是选型的关键,熟悉各框架的最佳实践更为重要。
|
13天前
|
JSON 前端开发 JavaScript
Vue微前端新探:iframe优雅升级,扬长避短,重获新生
Vue微前端新探:iframe优雅升级,扬长避短,重获新生
67 0
|
13天前
|
JavaScript 前端开发 应用服务中间件
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
83 0
|
3月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
22天前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
50 2
|
26天前
|
JSON 安全 前端开发
第二次面试总结 - 宏汉科技 - Java后端开发
本文是作者对宏汉科技Java后端开发岗位的第二次面试总结,面试结果不理想,主要原因是Java基础知识掌握不牢固,文章详细列出了面试中被问到的技术问题及答案,包括字符串相关函数、抽象类与接口的区别、Java创建线程池的方式、回调函数、函数式接口、反射以及Java中的集合等。
24 0
|
3月前
|
XML 存储 JSON
【IO面试题 六】、 除了Java自带的序列化之外,你还了解哪些序列化工具?
除了Java自带的序列化,常见的序列化工具还包括JSON(如jackson、gson、fastjson)、Protobuf、Thrift和Avro,各具特点,适用于不同的应用场景和性能需求。
|
3月前
|
Java
【Java基础面试三十七】、说一说Java的异常机制
这篇文章介绍了Java异常机制的三个主要方面:异常处理(使用try、catch、finally语句)、抛出异常(使用throw和throws关键字)、以及异常跟踪栈(异常传播和程序终止时的栈信息输出)。