欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    某天閑著無聊想練一下手速,去上拉一個小程序項目中一個有1萬多條商品數據的列表。在數據加載到1000多條后,是列表居然出現了白屏。看了一下控制臺:

    圖一

    ‘Dom limit ’,dom數超出了限制, 不知道微信是出于什么考慮,要限制頁面的dom數量。

    一.小程序頁面限制多少個wxml節點

    寫了個小dome做了個測試。的數據結構為:

    listData:[
    ???{
    ????isDisplay:true,
    ????itemList:[{
    ??????????qus:'下面哪位是劉發財女朋友?',
    ??????????answerA:'劉亦菲',
    ??????????answerB:'迪麗熱巴',
    ??????????answerC:'齋藤飛鳥',
    ??????????answerD:'花澤香菜',
    ???????}
    ??????.......//20條數據
    ?????]
    ???}]

    頁面渲染效果:

    圖二1.dome1

    <view?wx:for="{{listData}}"?class="first-item"??wx:for-index="i"?wx:for-item="firstItem"?wx:key="i"?wx:if="{{firstItem.isDisplay}}">
    ?????<view?class="item-list"?wx:for="{{firstItem.itemList}}"?wx:key="index">
    ?????????<view>{{item.qus}}view>
    ?????????<view?class="answer-list">
    ??????????????<view>A.?<text>{{item.answerA}}text>view>
    ??????????????<view>B.?<text>{{item.answerB}}text>view>
    ??????????????<view>C.?<text>{{item.answerC}}text>view>
    ??????????????<view>D.?<text>{{item.answerD}}text>view>
    ?????????view>
    ????view>???????
    view>
    復制代碼

    圖三 運行結果:渲染了72*20條數據2.dome2小程序帶參數分享,刪除了不必要的dom嵌套

    小程序自定義分享按鈕_微信小程序分享_小程序帶參數分享

    <view?wx:for="{{listData}}"?class="first-item"??wx:for-index="i"?wx:for-item="firstItem"?wx:key="i"?wx:if="{{firstItem.isDisplay}}">
    ?????<view?class="item-list"?wx:for="{{firstItem.itemList}}"?wx:key="index">
    ?????????<view>{{item.qus}}view>
    ?????????<view?class="answer-list">
    ??????????????<view>A.?{{item.answerA}}view>
    ??????????????<view>B.?{{item.answerB}}view>
    ??????????????<view>C.?{{item.answerC}}view>
    ??????????????<view>D.?{{item.answerD}}view>
    ?????????view>
    ????view>???????
    view>
    復制代碼

    圖四 運行結果:渲染了113*20條數據

    通過大致計算,一個小程序頁面大概可以渲染2萬個wxml節點而小程序官方的性能測評得分條件為少于1000個wxml節點[官方鏈接](#5. 數據大小)

    圖五 小程序性能評分二.列表頁面優化1.減少不必要的標簽嵌套

    由上面的測試dome可知,在不影響代碼運行和可讀性的前提下,盡量減少標簽的嵌套,可以大幅的增加頁面數據的列表條數,畢竟公司不是按代碼行數發工資的。如果你的列表數據量有限,可以用這種方法來增加列表渲染條數。如果數據量很大,再怎么精簡也超過2萬的節點,這個方法則不適用。

    2.優化的使用

    如圖五所示,小程序的性能會受到數據量大小和調用頻率限制。所以要圍繞減少每一次數據量大小,降低調用頻率進行優化。#####(1)刪除冗余字段 后端的同事經常把數據從數據庫中取出就直接返回給前端,不經過任何處理,所以會導致數據大量的冗余,很多字段根本用不到,我們需要把這些字段刪除,減少的數據大小。#####(2)的進階用法 通常,我們對data中數據的增刪改操作,是把原來的數據取出,處理,然后用整體去更新,比如我們列表中使用到的上拉加載更多,需要往尾部添加數據:

    ????newList=[{...},{...}];
    ???this.setData({
    ?????listData:[...this.data.listData,...newList]
    ???})
    復制代碼

    這樣會導致的數據量越來越大,頁面也越來越卡。

    的正確使用姿勢

    比如我們要修改數組第一個元素的屬性,我們可以這樣操作:

    小程序自定義分享按鈕_微信小程序分享_小程序帶參數分享

    ??let?index=0;
    ??this.setData({
    ?????[`listData[${index}].isDisplay`]:false,
    ??})
    復制代碼

    如果我們想同時修改數組中下標從0到9的元素的屬性,那要如何處理呢?你可能會想到用for循環來執行:

    ??for(let?index=0;index<10;index++){
    ?????this.setData({
    ????????[`listData[${index}].isDisplay`]:false,
    ?????})
    ??}

    那么這樣就會導致另外一個問題,那就是的調用過于頻繁,也會導致性能問題,正確的處理方式是先把要修改的數據先收集起來,然后調用一次處理完成:

    ??let?changeData={};
    ??for(let?index=0;index<10;index++){
    ??????changeData[[`listData[${index}].isDisplay`]]=false;
    ??}
    ??this.setData(changeData);

    這樣我們就把數組中下標從0到9的元素的屬性改成了false。

    如果只添加一條數據

    ??let?newData={...};
    ??this.setData({
    ????[`listData[${this.data.listData.length}]`]:newData
    ??})

    如果是添加多條數據

    ??let?newData=[{...},{...},{...},{...},{...},{...}];
    ??let?changeData={};
    ??let?index=this.data.listData.length
    ????newData.forEach((item)?=>?{
    ????????newData['listData['?+?(index++)?+?']']?=?item?//賦值,索引遞增
    ????})?
    ??this.setData(changeData)

    至于刪除操作,還沒有找到更好的方法,不知道大家有什么方法可以分享嗎?

    三.使用自定義組件

    可以把列表的一行或者多行封裝到自定義組件里,在列表頁使用一個組件,只算一個節點,這樣你的列表能渲染的數據可以成倍數的增加。組件內的節點數也是有限制的,但是你可以一層層嵌套組件實現列表的無限加載,如果你不怕麻煩的話

    小程序帶參數分享_小程序自定義分享按鈕_微信小程序分享

    四.使用虛擬列表

    經過上面的一系列操作后,列表的性能會得到很大的提升,但是如果數據量實在太大,wxml節點數也會超出限制,導致頁面發生錯誤。我們的處理方法是使用虛擬列表,頁面只渲染當前可視區域以及可視區域上下若干條數據的節點,通過控制節點的渲染。

    圖六 節點渲染示意圖1.數組的結構

    使用二維數組,因為如果是一維數組,頁面滾動需要用設置大量的元素屬性來控制列表的的渲染。而二維數組可以這可以一次調用控制十條,二十條甚至更多的數據的渲染。

    listData:[
    ???{
    ????isDisplay:true,
    ????itemList:[{
    ??????????qus:'下面哪位是劉發財女朋友?',
    ??????????answerA:'劉亦菲',
    ??????????answerB:'迪麗熱巴',
    ??????????answerC:'齋藤飛鳥',
    ??????????answerD:'花澤香菜',
    ???????}
    ??????.......//二維數組中的條數根據項目實際情況
    ?????]
    ???}]

    2.必要的參數

    ???data{
    ???????itemHeight:4520,//列表第一層dom高度,單位為rpx
    ???????itemPxHeight:'',//轉化為px高度,因為小程序獲取的滾動條高度單位為px
    ???????aboveShowIndex:0,//已渲染數據的第一條的Index
    ???????belowShowNum:0,//顯示區域下方隱藏的條數
    ???????oldSrollTop:0,//記錄上一次滾動的滾動條高度,判斷滾動方向
    ???????prepareNum:5,//可視區域上下方要渲染的數量
    ???????throttleTime:200//滾動事件節流的時間,單位ms
    ???}

    3.wxml的dom結構

    ????
    ????<view?class="above-box"?style="height:{{aboveShowIndex*itemHeight}}rpx">?view>
    ???
    ????<view?wx:for="{{listData}}"?class="first-item"??wx:for-index="i"?wx:for-item="firstItem"?wx:key="i"?wx:if="{{firstItem.isDisplay}}">
    ????????<view?class="item-list"?wx:for="{{firstItem.itemList}}"?wx:key="index">
    ???????????<view>{{item.qus}}view>
    ???????????<view?class="answer-list">
    ????????????????<view>A.?{{item.answerA}}view>
    ????????????????<view>B.?{{item.answerB}}view>
    ????????????????<view>C.?{{item.answerC}}view>
    ????????????????<view>D.?{{item.answerD}}view>
    ???????????view>
    ????????view>???
    ????view>
    ????
    ????<view??class="below-box"?style="height:{{belowShowNum*itemHeight}}rpx">?view>

    4.獲取列表第一層dom的px高度

    ??let?query?=?wx.createSelectorQuery();
    ??query.select('.content').boundingClientRect(rect=>{
    ????let?clientWidth?=?rect.width;
    ????let?ratio?=?750?/?clientWidth;
    ????this.setData({
    ??????itemPxHeight:Math.floor(this.data.itemHeight/ratio),
    ?????})
    ???}).exec();

    5.頁面滾動時間節流

    微信小程序分享_小程序帶參數分享_小程序自定義分享按鈕

    function?throttle(fn){
    ??let?valid?=?true
    ??return?function()?{
    ?????if(!valid){
    ?????????return?false?
    ?????}
    ?????//?工作時間,執行函數并且在間隔期內把狀態位設為無效
    ??????valid?=?false
    ??????setTimeout(()?=>?{
    ??????????fn.call(this,arguments);
    ??????????valid?=?true;
    ??????},?this.data.throttleTime)
    ??}
    }

    6.頁面滾動事件處理

    ???onPageScroll:throttle(function(e){
    ????let?scrollTop=e[0].scrollTop;//滾動條高度
    ????let?itemNum=Math.floor(scrollTop/this.data.itemPxHeight);//計算出可視區域的數據Index
    ????let?clearindex=itemNum-this.data.prepareNum+1;//滑動后需要渲染數據第一條的index
    ????let?oldSrollTop=this.data.oldSrollTop;//滾動前的scrotop,用于判斷滾動的方向
    ????let?aboveShowIndex=this.data.aboveShowIndex;//獲取已渲染數據第一條的index
    ????let?listDataLen=this.data.listData.length;
    ????let?changeData={}
    ??//向下滾動
    ????if(scrollTop-oldSrollTop>0){
    ????????if(clearindex>0){
    ?????????//滾動后需要變更的條數
    ??????????for(let?i=aboveShowIndex;i????????????????changeData[[`listData[${i}].isDisplay`]]=false;
    ????????????????let?belowShowIndex=i+2*this.data.prepareNum;
    ????????????????if(i+2*this.data.prepareNum??????????????????changeData[[`listData[${belowShowIndex}].isDisplay`]]=true;
    ?????????????????}
    ??????????}???
    ????????}????
    ????}else{//向上滾動
    ????????if(clearindex>=0){
    ?????????let?changeData={}
    ?????????for(let?i=aboveShowIndex-1;i>=clearindex;i--){
    ???????????let?belowShowIndex=i+2*this.data.prepareNum
    ???????????if(i+2*this.data.prepareNum<=listDataLen-1){
    ????????????changeData[[`listData[${belowShowIndex}].isDisplay`]]=false;
    ???????????}
    ???????????changeData[[`listData[${i}].isDisplay`]]=true;
    ?????????}??
    ????????}else{
    ??????????if(aboveShowIndex>0){
    ????????????for(let?i=0;i??????????????this.setData({
    ????????????????[`listData[${i}].isDisplay`]:true,
    ??????????????})
    ????????????}
    ??????????}
    ????????}??????
    ????}
    ????clearindex=clearindex>0?clearindex:0
    ????if(clearindex>=0&&!(clearindex>0&&clearindex==this.data.aboveShowIndex)){
    ??????changeData.aboveShowIndex=clearindex;
    ??????let?belowShowNum=this.data.listData.length-(2*this.data.prepareNum+clearindex)
    ??????belowShowNum=belowShowNum>0?belowShowNum:0
    ??????if(belowShowNum>=0){
    ????????changeData.belowShowNum=belowShowNum
    ??????}
    ??????this.setData(changeData)
    ????}
    ????this.setData({
    ??????oldSrollTop:scrollTop
    ????})
    ??}),

    經過上面的處理后,頁面的wxml節點數量相對穩定,可能因為可視區域數據的index計算誤差,頁面渲染的數據有小幅度的浮動,但是已經完全不會超過小程序頁面的節點數量的限制。理論上100萬條數據的列表也不會有問題,只要你有耐心和精力一直劃列表加載這么多數據。

    7.待優化事項五.使用自定義組件和虛擬列表的對比。

    雖然不知道為什么,但是直覺告訴我使用自定義組件性能會相對差一點。為了對比兩種方法的優劣,使用了Trace工具對一個5000條帶圖片數據進行了性能測試。

    內存占用對比:

    自定義組件內存占用情況:

    圖七 自定義組件內存占用情況

    虛擬列表內存占用情況:

    圖八 虛擬列表內存占用情況

    微信小程序分享_小程序自定義分享按鈕_小程序帶參數分享

    對比可以看出,因為組件在上拉加載時,組件是沒有銷毀的小程序帶參數分享,導致數據量逐漸增多。而虛擬列表在增加數據的同時,也會銷毀相同數量的數據,所以內存占比會穩定在一個數量。具體到這個測試dome,5000條數據使用自定義組件,最后占用的內存,而虛擬列表穩定在700MB。

    后重新渲染所用的時間對比:

    自定義組件重新渲染耗時:

    圖九 自定義組件重新渲染耗時

    虛擬列表重新渲染耗時:

    圖十 虛擬列表重新渲染耗時

    從測試結果可以看出,無論是耗時的次數分布,還是最大耗時,最小耗時,虛擬列表都優于自定義組件

    最后附上虛擬列表的地址,如果對您有幫助,記得給個小星星哦

    如果覺得這篇文章還不錯點擊下面卡片關注我來個【分享、點贊、在看】三連支持一下吧

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有