Beispiel für die Implementierung einer virtuellen Liste im WeChat Mini-Programm

Beispiel für die Implementierung einer virtuellen Liste im WeChat Mini-Programm

Vorwort

Die meisten Miniprogramme haben eine solche Anforderung. Die Seite hat eine lange Liste und muss beim Scrollen nach unten Hintergrunddaten anfordern. Die Daten werden kontinuierlich gerendert. Wenn die Datenliste lang ist, kommt es zu deutlichen Verzögerungen und auf der Seite blinkt ein weißer Bildschirm.

analysieren

  • Das Anfordern von Hintergrunddaten erfordert ein ständiges Festlegen von Daten und eine kontinuierliche Datenzusammenführung, was im späteren Stadium zu einer übermäßigen Datendarstellung führt.
  • Es müssen viele DOM-Strukturen gerendert werden, und bei jedem Rendering wird ein DOM-Vergleich durchgeführt. Die zugehörigen Diff-Algorithmen sind zeitaufwändig und
  • Es gibt viele DOMs, die viel Speicher beanspruchen, wodurch die Seite einfriert und ein weißer Bildschirm angezeigt wird.

Erste Rendering-Methode

/*
 * @Beschreibung: 
 * @version: 
 * @Autor: shijuwang
 * @Datum: 2021-07-14 16:40:22
 * @LetzteEditoren: shijuwang
 * @LastEditTime: 2021-07-14 17:10:13
 */
//Seitenobjekt
Seite({
  Daten: {
    Liste: [], // alle Daten},
  //Optionen(Objekt)
  onLoad: Funktion (Optionen) {
    dieser.index = 0
    Konstanten arr = [
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },




    ]
    dies.setData({ Liste: arr })
  },

  onReachBottom: Funktion () {
    Konstanten arr = [
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },

    ]
    let { Liste } = diese.Daten
    dies.setData({
      Liste: [...Liste, ...arr]
    })
  },

});


// wxml 
<Klasse anzeigen="Container">
    <Ansicht Klasse="item-list" wx:for="{{list}}">
      <text Klasse="">
          {{item.idx}}
      </text>
    </Ansicht>
</Ansicht>

Bei jedem Berühren des unteren Rands werden die Daten erneut angefordert, das Array zusammengeführt und die setData neu gesetzt. Wenn die Liste zuständig ist, wird ein weißer Bildschirm angezeigt. Die Daten von setData werden jedes Mal größer und größer, was die Kommunikationszeit erhöht und zu viele DOM-Elemente rendert, wie in der folgenden Abbildung dargestellt:

Erste Optimierung

1. Ändern Sie das eindimensionale Array in ein zweidimensionales Array

  • Normalerweise rendert setData alle Daten neu.
  • Paginierte Anfragen belasten den Server relativ weniger, und paginiertes inkrementelles Rendering belastet auch setData weniger.
  • setData sucht nach dem Index der Daten, die dem Index im zweidimensionalen Array entsprechen, und führt mit setData eine teilweise Aktualisierung durch
  • Bei setData werden nur die Daten des aktuellen Bildschirms zugewiesen
// wxml
<Klasse anzeigen="Container">
  <block wx:for="{{list}}" wx:for-index="pageNuma">
    <Ansichtsklasse="Artikelliste" wx:for="{{Artikel}}">
      <text class="">{{item.idx}}</text>
    </Ansicht>
  </block>
</Ansicht>
// wx.js
Seite({
  Daten: {
    Liste: [], // alle Daten},
  //Optionen(Objekt)
  onLoad: Funktion (Optionen) {
    dieser.index = 0;
    this.currentIndex = 0; // Aktuelle Seitenzahl pageNuma
    Konstanten arr = [
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },




    ]
    dies.setData({ [`Liste[${this.currentIndex}]`]: arr })
  },

  onReachBottom: Funktion () {
    this.currentIndex++; // Tiefpunkt +1
    Konstanten arr = [
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },

    ]
    dies.setData({
      [`Liste[${this.currentIndex}]`]: arr
    })
  },
}); 

Auf diese Weise können wir sehen, dass das gesamte Rendering seitenweise basierend auf dem Bildschirm gerendert wird. Wenn mehrere Seitennummern angefordert werden, werden mehrere Bildschirme gerendert und jede Liste wird auf jedem Bildschirm gerendert.

Weitere Optimierung

2 Wir können nur einen Bildschirm des sichtbaren Bereichs rendern oder mehrere Bildschirme in der Nähe des sichtbaren Bereichs rendern und Ansichten verwenden, um andere Bereiche ohne spezifisches Rendering zu belegen, wodurch das DOM-Rendering reduziert und die durch zu viele Knoten verursachten Probleme verringert werden.

Dazu müssen Sie die folgenden Schritte aufteilen:

  • Ermitteln Sie die aktuelle Bildschirmhöhe, ermitteln Sie die Höhe jedes Bildschirms beim Rendern und berechnen Sie die Bildlaufdistanz
  • Speichern Sie alle erhaltenen gerenderten Daten, speichern Sie die Höhe jedes Bildschirms und berechnen Sie über onPageScroll, auf welchem ​​Bildschirm sich der sichtbare Bereich befindet
  • Mit Ausnahme des sichtbaren Bereichs sind die Daten in anderen Bereichen leer und die Ansicht wird verwendet, um den Platz einzunehmen
    is.currentIndex = 0; // Aktuelle Seitenzahl pageNum
    this.pageHeight = []; //Jede Bildschirmhöhe speichern this.allList = []; //Alle Daten abrufen this.systemHeight = 0; //Bildschirmhöhe this.visualIndex = []; //Sichtbaren Bereich speichern pageNum

Tragen Sie beim Aufrufen der Seite die entsprechenden Daten ein:

 // wxml
 <view wx:for="{{list}}" wx:for-index="Seitennummer" id="Artikel{{Seitennummer}}">
    <Ansichtsklasse="Artikelliste" wx:for="{{Artikel}}">
      <text class="">{{item.idx}}</text>
    </Ansicht>
  </Ansicht>
 onLoad: Funktion (Optionen) {
    dieser.index = 0;
    this.currentIndex = 0; // Aktuelle Seitenzahl pageNum
    this.pageHeight = []; // Jede Bildschirmhöhe wird gespeichert this.allList = []; // Alle Daten erhalten this.systemHeight = 0; // Bildschirmhöhe const arr = [
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      },
      {
        idx: dies.index++
      }
    ]
    this.setData({ [`list[${this.currentIndex}]`]: arr }, () => {

      this.setPageHeight();
    });
    dies.getSystemInfo();
  },

Legen Sie den ID-Namen für die Ansicht jedes Bildschirms dynamisch fest, um das Erfassen und Speichern der Höhe jedes Bildschirms während des Renderings zu erleichtern. Verwenden Sie die Schleife pageHeight, um die Höhe für die nachfolgende Platzierung nicht sichtbarer Bereiche festzulegen. Addieren Sie zum Vergleich die Höhe jeder Seite und die aktuelle Scroll-Distanz, um die aktuell gerenderte Seitennummer zu erhalten, und fügen Sie dann die aktuell ausgewählte gerenderte Seitennummer -+1, den vorherigen Bildschirm und den nächsten Bildschirm in das Array ein. Die aktuellen drei Seitendaten werden angezeigt, und die Daten anderer Bildschirme werden für die Platzierung der Ansicht verwendet, und die Höhe ist die gespeicherte Höhe.

   // Berechnung der Scroll-Distanz onPageScroll: throttle(function (e) {
    let pageScrollTop = e[0].scrollTop;  
    lass das = dies;
    // Scrollen, um den aktuellen Seitenbildschirm zu berechnen let scrollTop = 0;
    sei aktuellerIndex = dieser.aktuellerIndex;

    für (var i = 0; i < diese.Seitenhöhe.Länge; i++) {
      scrollTop = scrollTop + diese.Seitenhöhe[i];

      wenn (scrollTop > pageScrollTop + this.systemHeight - 50) {
        dies.aktuellerIndex = i;
        Dies.visualIndex = [i - 1, i, i + 1];
        dass.setData({
          visuellerIndex: dieser.visuellerIndex
        })
        brechen;
      }
    }
  },200)

Echtzeitüberwachung der Scroll- und Drosselungsoptimierung

const Drosselklappe = (fn, Intervall) => {
  var enterTime = 0; //Triggerzeit var gapTime = Intervall || 300; //Intervallzeit, wenn kein Intervall überschritten wird, beträgt der Standardwert 300 ms
  Rückgabefunktion () {
    var das = dies;
    var backTime = new Date(); //Der Zeitpunkt, zu dem die Funktion zum ersten Mal zurückkehrt, wird ausgelöst, wenn (backTime - enterTime > gapTime) {
      fn.call(das, Argumente);
      enterTime = backTime; //Wechsle die Zeit des ersten Triggers, um die Zeit des zweiten Triggers zu speichern}
  };
}

Holen Sie sich das Array des sichtbaren Bereichs und bestimmen Sie dann, ob sich die aktuelle Seitennummer im visuellen Index befindet. Wenn dies der Fall ist, rendern Sie sie. Wenn nicht, nimmt die Ansicht Platz ein und die Höhe wird abgerufen und gespeichert.

<wxs module='filter'>
 var includesList = Funktion(Liste, aktuellerIndex){
   wenn(Liste){
    Rückgabeliste.indexOf(aktuellerIndex) > -1
   }
 }
 module.exports.includesList = enthältListe;
</wxs>
<Klasse anzeigen="Container">
 <view wx:for="{{list}}" wx:for-index="Seitennummer" id="item{{Seitennummer}}" wx:key="Seitennummer">
   <block wx:if="{{filter.includesList(visualIndex,pageNum)}}">
     <Ansichtsklasse="Artikelliste" wx:for="{{Artikel}}">
       <text class="">{{item.idx}}</text>
     </Ansicht>
   </block>
   <block wx:sonst>
     <view class="item-visible" style="height:{{pageHeight[pageNum]}}px"></view>
   </block>
 </Ansicht>
</Ansicht>

Wenn die Seitennummer des Arrays im sichtbaren Bereich nicht im aktuellen Array enthalten ist, wird der Platzhalter für die Höhe gesetzt. Der Rendering-Effekt ist wie folgt:

Diese Methode funktioniert!

Methode 2

Verwenden der WeChat Mini-Programm-API
Kreuzungsbeobachter

  //Monitor anzeigen observePage: function (pageNum) {
    const das = dies;
    const observerView = wx.createIntersectionObserver(this).relativeToViewport({ top: 0, bottom: 0});
    observerView.observe(`#item${pageNum}`, (res) => {
      konsole.log(res,'res');
      wenn (res.intersectionRatio > 0) {
        dass.setData({
          visualIndex: [Seitennummer - 1, Seitennummer, Seitennummer + 1]
        })

      }
    })
  }

Verwenden Sie observe, um zu überwachen, ob sich die aktuelle Seite im sichtbaren Bereich befindet. Wenn ja, setzen Sie die aktuelle Seitennummer -+1 und die Seitennummer in das sichtbare Bereichsarray visualIndex. Verwenden Sie wxs, um zu bestimmen, ob die aktuelle Seitennummer im sichtbaren Bereichsarray vorhanden ist. Wenn ja, rendern Sie sie. Wenn nicht, verwenden Sie view, um den Platz einzunehmen.

Lösung 1: Scrollende Berechnung >>>Codeausschnitt: (scrollende virtuelle Liste)

Lösung 2 IntersectionObserver API >>> Codeausschnitt: intersectionObserver

Dies ist das Ende dieses Artikels über das Implementierungsbeispiel der virtuellen Liste des WeChat-Miniprogramms. Weitere relevante Inhalte zur virtuellen Liste des Miniprogramms finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • Anwendungsbeispiele für die virtuelle Liste des WeChat-Applets

<<:  So verwenden Sie Port 80 in Tomcat unter Linux

>>:  Implementierungscode zur Installation von vsftpd in Ubuntu 18.04

Artikel empfehlen

Detaillierte Erklärung des Responsive-Prinzips von Vue3

Inhaltsverzeichnis Überprüfung der responsiven Pr...

Detaillierter Installationsprozess von mysql5.7.21 unter Win10

In diesem Artikel erfahren Sie mehr über die Inst...

Mysql Master-Slave-Synchronisation Last_IO_Errno:1236 Fehlerlösung

Was ist der Grund für den Fehler Last_IO_Errno:12...

Einigen Eigenschaften in CSS geht ein "*" oder "_" voraus.

Einigen Eigenschaften in CSS geht ein "*&quo...

Auszeichnungssprache - Titel

Klicken Sie hier, um zum Abschnitt „HTML-Tutorial“...

Ein Artikel zeigt Ihnen, wie Sie den Watch-Listener von Vue verwenden

Inhaltsverzeichnis Hörer beobachten Format Richte...

Detaillierte Erläuterung des CocosCreator-Projektstrukturmechanismus

Inhaltsverzeichnis 1. Projektordnerstruktur 1. As...

Einführung, Installation und Verwendung von Hyper-V (detaillierte Abbildungen)

Vorwort: Als Gigant in der IT-Branche ist Microso...

Implementierungsideen für die Synchronisierung von Docker-Registry-Images

Einleitung Bisher wurden unsere Docker-Images in ...

Miniprogramm zur Implementierung einer einfachen Listenfunktion

In diesem Artikelbeispiel wird der spezifische Co...

MySQL und MySQL Workbench Installations-Tutorial unter Ubuntu

Ubuntu-JDK installieren: [Link] Installieren Sie ...

Detaillierte Erklärung zum Bereitstellen von H5-Spielen auf einem Nginx-Server

Auf dem Weg zur selbstlernenden Spieleentwicklung...

So verwenden Sie MySQL zur Abdeckung von Index- und Tabellenrückgabe

Zwei Hauptkategorien von Indizes Verwendete Speic...