無限滾動列表,顧名思義,是能夠無限滾動的列表(願意是指那些能夠不斷緩衝載入新資料的列表的)。但是,我們真的需要這樣乙個列表嗎?在pc端,瀏覽器的效能其實已經能夠滿足海量dom節點的渲染重新整理(筆者經過簡單的測試,1w+的節點並沒有很明顯的卡頓),但是同樣的dom數量在移動端卻不行,在dom結構合理的情況下,能夠保持在2k+的dom數量已是乙個很不錯的列表了,但是dom數量再進一步增加就會明顯影響頁面的渲染效率,也正因為此原因,才有了此文關於無限列表的一些思考和探索。
首先,為什麼會卡頓?因為dom數量的絕對值上的不斷增多,在後續的互動上(如滾動,區域性更新)都會導致頁面渲染效能的下降。
那麼,應該如何解決?既然是dom數量過多引起的,最簡單也最有效的方法自然是減少dom數量。在jquery時代,筆者便見過一種思路(其實本質實現至今也沒有太大的變化):
1、只渲染特定幾屏的資料,將多餘的資料快取在記憶體中,並不直接例項化到dom tree上,減少dom的絕對數量;
2、監聽滾動事件,在滾動的時候動態的更新dom,讓使用者在視覺上看不出區別;
jquery的實現由於年代久遠,已經找不太到了,不過筆者在react社群找到了乙個比較好的實現:react-virtualized,值得一提的是,它還將我們的滾動場景區分為了viewport內的區域性滾動,和基於viewport的滾動,前者相當於在頁面中開闢了一塊獨立的滾動區域,屬於內部滾動(和iscroll的滾動很類似,順帶一提iscroll也給出了iscroll-infinite的解決方案);而後者則把滾動作為了window滾動的一部分(對於移動端而言,在非模態窗的場景下這種滾動更常見,共用乙個滾動條也不容易引起使用者的誤操作)。因為筆者主要的使用場景是後者,而iscroll的解決方案雖然也能作用於頁面維度的滾動,但是它需要完全替換scroll事件(相當於頁面沒有了scroll事件,只有touchmove事件;且此種頁面在內部滾動和全域性滾動的實現上有不小的難度),所以筆者在無限滾動列表上並沒有使用iscroll的方案。
不過,業內雖然有現成的解決方案固然是好事,但是每種方案都有自己的特性,並不一定都合適,以react-virtualized來說,它的特性在pc上算是乙個很有趣也很不錯的解決方案了:
1、它構造乙個「足夠大」的容器來再現滾動條的實際數值;
2、它使用絕對定位來不斷跟隨滾動事件,改變元素的位置,幾乎完美還原了正常列表的視覺,而且無論dom再多也不會卡頓;
不過,與此同時,它也有一些不足:
1、因為使用了scroll事件,某種程度上,就注定了在ios上的不足(ios scroll時會阻塞js執行),加上它的緩衝區其實是單向的(雖然這也體現了作者想盡可能節省dom的願景),導致使用者如果上下來回滾動,則很容易看到白屏;
2、由於絕對定位的「小技巧」,它要求在元件渲染之初就必須知道每一行元素的高度,但是這個看起來不起眼的小操作,卻很大的影響了開發的體驗(很不湊巧的筆者使用的無限列表的場景,很多情況下列表元素的高度都不能預先知道。。)
也基於以上原因,雖然react-virtualized是很不錯的解決方案了,但是筆者最終沒有採用。不過,在廣泛借鑑了各大廠的實現之後,筆者發現,手淘列表頁的實現,最簡單也最有效,那麼簡單說下實現思路:
1、它引入了分頁的概念,在使用者不斷重新整理增加頁面長度的同時,它將若干元素分為一頁;
2、然後在滾動的時候計算當前滾動到了具體的哪一頁,將「多餘」(不需要顯示,也不需要作為緩衝顯示)的頁的高度取出,直接賦值在容器上,然後將容器內所有元素置空;
3、當「當前頁」發生變化時,動態將需要顯示「空頁」重新加上元素。
其實這一解決方案也有反覆操作dom的效能問題,而且它並不是dom數量優化上的最優解,但是結合筆者的實際使用場景,而且結合考慮到對業務同學的api友好等各方面的,筆者最終也選擇了這一實現,雖然各方面效能不是最好,但是在筆者當前的使用場景中,卻最是有效的。
簡單的小結一下,其實有關無限列表的實現有很多種方案,使用原生scroll事件的痛點在於ios的js阻塞問題以及如何巧妙的設計緩衝區,而使用transform模擬滾動的痛點則是有具體場景的限制和整體的重構成本,兩種方案各有千秋,具體使用還需要看具體的使用場景,所以,聰明的你,告訴我?我們需要無線滾動列表麼?
利用js實現列表向上無限滾動
先來一張效果圖 判斷滾動的距離剛好為一條公告的高度時停掉定時器,隔1s之後重新啟動計時器即可實現公告滾動停留效果 if box.scrolltop 25 0 2000 css 樣式自己調 transdata1 tody table header2 tody table header2 li tody...
使用js實現列表無限迴圈滾動
最近的業務有涉及到需要將列表做成無限迴圈滾動,即第乙個element滾出邊界之後需要自動跳到隊尾,參與下一輪滾動,達到無限滾動的效果。最終實現效果如上圖所示,下面講一下思路。jsv for index in 8 key index class scroll item style styleforma...
我們需要敏捷嗎?
指標敏捷研發 傳統研發 研發模型 迭代 增量 瀑布計畫 隨進度和需求調整 詳細完整的計畫 團隊協作程度 極高一般 人員技能要求 高 幾乎要求全棧 一般變更管理 迭代控制 嚴格遵循流程 文件必要的文件,並不是不需要文件 完整的檔案 測試過程 tdd需求驅動 自動化測試 各個環節 主要是回歸測試 質量保...