2016-12-23 4 views
5

Używam Aurelii na co dzień. Niedawno pracowałem nad wykorzystaniem Redux (tj. Zbudowałem kilka małych aplikacji próbnych z wykorzystaniem Aurelia + Redux) i byłem naprawdę pod wrażeniem (moja praca nad rozwojem i jasność rozumowania na temat mojej aplikacji uległa znacznej poprawie). Zdecydowałem, że chciałbym rozpocząć pracę nad aplikacjami w realnym świecie.Aurelia + Redux performance

Powiedziawszy to, mam obawy dotyczące wydajności (rozejrzałem się po postach dotyczących wydajności, ale nie widziałem bezpośrednio adresu mojego problemu). Myślę, że to pytanie nie jest specyficzne dla Aurelii, bardziej pytanie o Redux i używanie go z bibliotekami, które nie reagują.

Pozwól mi przedłożyć moje pytanie z moim zrozumieniem Redux (być może moje pytanie naprawdę wynika z błędnego zrozumienia?). Zasadniczo sposób, w jaki rozumiem Redux jest to, że istnieje sklep (obiekt javascript) i funkcja redukująca. Teraz funkcja redukująca może być zdefiniowana jako drzewo funkcji (każda odpowiedzialna za modyfikację określonej gałęzi całego magazynu), jednak w rzeczywistości Redux otrzymuje pojedynczą funkcję redukującą (nie ma możliwości dowiedzenia się, ile funkcji zostało złożonych aby utworzyć tę pojedynczą funkcję).

Sposób używam Redux jest jak SO (tylko przykład):

@inject(Store) 
export class TodosListCustomElement { 
    constructor(store) { 
     this.store = store; 
    } 

    activate() { 
     this.update(); 
     this.unsubcribe = this.store.subscribe(this.update.bind(this)); 
    } 

    deactivate() { 
     this.unsubcribe(); 
    } 

    update() { 
     const newState = this.store.getState(); 

     this.todos = newState.todos; 
    } 

    toggleCompleted(index) { 
     this.store.dispatch({ 
      type: UPDATE_TODO, 
      payload: { 
       index, 
       values: { 
        isCompleted: !this.todos[index].isCompleted 
       } 
      } 
     }); 
    } 
} 

Zasadniczo, każdy składnik w dół drzewa komponentów, zgadza się, aby zapisać zmiany i odświeża dane, które musi ze sklepu.

Moją obawą jest to, że wydaje się, że wiele się dzieje na każdej opublikowanej akcji. Załóżmy na przykład, że mam dużą aplikację z podobnie dużym drzewem magazynu i reduktora. Załóżmy, że istnieje pewne ograniczone pole tekstowe, które wywołuje zmiany w jednym polu tekstowym (w jednym elemencie listy) w magazynie co 250 ms. Oznaczałoby to, że gdy użytkownik wpisze, cała funkcja reduktora jest wykonywana co 250 ms (co może oznaczać wykonanie dość dużej liczby jego potomnych reduktorów), jak również wszystkie funkcje subskrypcji są również wykonywane. Zasadniczo wydaje się, że istnieje wiele kosztów, aby zmienić nawet najmniejszą część sklepu.

Kontrast to z wiążącej (Aurelia) w standardzie, gdzie istnieje tylko jedna granica funkcji (mutacja obserwator), który musi wykonać co 250ms do aktualizacji modelu ...

Ponieważ jestem nowy na Redux, Sądzę, że istnieje duża szansa, że ​​jestem naiwnie nieporozumieniem itp. Przepraszam z góry i mam nadzieję, że będę poprawiony/postawiony na właściwej ścieżce (ponieważ moje ograniczone doświadczenie z wykorzystaniem Redux było bardzo przyjemne).

góry dzięki

Odpowiedz

3

Ty rzeczywiście opisując sytuację całkiem dobrze na wielu poziomach.

Po pierwsze, wiązania React-Redux wykonują wiele pracy, aby upewnić się, że połączone komponenty rzeczywiście ponownie się renderują, gdy niektóre dane dotyczące danego komponentu uległy zmianie. Odbywa się to poprzez podłączenie zasilania komponentu do funkcji o nazwie mapStateToProps, która pobiera dane, które komponent chce ze stanu magazynu. Elementy opakowania generowane przez connect ponownie wykonają funkcje mapState po każdej wysyłce i wykonają płytkie porównania między ostatnimi zwróconymi wartościami i poprzednimi zwracanymi wartościami, aby zobaczyć, czy dane uległy zmianie. To ogranicza ilość rzeczywistych aktualizacji interfejsu użytkownika, które należy wykonać.

Istnieją również komplikacje związane z obsługą obsługiwanych formularzy. Tak, wysłanie akcji za każde naciśnięcie klawisza może być ogólnie nieefektywne.Osobiście używam komponentu opakowania typu React, który buforuje te zmiany wprowadzania tekstu lokalnie, i wywołuje tylko zdeklarowaną akcję Redux po zakończeniu pisania.

Wiązania React-Redux zostały ostatnio przepisane i obecnie oparte są głównie na pamiętanych funkcjach selektora, a nie na większości elementów logicznych wewnątrz komponentów React. Nie wiem, jak łączą się wiązania Aurelia, ale podejrzewam, że prawdopodobnie wykorzystali wiele pracy, która została wykonana, aby zoptymalizować wiązania React.

Możesz być zainteresowany artykułami, które mam na temat wydajności związanej z Redux. Zobacz pytanie FAQ Redux pod adresem http://redux.js.org/docs/faq/Performance.html#performance-scaling, a także artykuły na mojej liście linków React/Redux pod numerem https://github.com/markerikson/react-redux-links/blob/master/react-performance.md#redux-performance.

+0

Dziękuję za odpowiedź. Popraw mnie, jeśli się mylę. Z twojej odpowiedzi wynika, że ​​istnieje wiele strategii optymalizacji operacji renderowania za pomocą Redux + React. Nie ma jednak strategii optymalizacji kosztów właściwych samej Redux, a mianowicie, że przy każdej zmianie sklepu należy uruchomić całą funkcję reduktora (która w dużych aplikacjach może oznaczać wywoływanie setek funkcji lub więcej), czy to jest poprawne? – pQuestions123

+0

Prawidłowo. Sam Redux jest naprawdę prosty - nie zapewnia sposobu "zasubskrybowania określonego fragmentu stanu" ani żadnego różnicowania wartości. Po prostu wywołuje reduktor, zapisuje wszystko, co zwraca i uruchamia wszystkie wywołania zwrotne. Powiedział, że nie martwię się o wydajność reduktora jako wąskie gardło. Zwykle będą to niektóre wywołania funkcji z instrukcjami przełączania i tabelami wyszukiwania - niezbyt drogie. Jeśli jesteś zaniepokojony, istnieją podejścia do zapewnienia fragmentów kodu reduktora, które są uruchamiane tylko w razie potrzeby. – markerikson