虚拟滚动列表和css虚拟滚动【有思考】
虛擬滾動列表助力性能優化
我所理解的是,虛擬滾動需要一次性獲取所有數據,但是只渲染顯示屏幕可見范圍內的那些。
要做到這些我需要知道:
- 一行的高度
- 屏幕范圍內能顯示的行數
- 列表在頁面中距離網頁頂部的位置
- 滾動條高度
假設一次只需要展示 10 條數據,需要加載的數據是一個數組listData,只需要裁剪數據范圍listData.slice(0, 10)
隨著滾動條向下,將滾動條高度/一行的高度可以計算出當前行數。
而要模擬滾動條高度就要在頁面掛載時就手動設置頁面的高度為一行高度*listData.length。
最后也是最關鍵的是保持列表一直保持在當前位置上,手動設置列表容器padding-top等于當前滾動條高度。
如何使用?
<template><infinite-list :listData="songs"><template #default="{ listItem }"><div>{{ listItem.title }}</div><!-- ... --></template></infinite-list> </template> <script lang="ts" setup> import InfiniteList from './InfiniteList.vue'const songs = [] // 列表數據 </script>CSS虛擬滾動
這個概念忘了在哪聽到的了。其實我認為它更像是一種內容的懶加載。
他需要用到一個css屬性:content-visibility:控制一個元素是否渲染其內容,它允許用戶代理(瀏覽器)潛在地省略大量布局和渲染工作,直到需要它為止。
其值為auto時的作用是,如果該元素不在屏幕上,并且與用戶無關,則不會渲染其后代元素。
假如我們有這樣一段代碼:
<div class="g-wrap"><div class="textarea-p">...</div>// ...<div class="textarea-p">...</div> </div>基于這種場景,其實我們非常希望對于仍未看到而且還未滾動到的區域,可以延遲加載,只有到我們需要展示、滾動到該處時,頁面內容才進行渲染。
所以,content-visibility: auto 就應運而生了,它允許瀏覽器對于設置了該屬性的元素進行判斷,如果該元素當前不處于視口內,則不渲染該元素。
我們基于上述的代碼,只需要最小化,添加這樣一段代碼:
.textarea-p {content-visibility: auto; }可以看到,在利用 content-visibility: auto 處理長文本、長列表的時候。在滾動頁面的過程中,滾動條一直在抖動,這不是一個好的體驗。
當然,這也是許多虛擬列表都會存在的一些問題。(當然,目前大多數人會選擇“無視”它)
好在,規范制定者也發現了這個問題。這里我們可以使用另外一個 CSS 屬性 —— contain-intrinsic-size來解決這個問題。
contain-intrinsic-size用來控制由 content-visibility 指定的元素的自然大小。
其實就是給需要隱藏的元素一個默認(至少是大概的)高度,讓滾動條能夠提前知道有這些東西。從而一開始就顯示出它應該顯示的大小。
比如上面的代碼:
一些其它思考
這兩天想到了一個場景:后端分頁下支持刪除功能的前端列表如何維持其length?
針對這個問題其實去年想到了一個方案,在學姐的認可下終于試著寫出來,非常簡單:『滾動列表分片請求,區別于一般的“重新請求這一頁甚至是回到第一頁”的做法。新開一個存儲。每次請求10條。后端新增一個字段給出第11-20數據。如果碰上刪除,直接從前端存儲里拿新的一條接上,保證了一定有10條還不用多發請求。新的請求后更新存儲區』
但是這樣終究覺得不夠高端。高~ 端 ~
于是就在想怎么能夠更流批一點。但是這又有一個問題:目前來說這個雖然很簡單的方案已經完全能夠解決問題。有了一絲頭緒的新方案又沒有想到能夠支撐的真實的案例。離譜了。
總結
以上是生活随笔為你收集整理的虚拟滚动列表和css虚拟滚动【有思考】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL 中文首字母提取与自定义排序
- 下一篇: iPhone/iPad/Touch苹果设