• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Vanilla JS vs Vue - wydajność generowania danych

VPS Starter Arubacloud
+1 głos
244 wizyt
pytanie zadane 17 września 2022 w JavaScript przez kordix Gaduła (3,910 p.)

Witam.

Mam przykład kodu który działa o niebo lepiej we vue js. Mocno mnie to zdziwiło, bo bylem pewny że kod w Vanilli nie będzie zamulać a jak już to będzie działać szybciej


let dane = jakasgrubatablicazdanymi;

  for (let i = 0; i < dane.length ; i++) {
        let elem = dane[i];
        document.querySelector('#tablebody').innerHTML += `<tr><td>${elem.id}</td> <td>${elem.date}</td> <td>${elem.nr}</td><tr>`;
   }

To generuje się holernie długo.

A teraz we vue:

        <tbody id="tablebody">
                <tr v-for="elem in cruddata">
                    <td>{{elem.id}}</td>
                    <td>{{elem.date}}</td>
                    <td>{{elem.nr}}</td>
                </tr>
            </tbody>

...

 mounted(){
        let self = this;
       fetch('/api/dane.php').then(res => res.json()).then((res) => self.cruddata = res)
    }

Zaznaczam - nie chodzi tu o długie pobieranie się danych z serwera przy fetch - dla przykładu z Vanillą ściągnąłem tablicę lokalnie do pliku , przykład we Vue śmiga mimo tego że pobiera dane z serwera.

 

document.querySelector('#tablebody').innerHTML +=

To może da się zrobić w mądrzejszy sposób?

2 odpowiedzi

+6 głosów
odpowiedź 17 września 2022 przez Comandeer Guru (599,730 p.)
edycja 17 września 2022 przez Comandeer

Vanilla nie oznacza automatycznie, że kod będzie szybszy. Frameworki mają wewnątrz siebie wiele zmyślnych technik optymalizacyjnych. Jedną z nich jest choćby dzielenie pracy na kilka części, by zmieścić się w jednej ramce. Zakłada się wówczas, że strona powinna działać w 60fps, co daje nam ok. 16ms na operacje. Jeśli framework widzi, że nie jest w stanie w tym czasie wszystkiego zrobić, dzieli prace na kawałki. W Reakcie jest za to odpowiedzialny Fiber, w Vue zapewne jest podobny mechanizm. Dodatkowo frameworki wykorzystują tzw. virtual DOM, czyli swoją wewnętrzną strukturę podobną do DOM, na której śledzą wszystkie zmiany zachodzące w prawdziwym DOM. Dzięki temu mogą obliczyć, w jaki sposób przejść od stanu A (np. strona z pustą listą dostępnych wydarzeń w okolicy) do stanu B (strona z wczytaną listą wydarzeń) w jak najmniejszej liczbie kroków. Dzięki połączeniu tych technik frameworki są w stanie dość wydajnie dokonywać nawet dużych zmian na stronach. Oczywiście coś za coś – czas samego wczytania strony się przez to wydłuża (frameworki swoje ważą) + zużycie pamięci jest wyższe.

W przypadku Vanilla tego typu optymalizacje trzeba robić samemu. Jedną z podstawowych zasad jest unikanie DOM-u tak długo, jak tylko się da. W Twoim kodzie odwołujesz się do DOM-u w pętli i, co gorsze, robisz to przy użyciu innerHTML. To sprawia, że za każdym przelotem pętli tak naprawdę nadpisujesz cały element #tablebody, co wymusza jego przerenderowanie przez przeglądarkę. Powinieneś stworzyć cały kod HTML jako po prostu string i dopiero na samym końcu wsadzić go do elementu:

let dane = jakasgrubatablicazdanymi;
let html = '';
 
for (let i = 0; i < dane.length ; i++) {
	let elem = dane[i];

	html += `<tr><td>${elem.id}</td> <td>${elem.date}</td> <td>${elem.nr}</td></tr>`;
}

document.querySelector('#tablebody').innerHTML = html;

Dzięki temu przerenderowanie elementu nastąpi tylko raz.

Istnieją też bardziej skomplikowane techniki optymalizacyjne, które można stosować przy vanilla JS, a które w dużej mierze sprowadzają się do wstrzelenia się z przerenderowaniem w odpowiedni moment. Niemniej samo ograniczenie operacji na DOM-ie powinno dać porządnego kopa, zwłaszcza w przypadku dużej liczby tych operacji.

+2 głosów
odpowiedź 17 września 2022 przez VBService Ekspert (251,210 p.)
edycja 17 września 2022 przez VBService
  • Niepotrzebne utworzenie zmiennej elem
    let elem = dane[i];
  • Spróbuj konkatenacji string-ów za pomocą += (lub tablicy) niż za pomocą backtick-ów 
    `<tr><td>${elem.id}</td> <td>${elem.date}</td> <td>${elem.nr}</td><tr>`
  • Przypisanie do DOM wygenerowanych danych poza pętlą
    for (let i=0; i<dane.length; i++) {
        let elem = dane[i];
        document.querySelector('#tablebody').innerHTML += ...;
    }

     

no i nie domknięty tag <tr> :
`<tr><td>${elem.id}</td> <td>${elem.date}</td> <td>${elem.nr}</td></tr>`

 

Sprawdź np.

const dane = jakasgrubatablicazdanymi;
let table = '';

for (let i=0; i<dane.length; i++)
  table += '<tr><td>'+dane[i].id+'</td><td>'+dane[i].date+'</td><td>'+dane[i].nr+'</td></tr>';

document.querySelector('#tablebody').innerHTML = table;

lub

const dane = jakasgrubatablicazdanymi;
let table = '';

for (const elem of dane)
  table += '<tr><td>'+elem.id+'</td><td>'+elem.date+'</td><td>'+elem.nr+'</td></tr>';

document.querySelector('#tablebody').innerHTML = table;

lub

const dane = jakasgrubatablicazdanymi,
      table = [];

for (const elem of dane)
  table.push('<td>'+elem.id+'</td><td>'+elem.date+'</td><td>'+elem.nr+'</td>');

document.querySelector('#tablebody').innerHTML = '<tr>'+table.join('</tr><tr>')+'</tr>';

przy wykorzystaniu tablicy w łatwy sposób można "dokonać" paginacji danych w przypadku "długiej" tabeli z danymi. smiley

Podobne pytania

0 głosów
1 odpowiedź 535 wizyt
pytanie zadane 23 maja 2018 w JavaScript przez Łucja Nowicjusz (120 p.)
0 głosów
3 odpowiedzi 287 wizyt
pytanie zadane 25 września 2022 w JavaScript przez Pawel82 Użytkownik (740 p.)
0 głosów
1 odpowiedź 188 wizyt
pytanie zadane 29 sierpnia 2019 w JavaScript przez Majonez.exe Gaduła (3,490 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...