長列表優化之滾動替換資料方案小記
最近專案中要用到比較長的列表,在瀏覽器中開啟渲染時比較慢,並佔用了較多記憶體,於是就同事就建議儘量減少節點,在滾動時只是替換資料,於是就決定試試這種方法。
首先要做的就是新增拖動滾動條時的事件,另外由於UE要求對滾動條進行美化,於是就選用了jscrollpane這個jQuery滾動條外掛,主頁是:http://jscrollpane.kelvinluck.com/
基本要求是表頭固定,內容可滾動,滾動時只是替換資料,不增減節點。由於要出現滾動條,所以要新增一個空的節點來佔位,所以DEMO的HTML結構如下:
<h3>DEMO</h3> <div class="bookList"> <table class="bookList_head"> <thead> <tr> <th class="book_title">Title</th> <th class="book_time">Time</th> <th class="book_author">Author</th> <th class="book_prize">Prize</th> </tr> </thead> </table> <div class="scroll-pane"> <div id="emptyContainer" class="emptyContainer"></div> <table class="bookList_body"> <tbody id="bookContent"> </tbody> </table> </div> </div>
然後要做的就是用測試資料填充列表,並給佔位節點設定高度,JS程式碼如下:
var bookData = [], bookMap = [], bookCount = 1000, showCount = 10, bookListBodyNode = $(".bookList_body"), bookContentNode = $("#bookContent"), itemHeight = 0, oFragment = document.createDocumentFragment(); var emptyContainerNode = $("#emptyContainer"); for(var i=0;i<bookCount;i++){ bookData.push({ "title":"JavaScript高階程式設計第"+(i+1)+"版", "time":"2013-1-27", "author":"佚名"+i, "prize":(i%50+1)+".00" }); } for(i=0;i<showCount;i++){ var bookItem = $("<tr></tr>"), bookItem_title = $("<td class="book_title">" + bookData[i].title + "</td>"), bookItem_time = $("<td class="book_time">" + bookData[i].time + "</td>"), bookItem_author = $("<td class="book_author">" + bookData[i].author + "</td>"), bookItem_prize = $("<td class="book_prize">" + bookData[i].prize + "</td>"); bookItem.append(bookItem_title) .append(bookItem_time) .append(bookItem_author) .append(bookItem_prize); bookMap[i] = bookItem; oFragment.appendChild(bookItem[0]); } bookContentNode[0].appendChild(oFragment); itemHeight = parseInt(bookMap[0].height()); emptyContainerNode.css("height", bookCount * itemHeight);
下一步就是給class為scroll-pane的節點應用jScrollPane外掛新增滾動條,同是要新增滾動條滾動時的事件,程式碼如下:
$(`.scroll-pane`).bind(`jsp-scroll-y`,function(event, scrollPositionY, isAtTop, isAtBottom){ bookListBodyNode.css("top",scrollPositionY); replaceBooklistData(scrollPositionY); } ).jScrollPane(); function replaceBooklistData(scrollPositionY){ var beginIndex = Math.round(scrollPositionY / itemHeight); for(var i=0;i<showCount;i++){ var bookItem = bookMap[i], bookItem_title = bookItem.find(".book_title"), bookItem_time = bookItem.find(".book_time"), bookItem_author = bookItem.find(".book_author"), bookItem_prize = bookItem.find(".book_prize"); bookItem_title.html(bookData[i+beginIndex].title); bookItem_time.html(bookData[i+beginIndex].time); bookItem_author.html(bookData[i+beginIndex].author); bookItem_prize.html(bookData[i+beginIndex].prize); } }
最後還要引入一個滑鼠滾動時的外掛mousewheel,全部程式碼如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Table Body Scroll Demo</title> <link type="text/css" href="style/jquery.jscrollpane.css" rel="stylesheet" media="all" /> <link type="text/css" href="style/demo.css" rel="stylesheet" media="all" /> <script type="text/javascript" src="script/jquery.js"></script> <script type="text/javascript" src="script/jquery.mousewheel.js"></script> <script type="text/javascript" src="script/jquery.jscrollpane.min.js"></script> </head> <body> <h3>DEMO</h3> <div class="bookList"> <table class="bookList_head"> <thead> <tr> <th class="book_title">Title</th> <th class="book_time">Time</th> <th class="book_author">Author</th> <th class="book_prize">Prize</th> </tr> </thead> </table> <div class="scroll-pane"> <div id="emptyContainer" class="emptyContainer"></div> <table class="bookList_body"> <tbody id="bookContent"> </tbody> </table> </div> </div> <script type="text/javascript" id="sourcecode"> var bookData = [], bookMap = [], bookCount = 1000, showCount = 10, bookListBodyNode = $(".bookList_body"), bookContentNode = $("#bookContent"), itemHeight = 0, oFragment = document.createDocumentFragment(); $(function(){ $(`.scroll-pane`).bind(`jsp-scroll-y`, function(event, scrollPositionY, isAtTop, isAtBottom){ bookListBodyNode.css("top",scrollPositionY); replaceBooklistData(scrollPositionY); } ).jScrollPane(); }); loadData(); function replaceBooklistData(scrollPositionY){ var beginIndex = Math.round(scrollPositionY / itemHeight); for(var i=0;i<showCount;i++){ var bookItem = bookMap[i], bookItem_title = bookItem.find(".book_title"), bookItem_time = bookItem.find(".book_time"), bookItem_author = bookItem.find(".book_author"), bookItem_prize = bookItem.find(".book_prize"); bookItem_title.html(bookData[i+beginIndex].title); bookItem_time.html(bookData[i+beginIndex].time); bookItem_author.html(bookData[i+beginIndex].author); bookItem_prize.html(bookData[i+beginIndex].prize); } } function loadData(){ var emptyContainerNode = $("#emptyContainer"); for(var i=0;i<bookCount;i++){ bookData.push({ "title":"JavaScript高階程式設計第"+(i+1)+"版", "time":"2013-1-27", "author":"佚名"+i, "prize":(i%50+1)+".00" }); } for(i=0;i<showCount;i++){ var bookItem = $("<tr></tr>"), bookItem_title = $("<td class="book_title">" + bookData[i].title + "</td>"), bookItem_time = $("<td class="book_time">" + bookData[i].time + "</td>"), bookItem_author = $("<td class="book_author">" + bookData[i].author + "</td>"), bookItem_prize = $("<td class="book_prize">" + bookData[i].prize + "</td>"); bookItem.append(bookItem_title) .append(bookItem_time) .append(bookItem_author) .append(bookItem_prize); bookMap[i] = bookItem; oFragment.appendChild(bookItem[0]); } bookContentNode[0].appendChild(oFragment); itemHeight = parseInt(bookMap[0].height()) || 34;//FOR IE7 emptyContainerNode.css("height", bookCount * itemHeight); } </script> </body> </html>
程式碼中的CSS(除了demo.css)和JS都可以在這裡找到:https://github.com/vitch/jScrollPane
demo.css程式碼如下:
.bookList{ width:520px; height:364px; } .scroll-pane { height:330px; overflow: auto; } .bookList .bookList_head,.bookList .bookList_body{ width:100%; border-collapse:collapse; } .bookList .bookList_body{ z-index:999; position:absolute; top:0; left:0; } .bookList .bookList_head thead{ background-color:#F2F4F6; } .bookList th,.bookList td{ padding:8px 0px 8px 5px; text-align:left; border-bottom:1px solid #CCC; font-size:14px; } .bookList .bookList_body tr:nth-child(even){ background-color:#F0F0F0; } .bookList .bookList_body tr:hover{ background-color:#CCC; } .book_title{ width:250px; } .book_time{ width:100px; } .book_author{ width:80px; } .book_prize{ } .emptyContainer{ width:100%; z-index:-1; }
初步測試,在IE6/7/8/9、chrome、firefox下均正常顯示,如果大家有更好方案,歡迎分享。
本文轉自Artwl部落格園部落格,原文連結:http://www.cnblogs.com/artwl/,如需轉載請自行聯絡原作者
相關文章
- react長列表優化方案: react-virtualizedReact優化Zed
- 效能優化 (八) APK 加固之動態替換 Application優化APKAPP
- 滾動優化(無限滾動載入、滾動元素內有大量dom,造成卡頓問題的優化方案)優化
- 介面自動化之引數動態生成替換
- sql 優化過程之union 替換 orSQL優化
- 資料庫SQL優化大總結之 百萬級資料庫優化方案資料庫SQL優化
- 資料庫SQL優化大總結之百萬級資料庫優化方案資料庫SQL優化
- [vue] 大資料最佳化之虛擬滾動Vue大資料
- 記一次列表載入超一萬條資料優化優化
- 後端思維之資料庫效能優化方案後端資料庫優化
- TableView 優化之資料模型優化View優化模型
- 資料庫優化小計資料庫優化
- 效能優化小冊 - 渲染十萬條資料:基於 IntersectionObserver 的虛擬列表優化Server
- 【資料庫訪問優化方案之讀寫分離】資料庫優化
- Bootstrap列表新增滾動條boot
- 記一次資料庫的優化之隱式轉換的破壞力資料庫優化
- 微信小程式-uniapp-切換tab時資料列表如何切換?微信小程式APP
- 微信小程式效能優化方案微信小程式優化
- iOS效能優化系列篇之“列表流暢度優化”iOS優化
- 資料庫優化之臨時表優化資料庫優化
- 在React專案中,如何優雅的優化長列表React優化
- 微信小程式之文字向上滾動效果微信小程式
- 【SQL優化】UNION替換OR效率測試及總結SQL優化
- Redis 記憶體優化神技,小記憶體儲存大資料Redis記憶體優化大資料
- JavaScript資料訪問效能優化方案JavaScript優化
- 經營分析資料庫優化方案資料庫優化
- 資料庫升級之-Dataguard滾動升級資料庫
- Android 列表視訊的全屏、自動小視窗優化實踐Android優化
- 資料庫效能優化之SQL語句優化資料庫優化SQL
- [分享]iOS開發 - iOS自動佈局的替換方案iOS
- 大型ORACLE資料庫優化設計方案Oracle資料庫優化
- React效能優化方案之PureRenderMixinReact優化
- 仿網易LOFTER視差滾動列表
- vue單頁應用中 返回列表記住上次滾動位置、keep-alive快取之後更新列表資料 那點事VueKeep-Alive快取
- 淘寶小程式體驗優化:資料分析和優化實踐優化
- 介面自動化測試-apiAutoTest 優化之資料依賴處理API優化
- 列表元件抽象(4):滾動列表及分頁說明元件抽象
- iOS 中關於列表滾動流暢方案的一些探討iOS