最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

前端虛擬列表實現(xiàn)的思路及完整代碼

 更新時間:2025年01月23日 09:54:06   作者:跳房子的前端  
這篇文章主要介紹了前端虛擬列表實現(xiàn)的思路及完整代碼,虛擬列表是一種優(yōu)化長列表性能的技術(shù),通過只渲染可視區(qū)域的列表項來提升頁面性能和用戶體驗,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

一、什么是虛擬列表

虛擬列表(Virtual List)是一種用于優(yōu)化長列表性能的技術(shù)解決方案。其核心思想是:只渲染可視區(qū)域的列表項,而不是渲染整個列表的所有項。這種技術(shù)特別適用于需要展示大量數(shù)據(jù)的場景,可以顯著提升頁面性能和用戶體驗。

二、為什么需要虛擬列表

假設(shè)我們需要渲染一個包含10000條數(shù)據(jù)的列表:

  • 性能問題

    • DOM節(jié)點過多會導致頁面渲染慢
    • 內(nèi)存占用大
    • 滾動卡頓
  • 用戶體驗

    • 首屏加載時間長
    • 操作響應(yīng)慢
    • 設(shè)備發(fā)熱嚴重

三、虛擬列表的實現(xiàn)原理

1. 核心概念

  • 可視區(qū)域(Viewport):用戶能看到的列表區(qū)域
  • 可視區(qū)域高度:視口的高度
  • 列表項高度:每個列表項的高度
  • 可視區(qū)域起始索引:當前可見區(qū)域的第一個列表項的索引
  • 可視區(qū)域結(jié)束索引:當前可見區(qū)域的最后一個列表項的索引
  • 偏移量(offset):列表滾動的距離

2. 計算公式

// 可顯示的列表項數(shù)量
visibleCount = Math.ceil(viewportHeight / itemHeight)

// 起始索引
startIndex = Math.floor(scrollTop / itemHeight)

// 結(jié)束索引
endIndex = startIndex + visibleCount

// 偏移量
offset = scrollTop - (scrollTop % itemHeight)

四、代碼實現(xiàn)

1. 基礎(chǔ)結(jié)構(gòu)

<div class="viewport" @scroll="handleScroll">
  <div class="scroll-list" :style="{ height: totalHeight + 'px' }">
    <div class="scroll-content" :style="{ transform: `translateY(${offset}px)` }">
      <!-- 渲染區(qū)域列表項 -->
    </div>
  </div>
</div>

2. 完整實現(xiàn)

class VirtualList {
  constructor(options) {
    this.itemHeight = options.itemHeight;
    this.total = options.total;
    this.viewport = options.viewport;
    this.buffer = options.buffer || 5;
    
    this.viewportHeight = this.viewport.clientHeight;
    this.visibleCount = Math.ceil(this.viewportHeight / this.itemHeight);
    this.startIndex = 0;
    this.endIndex = this.startIndex + this.visibleCount + this.buffer;
    this.offset = 0;
    
    this.initDom();
    this.bindEvents();
  }
  
  initDom() {
    this.scrollList = document.createElement('div');
    this.scrollList.className = 'scroll-list';
    this.scrollList.style.height = this.total * this.itemHeight + 'px';
    
    this.scrollContent = document.createElement('div');
    this.scrollContent.className = 'scroll-content';
    
    this.scrollList.appendChild(this.scrollContent);
    this.viewport.appendChild(this.scrollList);
  }
  
  bindEvents() {
    this.viewport.addEventListener('scroll', this.handleScroll.bind(this));
  }
  
  handleScroll() {
    const scrollTop = this.viewport.scrollTop;
    this.startIndex = Math.floor(scrollTop / this.itemHeight);
    this.endIndex = this.startIndex + this.visibleCount + this.buffer;
    this.offset = this.startIndex * this.itemHeight;
    
    this.updateContent();
  }
  
  updateContent() {
    const visibleData = this.getVisibleData();
    this.scrollContent.style.transform = `translateY(${this.offset}px)`;
    // 更新列表內(nèi)容
    this.renderData(visibleData);
  }
  
  getVisibleData() {
    return this.data.slice(this.startIndex, this.endIndex);
  }
  
  renderData(data) {
    // 根據(jù)數(shù)據(jù)渲染DOM
  }
}

五、優(yōu)化技巧

1. 使用 Buffer 緩沖區(qū)

在可視區(qū)域的上下額外渲染一些列表項,可以改善快速滾動時的白屏問題:

const bufferSize = 5;
startIndex = Math.max(0, startIndex - bufferSize);
endIndex = Math.min(total, endIndex + bufferSize);

2. 動態(tài)高度處理

對于列表項高度不固定的情況,可以:

  • 預(yù)估高度
  • 緩存真實高度
  • 動態(tài)更新位置
class DynamicVirtualList {
  constructor() {
    this.heightCache = new Map();
    this.estimatedHeight = 100;
  }
  
  updatePosition() {
    let totalHeight = 0;
    for (let i = 0; i < this.startIndex; i++) {
      totalHeight += this.getItemHeight(i);
    }
    this.offset = totalHeight;
  }
  
  getItemHeight(index) {
    return this.heightCache.get(index) || this.estimatedHeight;
  }
}

3. 防抖和節(jié)流

對滾動事件進行防抖和節(jié)流處理,避免頻繁計算:

function throttle(fn, delay) {
  let timer = null;
  return function() {
    if (!timer) {
      timer = setTimeout(() => {
        fn.apply(this, arguments);
        timer = null;
      }, delay);
    }
  }
}

handleScroll = throttle(function() {
  // 滾動處理邏輯
}, 16);

六、性能優(yōu)化建議

  • 使用 transform 代替 top

    • transform 執(zhí)行在合成層,性能更好
    • 避免重排
  • RAF優(yōu)化

    requestAnimationFrame(() => {
      this.updateContent();
    });
    
  • 列表項組件緩存

    • 使用React.memo或Vue的keep-alive
    • 避免不必要的重渲染
  • 避免在滾動時進行大量計算

    • 預(yù)計算數(shù)據(jù)
    • 使用Web Worker

七、使用場景

  • 長列表渲染
  • 無限滾動
  • 大數(shù)據(jù)表格
  • 時間軸
  • 聊天記錄

八、注意事項

  • 需要準確設(shè)置容器高度
  • 處理列表項動態(tài)高度
  • 考慮滾動到底部的加載更多
  • 保持滾動位置
  • 鍵盤訪問性

這篇文章詳細介紹了虛擬列表的概念、實現(xiàn)原理和優(yōu)化方案。主要包括:

  • 基本概念和原理解釋
  • 完整的代碼實現(xiàn)
  • 多種優(yōu)化方案
  • 實際應(yīng)用場景
  • 注意事項

總結(jié) 

到此這篇關(guān)于前端虛擬列表實現(xiàn)的文章就介紹到這了,更多相關(guān)前端虛擬列表實現(xiàn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue中使用router全局守衛(wèi)實現(xiàn)頁面攔截的示例

    vue中使用router全局守衛(wèi)實現(xiàn)頁面攔截的示例

    這篇文章主要介紹了vue中使用router全局守衛(wèi)實現(xiàn)頁面攔截的示例,幫助大家維護自己的項目,感興趣的朋友可以了解下
    2020-10-10
  • vue element-ui讀取pdf文件的方法

    vue element-ui讀取pdf文件的方法

    這篇文章主要介紹了vue element-ui讀取pdf文件的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • Vue項目利用axios請求接口下載excel

    Vue項目利用axios請求接口下載excel

    這篇文章主要為大家詳細介紹了Vue項目利用axios請求接口下載excel,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • vue-cli2.x舊版本卸載不掉的問題踩坑指南(附Vue腳手架安裝教程)

    vue-cli2.x舊版本卸載不掉的問題踩坑指南(附Vue腳手架安裝教程)

    遇到一個Vuecli2腳手架卸載不了的問題,查了許多資料說的都比較復雜,所以下面這篇文章主要給大家介紹了關(guān)于vue-cli2.x舊版本卸載不掉的問題踩坑的相關(guān)資料,文中還附了Vue腳手架安裝教程,需要的朋友可以參考下
    2022-07-07
  • 詳細解釋Vue3中的getCurrentInstance是什么

    詳細解釋Vue3中的getCurrentInstance是什么

    這篇文章主要介紹了Vue3中g(shù)etCurrentInstance是什么的相關(guān)資料,getCurrentInstance是Vue3提供的一個API,用于在組合式API中獲取當前組件實例,從而訪問組件的屬性、方法、插槽等信息,文中將用法介紹的非常詳細,需要的朋友可以參考下
    2025-05-05
  • elementPlus?的el-select在提示框關(guān)閉時自動彈出的問題解決

    elementPlus?的el-select在提示框關(guān)閉時自動彈出的問題解決

    這篇文章主要介紹了elementPlus?的el-select在提示框關(guān)閉時自動彈出閉時自動彈出的問題,主要問題就是因為filterable屬性,根本解決方案是選中的時候讓他失去焦點?el-select有一個visible-change事件,下拉框出現(xiàn)/隱藏時觸發(fā),感興趣的朋友跟隨小編一起看看吧
    2024-01-01
  • Element input樹型下拉框的實現(xiàn)代碼

    Element input樹型下拉框的實現(xiàn)代碼

    這篇文章主要介紹了Element input樹型下拉框的實現(xiàn)代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • moment轉(zhuǎn)化時間戳出現(xiàn)Invalid Date的問題及解決

    moment轉(zhuǎn)化時間戳出現(xiàn)Invalid Date的問題及解決

    這篇文章主要介紹了moment轉(zhuǎn)化時間戳出現(xiàn)Invalid Date的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • vue實現(xiàn)div拖拽互換位置

    vue實現(xiàn)div拖拽互換位置

    這篇文章主要為大家詳細介紹了vue實現(xiàn)div拖拽互換位置的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • 教你如何優(yōu)化?Vue.js?應(yīng)用程序

    教你如何優(yōu)化?Vue.js?應(yīng)用程序

    Vue?3引入了Composition?API,這是一套新的API用于編寫組件,作為Options?API的替代,這篇文章主要介紹了如何優(yōu)化?Vue.js?應(yīng)用程序,需要的朋友可以參考下
    2023-02-02

最新評論

苍南县| 蓝田县| 安国市| 田阳县| 景洪市| 金溪县| 桦甸市| 临湘市| 自贡市| 乡宁县| 忻州市| 论坛| 隆回县| 平罗县| 湟中县| 安西县| 剑河县| 孝感市| 明光市| 甘南县| 屯门区| 凤凰县| 图们市| 微山县| 淮南市| 务川| 平乐县| 泰州市| 苗栗市| 察雅县| 黑水县| 平顶山市| 古田县| 哈尔滨市| 林周县| 涡阳县| 阿瓦提县| 绿春县| 保德县| 休宁县| 南乐县|