【性能优化】在大批量数据下使用 HTML+CSS实现走马灯,防止页面卡顿

切换效果

页面结构变化

1.需求背景

项目首页存有一个小的轮播模块,保密原因大概只能这么展示,左侧图片右侧文字,后端一次性返回几百条数据(开发环境下,生产环境只会更多).无法使用分页解决,前端需要懒加载防止页面卡顿

写个小demo演示,如下

2.解决思路

获取到数据后,取第一条数据展示.切换时,这里以查看下一张为例演示.切换下一张时,动态创建一个dom元素,通过字符串的方式设置innerHtml,将下一张的dom元素插入父节点.

同时父元素的第一个子元素(初始展示第一条数据的dom元素)和新创建的展示下一条数据的dom元素同时向左偏移自身宽度,然后把切走的dom元素清除,实现切换效果,同时避免页面大量结构堆积

3.代码如下

仅做了'下一张'功能,其他请自行补充

html 复制代码
<template>
    <div class="container">
        <button @click="golast">上一张</button>
        <button @click="gonext">下一张</button>
        <div class="windows">
            <div class="scrollBox">
                <div class="scrollItem">
                    <div class="img">
                        <el-image :src="initialData.imgUrl"></el-image>
                    </div>
                    <div class="messBox">{{ initialData.mess }}</div>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
export default {
  data () {
    return {
      localData: [
       { imgUrl: '../assets/xxx.png', mess: '11111' },
       { imgUrl: '../assets/xxx.png', mess: '22222' },
       { imgUrl: '../assets/xxx.png', mess: '33333' },
       { imgUrl: '../assets/xxx.png', mess: '44444' },
       { imgUrl: '../assets/xxx.png', mess: '55555' },
       { imgUrl: '../assets/xxx.png', mess: '66666' },
      ],
      initialData: '', // 初始展示数据
      nowIndex: 0// 当前展示数据的索引
    }
  },
  created () {
  },
  mounted () {
    this.initData()
  },
  computed: {
  },
  methods: {
    initData () {
      // 初始副职
      this.initialData = this.localData[this.nowIndex]
    },

    // 点击查看上一张
    golast () {
    },

    // 点击查看下一张
    gonext () {
      if (this.localData.length <= this.nowIndex + 1) return
      this.readyBox('next')

      const fatherDom = document.querySelector('.windows')
      const moveDistanceX = fatherDom.offsetWidth
      const domArr = fatherDom.querySelectorAll('.scrollBox')
	   // 这里判断.初始结构和动态创建的元素的初始位置不同,导致偏移时的数值是不同的
      if (!domArr[0].classList.contains('newScrollBox')) {
        domArr[0].style.transform = `translate(-${moveDistanceX}px,0px)`
      } else {
        domArr[0].style.transform = `translate(-${moveDistanceX * 2}px,0px)`
      }
      domArr[1].style.transform = `translateX(-${moveDistanceX}px)`
      this.nowIndex++
      // 移除上一个dom元素
      const timeId1 = setTimeout(() => {
        fatherDom.removeChild(domArr[0])
        clearTimeout(timeId1)
      }, 501)
    },

    // 为下一次切换准备dom元素
    readyBox (type) {
      // 信息展示列表无数据或只有一条数据时,不执行
      if (this.localData.length <= 1) return

      let nextShowData = ''// 上一张或下一张要展示的数据
      const fatherDom = document.querySelector('.windows')// 获取父元素
      const newDom = document.createElement('div')// 创建新元素
      // 设置新元素的样式
      newDom.className = 'scrollBox'
      newDom.classList.add('newScrollBox')
      newDom.style.width = '100%'
      newDom.style.height = '100%'
      newDom.style.position = 'absolute'
      newDom.style.transition = 'all 0.5s'

      // 上一张
      if (type === 'last') {
        // 判断当前展示列表是否合法
        if (this.nowIndex - 1 < 0) return
        nextShowData = this.localData[this.nowIndex - 1]
        //此处省略........,自行补充
      }
      //   下一张
      if (type === 'next') {
        // 判断当前展示列表是否合法
        if (this.localData.length <= this.nowIndex + 1) return
        nextShowData = this.localData[this.nowIndex + 1]// 下一张的数据
        newDom.style.left = '100%'
      }

      // 新元素的内部结构
      const innerHtml = `
                <div class="scrollItem" style=" display: flex;  width: 100%; height: 100%; background-color: pink;">
                    <div class="img" style="width:50%; height:100%" >
                        <el-image src="${nextShowData.imgUrl}"></el-image>
                    </div>
                    <div class="messBox" style=" font-size: 16px; width:50%; height:100%; background-color: skyblue; ">
                        ${nextShowData.mess}
                    </div>
                </div>
        `
      // 插入子元素
      newDom.innerHTML = innerHtml
      fatherDom.appendChild(newDom)
    }
  }
}
</script>
<style lang='scss' scoped>
.container {
    width: 100%;
    height: 100%;
}

.container .windows {
    position: relative;
    left: 30%;
    font-size: 0px;
    overflow: hidden;
    width: 40%;
    height: 40%;
    border: 1px solid red;
}

.scrollBox {
    position: absolute;
    width: 100%;
    height: 100%;
    transition: all 0.5s;
}

.windows .scrollItem {
    display: flex;
    width: 100%;
    height: 100%;
    background-color: pink;
}

.windows .scrollItem .img {
    width: 50%;
    height: 100%;
}

.windows .messBox {
    font-size: 16px;
    width: 50%;
    height: 100%;
    background-color: skyblue;
}
</style>
相关推荐
饼干哥哥27 分钟前
2026年是 AI落地大年,但会淘汰一批AI PPT工具
html
酉鬼女又兒1 小时前
零基础快速入门前端Web存储(sessionStorage & localStorage)知识点详解与蓝桥杯考点应用(可用于备赛蓝桥杯Web应用开发)
开发语言·前端·javascript·职场和发展·蓝桥杯·html
带娃的IT创业者2 小时前
WeClaw_38_CFTA异步调用链优化:从阻塞15秒到非阻塞并发
性能优化·系统架构·异步编程·事件总线·事件驱动·并发优化·cfta
是上好佳佳佳呀6 小时前
【前端(四)】CSS 知识梳理:显示模式与盒子模型
前端·css
apcipot_rain7 小时前
HTML知识概述
前端·javascript·html
dora8 小时前
Android弱网优化 —— 都要卫星互联网了,谁给我限速体验2G
android·性能优化
ZPC82108 小时前
MoveIt Servo 控制真实机械臂
人工智能·pytorch·算法·性能优化·机器人
爱丽_8 小时前
MyBatis 性能优化:批处理、分页、缓存与慢 SQL 定位
缓存·性能优化·mybatis
qq_381338508 小时前
Vue3 性能优化实战:从 10s 到 1s 的加载速度提升
性能优化
yivifu9 小时前
接近完美的HTML文本双行合一排版
前端·javascript·html·双行合一