寫在前面:不知不覺 ~2023年的日子已經過去了3/4,看到微博熱搜說:2023年還剩下3個月的時候,心情突然驟降~哈哈哈哈
切入正題:
什麼是長列表優化?
我們為什麼需要長列表優化?
我們怎樣進行長列表優化
在我們的日常工作中,會越到各種各樣的列表,比如,我們通常採用分頁的方式進行內容的逐漸獲取,但是不可否認的是,當我們列表內容過多的時候,就會出現頁面滑動卡頓、資料渲染較慢的問題,本次將以10000條資料為基準,進行長列表的優化說明
進行長列表優化,其實和js在瀏覽器中執行的順序有莫大的關係,在我們進行頁面訪問的時候,瀏覽器會根據頁面進行渲染的進行,主要包含
我們的每一步操作,是否恰當或者是否阻塞瀏覽器的執行機制,都是有莫大的關聯的
l瀏覽器中對於js的執行順序
引擎執行緒和ui執行緒是共用乙個執行緒,js的主線程是單執行緒的,但是其在執行過程中能夠開發進行新的執行緒,
1.先進行10000的資料初渲染
我們在懟頁面進行操作的時候,能夠感覺到此時是卡頓的,白屏的時間也是達到了3秒多2.切片,分段渲染頁面
let total =100000;此時進行分片的處理方式,先讓頁面渲染50條資料,然後在逐漸渲染50條資料,達到了分片的目的,但是如果使用者此時拉動比較快的話,頁面資料還沒有渲染出來,導致存在空白螢幕的情況,但是可以解決簡單的分頁資料獲取的問題var con = document.getelementbyid("container")
let timer = date.now();
let index = 0;
let id = 0;//遞增的內容
//分片 根據資料大小劃分,每次載入固定的資料
function load()
load();
},0)}}
//分片載入 會導致頁面dom元素過多,造成頁面的卡頓
load();
不管是切片還是分時進行載入,無非是解決dom節點過多的時候,給我們頁面帶來的壓力問題,因此嘗試動態載入固定資料的節點專案,進而讓頁面中的dom節點減少,渲染一定資料的節點資料;
可以通過按需進行載入dom,即在可視區域內根據當前滾動的高度和列表的長度進行渲染響應dom頁面中減少dom的結構資料
我們dom的節點只載入可視區域的內容
思路分析
首先進行外側的容器的scroll事件進行監聽
計算當前滾動的高度
計算開始位置和結束位置
計算向上滾動的偏移量
進行可視區域資料計算
1.構造資料
import mock from 'mockjs'let items =;2. 使用列表進行資料傳入for(var i=0;i<500;i++))
}
true>virtallist.vue的dom結構
樣式結構
.viewport3.引數說明.scroll-list
size: number, //當前每一項的高度4.滾動監聽後handlscroll的處理函式remain: number, //可見多少個
items: array, //當前專案
由於我們每個列表的高度都是固定的,因此我們不需要計算高度,
this.$refs.viewport.style.height = this.size * this.remain + "px"; //當前的一項高度*顯示的專案高度this.$refs.scrollbar.style.height = this.items.length * this.size + "px"; //當前總長度*當前的專案高度
this.start = math.floor(scrolltop / this.size); //列表開始的位置應該額等於滾動的位置/列表的高度5.計算視覺化的資料列表,渲染該列表即可this.end = this.start + this.remain; //要渲染列表結束的位置等於列表開始的位置加上每一頁資料展示的高度
//如果前面有預留渲染,應該把這個位置向上移動
this.offset = this.start * this.size - this.prevcount * this.size;
computed: ,6.此時看到了prevcount 和nextcount ,是為了解決問題不一致的原因,比如上滑倒一半時候,視覺化資料的前乙個資料還沒有渲染出來,此時導致資料是空白的,後面的資料也是一樣,如果存在一般沒有載入出來的時候,可能導致後面就是白色空白的頁面,因此,此時需要將可視區域的前面幾項和後面幾項多載入出來,防止出現空白化的問題,定義prevcount和nextcount},
computed: ,這樣就可以有效的防止滑動到可視區域的第一項的時候或者最後一項的時候為空而出現空白的頁面//後面預留幾個
nextcount() ,
},
但是在實際工作中,可能列表的高度是乙個不固定的值,這個時候我們就需要進行動態的配置高度和顯示,
思路分析
預估列表的初始高度值,和實際值的列表相差幅度不是很大
根據預估值儲存每個列表的頂部top,高度、底部bottom
滾動時候根據二分查詢方法查詢到當前的初始區域,
更新列表中的實際高度
1.設定列表的 varlable 屬性,表示當前的item的子專案是不固定高度的
2.初始化列表的儲存高度 預估高度
//快取當前的高度,top志等資訊,還有bottom3.滾動時候根據scrolltop查詢到當前可視區域開始顯示位置和結束顯示位置cachelist() ;
});
let scrolltop = this.$refs.viewport.scrolltop;4.二分查詢方法進行查詢開始位置和結束位置if (this.varlable) else
getstartindex(value)else if(middlevalue value)二分查詢法進行步驟分析end = middleindex -1; } }
return temp;
},
5.更新元件內儲存的列表高度
此時列表是不固定高度的,因此在滾動的過程中,我們需要對列表的真實高度進行測試和賦值
在vue的updated的生命週期中進行更新資料操作
updated()除了我們的高度,滾動條設定的為初始值,因此也需要進行更新//遍歷當前所在節點資訊,
nodes.foreach(node=> = node.getboundingclientrect();//真實高度
let id = node.getattribute('vid')-0; //獲取當前的item的位置,id表示index
let oldheight = this.positions[id].height; //老的高度
let val = oldheight - height; //高度差值
//如果當前元素存在高度差值,則當前高度需要進行增加/減少,這樣,當前元素的後面元素的表示位置也需要在原高度上進行更改
if(val)
} })
//動態的計算滾動條的高度 滾動條的高度就等於positions的最後乙個元素的最底部的位置
this.$refs.scrollbar.style.height
= this.positions[this.positions.length-1].bottom
+'px'
})},
效果圖展示:
留下一些疑問,我們在滾動的時候其實做著大量的計算操作,會不會影響效能呢?
這樣做的好處又是什麼呢?
vue 長列表效能優化
因為每次 dom 修改,瀏覽器往往需要重新計算元素布局,再重新渲染。也就是所謂的重排 reflow 和重繪 repaint 尤其是在頁面包含大量元素和複雜布局的情況下,效能會受到影響。乙個常見的場景是大資料量的列表渲染。通常表現為可無限滾動的無序列表或者 當資料很多時,頁面會出現明顯的滾動卡頓 方案...
優化長列表
最近做的專案有乙個列表模組資料量巨大,後端限制完資料後還有大概10000條資料,直接渲染的話會有明細的卡頓情況,於是擼起袖子開始重構。這裡只回顧一下實現原理以便以後忘了能立馬撿起來 1.儲存原始列表陣列資料 2.只渲染可視區域大小的元素 3.當滾輪滾動時,動態的計算當前的scrolltop的值,然後...
靜態長列表優化
之前在商品模組的時候遇到乙個這樣的問題多個規格組合在一起的時候 規格列表就會很長並且每乙個規格都會有不同的 跟會員價等等資訊,所以會造成每一條商品資料會十分的臃腫再加上多條的話,對於商品規格資料的增刪改查操作的時候頁面會卡頓白屏操作甚至會載入不出來等情況 針對這一反饋我們的長列表優化就來了 思路外層...