- Η αποστολή της σωστής έκδοσης React και η βελτιστοποίηση του bundler σας (παραλλαγές παραγωγής και δημιουργίας προφίλ) είναι η βάση για οποιαδήποτε σοβαρή εργασία απόδοσης.
- Η δημιουργία προφίλ με το React DevTools και τα tracks απόδοσης του προγράμματος περιήγησης αποκαλύπτει περιττές αποδόσεις, αργά εφέ και σημεία συμφόρησης διακομιστή που μπορείτε στη συνέχεια να στοχεύσετε.
- Η απομνημόνευση, η αμετάβλητη λειτουργία και η εικονικοποίηση συνεργάζονται για να μειώσουν τη συχνότητα απόδοσης, να συρρικνώσουν την εργασία ανά απόδοση και να διατηρήσουν ομαλά τα μεγάλα UI.
- Ο διαχωρισμός κώδικα, η SSR, οι Web Workers και η συνεχής παρακολούθηση εξασφαλίζουν γρήγορες αρχικές φορτώσεις, αλληλεπιδράσεις με δυνατότητα απόκρισης και βιώσιμη απόδοση σε μεγάλη κλίμακα.

Το React μπορεί να φαίνεται εκπληκτικά γρήγορο από την πρώτη κιόλας στιγμή, αλλά καθώς η εφαρμογή σας αναπτύσσεται, είναι εκπληκτικά εύκολο να συσσωρεύσετε ανεπαίσθητες παλινδρομήσεις στην απόδοση. που μετατρέπουν τις ομαλές διεπαφές σε αργές, απαιτητικές σε μπαταρία τέρατα. Μεγάλες λίστες, βαριά στοιχεία, αδέξιες δομές κατάστασης και δομές εντοπισμού σφαλμάτων στην παραγωγή, όλα αθροίζονται μέχρι οι χρήστες να αρχίσουν να εγκαταλείπουν τις σελίδες σας.
Τα καλά νέα είναι ότι το React συνοδεύεται από μια πλούσια εργαλειοθήκη για τη μέτρηση, την κατανόηση και τη βελτίωση της απόδοσης απόδοσης.και το περιβάλλον οικοσύστημα (bundlers, profilers, βιβλιοθήκες παραθύρων, Web Workers, frameworks SSR) σας παρέχει όλα όσα χρειάζεστε για να διατηρείτε το UI σας γρήγορο ακόμη και σε μεγάλη κλίμακα. Σε αυτόν τον οδηγό, θα εξετάσουμε αυτά τα εργαλεία σε βάθος, θα δείξουμε πώς συνδυάζονται και θα επισημάνουμε ορισμένα λιγότερο προφανή κόλπα που οι ομάδες συχνά παραλείπουν, αλλά που αξίζουν τον κόπο.
Χρησιμοποιήστε τη σωστή έκδοση React: ανάπτυξη, παραγωγή και δημιουργία προφίλ
Ο πρώτος έλεγχος απόδοσης για οποιαδήποτε εφαρμογή React είναι η επαλήθευση ότι στέλνετε την έκδοση παραγωγής και όχι την έκδοση ανάπτυξης.Η έκδοση προγραμματιστών περιλαμβάνει τόνους φιλικών προειδοποιήσεων, επιπλέον ελέγχους και βοηθήματα εντοπισμού σφαλμάτων που είναι φανταστικά κατά την κωδικοποίηση, αλλά αισθητά πιο αργά και μεγαλύτερα στην παραγωγή.
Μπορείτε να επιβεβαιώσετε ποια έκδοση χρησιμοποιείτε με την επέκταση προγράμματος περιήγησης React Developer Tools: όταν ανοίγετε έναν ιστότοπο χρησιμοποιώντας το React, το εικονίδιο επέκτασης έχει σκούρο φόντο στην παραγωγή και κόκκινο φόντο στην ανάπτυξη. Εάν δείτε ποτέ κόκκινο στον ενεργό ιστότοπό σας, η διαμόρφωση του bundler σας διαρρέει λάθος έκδοση.
Για έργα που βασίζονται στην εφαρμογή Create React, η δημιουργία ενός βελτιστοποιημένου πακέτου παραγωγής είναι τόσο απλή όσο η εκτέλεση του σεναρίου δημιουργίας σας., το οποίο εξάγει μια ελαχιστοποιημένη δέσμη στο build/ κατάλογο. Κατά την τοπική ανάπτυξη θα πρέπει να τηρείτε npm start (ή ισοδύναμο) και εκτελέστε την έκδοση παραγωγής μόνο για ανάπτυξη ή για ρεαλιστικά benchmarks απόδοσης.
Εάν βασίζεστε στις εκδόσεις ενός αρχείου UMD του React και του React DOM (για παράδειγμα σε ένα μη ομαδοποιημένο περιβάλλον), βεβαιωθείτε ότι έχετε συμπεριλάβει τα αρχεία που τελειώνουν σε .production.min.jsΟποιοδήποτε μη ελαχιστοποιημένο ή μη παραγωγικό αρχείο προορίζεται μόνο για ανάπτυξη και θα επιφέρει περιττή επιβάρυνση εντοπισμού σφαλμάτων στους χρήστες σας.
Πακέτα: Browserify, Rollup, Brunch και webpack
Διαφορετικά bundlers απαιτούν διαφορετικές τροποποιήσεις για να ενεργοποιήσουν πλήρως τις βελτιστοποιήσεις παραγωγής του React., αλλά όλα ακολουθούν την ίδια υποκείμενη ιδέα: ορίστε το περιβάλλον σε παραγωγή, αφαιρέστε τους κλάδους που είναι μόνο για προγραμματιστές και ελαχιστοποιήστε την προκύπτουσα JavaScript.
Με το Brunch, η συνιστώμενη προσέγγιση είναι η εγκατάσταση ενός πρόσθετου minifier όπως το terser-brunch, στη συνέχεια εκτελέστε την κατασκευή σας με τη σημαία παραγωγής (για παράδειγμα με -p). Αυτή η διαμόρφωση διασφαλίζει ότι οι προειδοποιήσεις χρόνου ανάπτυξης αφαιρούνται και η τελική δέσμη συμπιέζεται δυναμικά.
Για το Browserify, συνήθως συνδέετε μερικούς μετασχηματισμούς σε μια συγκεκριμένη σειρά: πρώτα εφαρμόστε envify παγκοσμίως για ένεση NODE_ENV="production", στη συνέχεια εφαρμόστε uglifyify παγκοσμίως για να διαγραφούν οι εισαγωγές ανάπτυξης και οι διαδρομές κώδικα και τελικά να διοχετευθεί η δέσμη terser για παραμόρφωση και συμπίεση. Η σειρά έχει σημασία εδώ, επειδή κάθε βήμα προετοιμάζει τον κώδικα για τον επόμενο μετασχηματισμό.
Όταν χρησιμοποιείτε το Rollup, συνδέετε τρία πρόσθετα (plugins) για να επιτύχετε μια λιτή παραγωγική δομή.: replace ορίζει το περιβάλλον σε παραγωγή, commonjs επιτρέπει την ομαδοποίηση ενοτήτων CommonJS και terser εκτελεί την τελική ελαχιστοποίηση και παραμόρφωση. Αυτός ο συνδυασμός παράγει ένα μικρό, έτοιμο για παραγωγή πακέτο χωρίς τους βοηθούς που είναι μόνο για προγραμματιστές.
Με το webpack 4 και άνω, η ενεργοποίηση της λειτουργίας παραγωγής ενεργοποιεί αυτόματα πολλές βελτιστοποιήσεις, συμπεριλαμβανομένης της ελαχιστοποίησης.. Σύνθεση mode: 'production' καλώδια στο Terser κάτω από την κουκούλα και επιτρέπει τη συμπεριφορά παραγωγής του React εφόσον NODE_ENV ταιριάζει. Συνήθως δεν χρειάζεται να προσθέσετε ξεχωριστό ελαχιστοποιητή, εκτός εάν έχετε πολύ συγκεκριμένες απαιτήσεις.
Δημιουργία προφίλ δομών του React
Εκτός από τις κανονικές εκδόσεις για προγραμματιστές και προϊόντα, το React προσφέρει επίσης μια ειδική έκδοση προφίλ που εστιάζει στην ανάλυση απόδοσης.Αυτή η παραλλαγή των οργάνων React εσωτερικά, έτσι ώστε εργαλεία όπως το DevTools Profiler να μπορούν να συλλέγουν πολύ λεπτομερείς πληροφορίες χρονισμού.
Για να χρησιμοποιήσετε τη δομή δημιουργίας προφίλ σε ένα περιβάλλον προγράμματος περιήγησης, εισάγετε react-dom/profiling αντί του react-dom/client και συνήθως ρυθμίζουν ένα ψευδώνυμο bundler, ώστε να μην χρειάζεται να αγγίζετε κάθε εισαγωγή χειροκίνητα. Ορισμένα πλαίσια εμφανίζουν ήδη μια σημαία ή λειτουργία για να εναλλάσσουν αυτήν τη συμπεριφορά για εσάς.
Οι παλαιότερες εκδόσεις του React (πριν από την έκδοση 17) βασίζονταν στο τυπικό API Χρονισμού Χρήστη. για να εμφανίζει σημάδια και μετρήσεις ορατά στον πίνακα Performance του προγράμματος περιήγησης. Το Modern React συνδυάζει αυτές τις δυνατότητες με την ειδική καρτέλα Profiler στο React DevTools, ώστε να μπορείτε να κάνετε απευθείας αναζήτηση σε στοιχεία.
Κατανόηση και μέτρηση της απόδοσης του React
Δεν μπορείτε να διορθώσετε αυτό που δεν μετράτε, επομένως η βελτίωση της απόδοσης στο React θα πρέπει πάντα να ξεκινά με τη δημιουργία προφίλ.Αυτό σημαίνει χρήση εργαλείων προγράμματος περιήγησης και ειδικών για το React profilers για να δείτε πού αφιερώνεται στην πραγματικότητα ο χρόνος και ποια στοιχεία επανεμφανίζονται περισσότερο από όσο θα έπρεπε.
Ο πίνακας απόδοσης του Chrome DevTools είναι η βάση για να κατανοήσετε τι κάνει το πρόγραμμα περιήγησης.Η εκτέλεση JavaScript, τα αιτήματα δικτύου, η διάταξη, τα χρώματα, οι καθυστερήσεις βρόχου συμβάντων και οι προσαρμοσμένες ιχνηλατήσεις εμφανίζονται όλα σε μια ενοποιημένη χρονογραμμή. Το React ενσωματώνεται σε αυτήν την προβολή με εξειδικευμένα κομμάτια που εκθέτουν δραστηριότητα συγκεκριμένη για το πλαίσιο.
Το Modern React εκθέτει τα ίχνη του Scheduler, των Components και του Server που ευθυγραμμίζονται με τα κανονικά ίχνη του προγράμματος περιήγησηςΑυτό σας δίνει μια συγχρονισμένη προβολή των ενημερώσεων δικτύου, JavaScript και React, κάτι που είναι εξαιρετικά χρήσιμο όταν ψάχνετε για ανοησίες ή παράξενα stalls που εμφανίζονται μόνο υπό φόρτο.
Ο προγραμματιστής παρακολουθεί και αποδίδει φάσεις
Ο Χρονοπρογραμματιστής είναι μια εσωτερική αφαίρεση του React που ενορχηστρώνει την εργασία με διαφορετικές προτεραιότητες.Στις ιχνηλατήσεις απόδοσης θα δείτε ξεχωριστά δευτερεύοντα ίχνη για εργασίες αποκλεισμού (συχνά σύγχρονες ενημερώσεις που καθοδηγούνται από τον χρήστη), εργασίες μετάβασης (ενημερώσεις περιβάλλοντος εργασίας χρήστη στο παρασκήνιο που ενεργοποιούνται από startTransition), Εργασίες που σχετίζονται με την αγωνία και αδρανής εργασία που εκτελείται όταν δεν υπάρχει τίποτα πιο επείγον σε εκκρεμότητα.
Κάθε πέρασμα απόδοσης περνάει από διάφορες φάσεις που μπορείτε να ελέγξετε στη χρονογραμμή: μια φάση ενημέρωσης (τι ενεργοποίησε την απόδοση), μια φάση απόδοσης (όπου το React καλεί τα στοιχεία σας και κατασκευάζει το επόμενο δέντρο), μια φάση υποβολής (όπου το DOM μεταλλάσσεται και εφέ διάταξης όπως useLayoutEffect εκτέλεση) και μια φάση υπολειπόμενων εφέ (όπου παθητικά εφέ όπως useEffect συνήθως τρέχουν μετά το χρώμα).
Οι διαδοχικές ενημερώσεις —αλλαγές κατάστασης που προγραμματίζονται κατά τη διάρκεια μιας απόδοσης— αποτελούν μια κλασική πηγή κρυφών προβλημάτων απόδοσης.Κατά την ανάπτυξη, το React μπορεί να τα επισημάνει αυτά στη χρονογραμμή, ακόμη και να δείξει ποιο στοιχείο και μέθοδος έχει προγραμματίσει την επιπλέον ενημέρωση, βοηθώντας σας να αποφύγετε ακούσιους βρόχους απόδοσης ή επαναλαμβανόμενη εργασία.
Παρακολούθηση στοιχείων: γραφήματα φλόγας για renders και εφέ
Το κομμάτι Στοιχείων απεικονίζει πόσο χρόνο χρειάζεται για την απόδοση κάθε στοιχείου (και των απογόνων του) χρησιμοποιώντας ένα φλογογράφημα. Όσο πιο πλατύ είναι το μπλοκ στο γράφημα, τόσο περισσότερο χρόνο καταναλώνει το υποδέντρο στοιχείων σε αυτό το πέρασμα απόδοσης.
Το React εκθέτει επίσης τις διάρκειες των εφέ ως ξεχωριστό φλογογράφημα. με ένα χρωματικό συνδυασμό που αντικατοπτρίζει την αντίστοιχη φάση στο κομμάτι του Χρονοδιαγράμματος, ώστε να μπορείτε να διακρίνετε τον χρόνο απόδοσης από τον χρόνο εφέ με μια ματιά.
Πρόσθετα συμβάντα όπως προσαρτήσεις, αποσυνδέσεις, επανασυνδέσεις και αποσυνδέσεις εμφανίζονται ως σχολιασμοί σε αυτά τα φλογογράμματαΓια παράδειγμα, θα επισημανθεί η τοποθέτηση ενός νέου μέρους του δέντρου ή η αποξήλωση ενός, και ορισμένα χαρακτηριστικά όπως <Activity> Τα στοιχεία λαμβάνουν τους δικούς τους δείκτες επανασύνδεσης/αποσύνδεσης.
Στην ανάπτυξη, κάνοντας κλικ σε μια καταχώρηση απόδοσης στο κομμάτι των Στοιχείων αποκαλύπτονται ποια props άλλαξαν., το οποίο είναι εξαιρετικά χρήσιμο όταν προσπαθείτε να εντοπίσετε περιττές αποδόσεις ή props που αλλάζουν συνεχώς αναφορές χωρίς να αλλάζουν στην πραγματικότητα την τιμή.
Κομμάτια διακομιστή: αιτήματα και στοιχεία διακομιστή
Εάν χρησιμοποιείτε React Server Components, τα εργαλεία απόδοσης μπορούν επίσης να εμφανίσουν συμπεριφορά από την πλευρά του διακομιστή.Ένα «Αιτήματα διακομιστή» παρακολουθεί συγκεντρωτικά στοιχεία Υποσχέσεις που τελικά τροφοδοτούν δεδομένα σε στοιχεία διακομιστή, συμπεριλαμβανομένων κλήσεων προς fetch ή ασύγχρονες λειτουργίες συστήματος αρχείων.
Προσπάθειες αντίδρασης για την ομαδοποίηση των Υποσχέσεων που δημιουργήθηκαν σε βοηθούς τρίτων σε ένα ενιαίο εύρος έτσι θα δείτε μια λογική λειτουργία όπως getUser αντί για δώδεκα χαμηλού επιπέδου fetch κλήσεις. Κάνοντας κλικ σε ένα εύρος εμφανίζεται η τοποθεσία δημιουργίας του και, όταν είναι διαθέσιμη, η τιμή που έχει επιλυθεί ή ο λόγος απόρριψης.
Ένα ξεχωριστό κομμάτι στοιχείων διακομιστή εμφανίζει πόσο χρόνο χρειάζονται τα δέντρα στοιχείων διακομιστή και οι αναμενόμενες υποσχέσεις τους, επίσης σε μορφή φλογόγραφου. Όταν το React μπορεί να αποδώσει στοιχεία διακομιστή ταυτόχρονα, δημιουργεί ένα κύριο κομμάτι και επιπλέον παράλληλα κομμάτια. Εάν η ταυτόχρονη εργασία υπερβεί έναν ορισμένο αριθμό, η επιπλέον εργασία ομαδοποιείται για να διατηρείται η προβολή αναγνώσιμη.
Μείωση περιττών αποδόσεων: React.memo, useMemo, useCallback και PureComponent
Μία από τις μεγαλύτερες και πιο συνηθισμένες μειώσεις στην απόδοση των εφαρμογών React είναι η άσκοπη επαναλαμβανόμενη απόδοση (re-rendering).Κάθε φορά που ενημερώνεται ένα γονικό στοιχείο, τα θυγατρικά του στοιχεία επανεμφανίζονται από προεπιλογή, ακόμα και αν οι είσοδοι (props) τους είναι πανομοιότυπες και το DOM εξόδου δεν θα άλλαζε στην πραγματικότητα.
Το React προσφέρει διάφορα εργαλεία για να μειώσει αυτή την χαμένη εργασία: React.memo για λειτουργικά εξαρτήματα, React.PureComponent για τα στοιχεία της κλάσης, και το useMemo/useCallback άγκιστρα για τη σταθεροποίηση τιμών που μεταδίδονται ως στηρίγματαΑυτά δεν διορθώνουν μαγικά όλα τα προβλήματα απόδοσης, αλλά αν χρησιμοποιηθούν προσεκτικά μπορούν να κάνουν τεράστια διαφορά.
React.memo αναδιπλώνει ένα λειτουργικό στοιχείο και παραλείπει την επαναλαμβανόμενη απόδοση όταν τα props του είναι ελαφρώς ίσα με τα προηγούμεναΑυτό είναι ιδιαίτερα πολύτιμο όταν ένα στοιχείο αποδίδεται συχνά με τα ίδια props, έχει έντονη λογική απόδοσης ή έχετε στοιχεία από το Profiler ότι αποτελεί σημείο συμφόρησης.
Όταν απομνημονεύετε ένα στοιχείο, πρέπει επίσης να βεβαιωθείτε ότι τα στηρίγματα του δεν αλλάζουν την ταυτότητά του άσκοπα.Η δημιουργία ενός νέου αντικειμένου ή ενσωματωμένης συνάρτησης μέσα στο γονικό JSX σε κάθε απόδοση θα ακυρώσει την επιφανειακή σύγκριση και θα αναγκάσει το θυγατρικό να την επαναλάβει, ακόμα κι αν τα λογικά δεδομένα είναι τα ίδια.
Εδώ είναι που useMemo useCallback Πέρασε Μέσα: useMemo σταθεροποιεί τις τιμές αντικειμένων ή πινάκων που προέρχονται από άλλη κατάσταση, έτσι ώστε να αλλάζουν μόνο όταν αλλάζουν και οι εξαρτήσεις τους, και useCallback παρέχει σταθερές αναφορές συναρτήσεων για επανακλήσεις που διαβιβάζονται σε απομνημονευμένα παιδιά.
Στοιχεία κλάσης: shouldComponentUpdate και React.PureComponent
Στο κάτω κάτω, οι περισσότερες βελτιστοποιήσεις απόδοσης Reaction καταλήγουν στον έλεγχο του εάν shouldComponentUpdate επιστρέφει true ή falseΗ προεπιλεγμένη υλοποίηση επιστρέφει πάντα την τιμή true, που σημαίνει ότι οποιαδήποτε αλλαγή στην πρόταση ή την κατάσταση ενεργοποιεί μια απόδοση και μια συμφωνία για αυτό το στοιχείο και το υποδέντρο του.
Με παράκαμψη shouldComponentUpdate, μπορείτε να βραχυκυκλώσετε την εργασία για υποδέντρα που δεν χρειάζονται ενημέρωσηΑν επιστρέψετε false, το React δεν θα καλέσει render() για αυτό το στοιχείο ή για οποιονδήποτε από τους απογόνους του, και δεν θα συγκρίνει καν τους νέους και τους παλιούς εικονικούς κόμβους DOM για αυτό το μέρος του δέντρου.
Θεωρήστε ένα μικρό δέντρο συστατικών όπου ορισμένοι κόμβοι επιστρέφουν false από shouldComponentUpdateΤο React μπορεί να παραλείψει εντελώς τη διέλευση σε αυτούς τους κλάδους, ενώ άλλοι κόμβοι όπου η μέθοδος επιστρέφει true θα υποβληθούν σε πλήρη επεξεργασία. Στο τέλος, μόνο οι κόμβοι των οποίων η απόδοση εξόδου άλλαξε πραγματικά θα προκαλέσουν μεταλλάξεις DOM.
Επειδή η γραφή κατά παραγγελία shouldComponentUpdate Η λογική είναι επαναλαμβανόμενη, το React αποστέλλεται React.PureComponent, το οποίο υλοποιεί μια επιφανειακή σύγκριση των τρεχόντων και προηγούμενων props και κατάστασης. Εάν δεν αλλάξει τίποτα επιφανειακά, το React μπορεί με ασφάλεια να παραλείψει την επαναφορά αυτού του στοιχείου κλάσης.
Αμετάβλητο και γιατί η επιφανειακή σύγκριση μπορεί να αποτύχει
Η ρηχή σύγκριση υποθέτει ότι εάν αλλάξει μια τιμή, θα αλλάξει και η αναφορά της — μια υπόθεση που ακυρώνεται τη στιγμή που μεταλλάσσετε υπάρχοντες πίνακες ή αντικείμενα στη θέση τους.Αυτή είναι μια κλασική πηγή σφαλμάτων κατά τον συνδυασμό βελτιστοποιήσεων που βασίζονται στην αμετάβλητη φύση με μεταβλητές δομές δεδομένων.
Φανταστείτε a ListOfWords στοιχείο που λαμβάνει ένα words πίνακα και τα αποδίδει διαχωρισμένα με κόμμα, σε συνδυασμό με έναν γονέα WordAdder στοιχείο που ωθεί μια νέα λέξη στον ίδιο πίνακα. Εάν ListOfWords Επεκτείνεται PureComponent, η επιφανειακή σύγκριση θα δει την ίδια αναφορά πίνακα και θα υποθέσει ότι δεν έχει αλλάξει τίποτα, επομένως το περιβάλλον χρήστη δεν θα ενημερωθεί.
Η λύση είναι να αποφεύγεται η άμεση μετάλλαξη των props ή της κατάστασης και να δημιουργούνται νέοι πίνακες ή αντικείμενα όταν αλλάζουν τα δεδομένα.. Αντί words.push(newWord), θα χρησιμοποιούσατε words.concat(newWord) ή η σύνταξη εξάπλωσης [...words, newWord], το οποίο δημιουργεί μια νέα αναφορά για τον πίνακα και ενεργοποιεί τις σωστές ενημερώσεις.
Η ίδια αρχή ισχύει και για τα αντικείμενα: αντί να γίνει εκ νέου ανάθεση colormap.right = 'blue' σε ένα υπάρχον αντικείμενο, θα επιστρέφατε ένα νέο αντικείμενο χρησιμοποιώντας Object.assign({}, colormap, { right: 'blue' }) ή η σύνταξη εξάπλωσης αντικειμένου { ...colormap, right: 'blue' }Αυτό εγγυάται ότι η επιφανειακή σύγκριση βλέπει μια νέα αναφορά και αναγνωρίζει την αλλαγή.
Όταν τα δεδομένα γίνονται βαθιά ένθετα, η διατήρηση της αμετάβλητης φύσης με το χέρι μπορεί να γίνει δυσκίνητη.Βιβλιοθήκες όπως το Immer ή το immutability-helper σάς επιτρέπουν να γράφετε κώδικα που φαίνεται επιτακτικός και μεταλλασσόμενος, ενώ παράλληλα παράγει εσωτερικά νέες αμετάβλητες δομές, κάτι που ταιριάζει απόλυτα με PureComponent React.memo.
Εικονικοποίηση μεγάλων λιστών και βαρέων UI
Η ταυτόχρονη απόδοση εκατοντάδων ή χιλιάδων κόμβων DOM είναι ένας από τους ταχύτερους τρόπους για να βελτιώσετε την απόδοση του React., ειδικά σε συσκευές χαμηλού επιπέδου ή όταν συνδυάζονται με σύνθετες διατάξεις και εικόνες. Ακόμα και με αποτελεσματική συμφωνία, η απλή ύπαρξη τόσων πολλών κόμβων στη μνήμη και στην οθόνη είναι δαπανηρή.
Η δημιουργία παραθύρων ή η εικονικοποίηση λίστας αντιμετωπίζει αυτό το πρόβλημα, αποδίδοντας μόνο το τμήμα μιας λίστας που είναι ορατό αυτήν τη στιγμή στο παράθυρο προβολής.Καθώς ο χρήστης κάνει κύλιση, το React προσαρτά νέα στοιχεία που εισέρχονται στην προβολή και αποπροσαρτά αυτά που κάνουν κύλιση προς τα έξω, διατηρώντας τον αριθμό των εμφανιζόμενων γραμμών περίπου σταθερό.
Δημοφιλείς βιβλιοθήκες όπως react-window react-virtualized παρέχουν επαναχρησιμοποιήσιμα στοιχεία για λίστες, πλέγματα και πίνακες που εφαρμόζουν αποτελεσματικές στρατηγικές εικονικοποίησης. Διαχειρίζονται τα μαθηματικά των στοιχείων που θα αποδοθούν, του μεγέθους, της κύλισης των κοντέινερ, ακόμη και της άπειρης συμπεριφοράς φόρτωσης.
Η εγκατάσταση της εικονικοποίησης συνήθως περιλαμβάνει τρία μέρη: επιλογή του κατάλληλου στοιχείου (για παράδειγμα, FixedSizeList για ομοιόμορφες σειρές ή VariableSizeList για δυναμικά ύψη), δίνοντας στο δοχείο ένα σταθερό ύψος με overflow: scrollκαι απόδοση μόνο του στοιχείου στοιχείου που ζητά η βιβλιοθήκη, συνήθως απομνημονευμένο με React.memo για να αποφευχθούν άσκοπες επαναλήψεις.
Με καλή απόδοση, η εικονικοποίηση διατηρεί την απόδοση κύλισης ομαλή και τη χρήση μνήμης χαμηλή ακόμη και για τεράστια σύνολα δεδομένων.Οι εφαρμογές του πραγματικού κόσμου έχουν χρησιμοποιήσει αυτήν την τεχνική για να περιηγούνται αποτελεσματικά σε τεράστιες συλλογές - μουσικές κριτικές, καταλόγους ηλεκτρονικού εμπορίου, εισερχόμενα - χωρίς να σταματάει το περιβάλλον χρήστη.
Η προσβασιμότητα απαιτεί επιπλέον προσοχή με τις εικονικοποιημένες λίστεςΠρέπει να διασφαλίσετε ότι η πλοήγηση μέσω πληκτρολογίου λειτουργεί, ότι η εστίαση διαχειρίζεται σωστά κατά την προσάρτηση και την αποπροσάρτηση στοιχείων και ότι τα προγράμματα ανάγνωσης οθόνης έχουν επαρκές περιεχόμενο μέσω των χαρακτηριστικών ARIA για να κατανοήσουν το τμήμα της λίστας που είναι ορατό αυτήν τη στιγμή.
Διαχείριση κατάστασης, εικονικό DOM και δομή στοιχείων
Το εικονικό DOM συχνά παρερμηνεύεται ως μια ακατανόητη λύση, αλλά στην πραγματικότητα είναι απλώς ένα έξυπνο διαφορικό επίπεδο.Το React διατηρεί μια αναπαράσταση του UI σας στη μνήμη και συγκρίνει το νέο δέντρο με το παλιό για να αποφασίσει ποιες λειτουργίες DOM είναι απολύτως απαραίτητες.
Ακόμα και με αυτήν την αποτελεσματικότητα, κάθε απόδοση και διαφορά εξακολουθεί να κοστίζει χρόνο, επομένως ο στόχος σας είναι να ελαχιστοποιήσετε τη συχνότητα με την οποία τα μεγάλα υποδέντρα χρειάζεται να επανααποδίδονται.Εδώ είναι που τέμνονται η διαχείριση κατάστασης, τα όρια των στοιχείων και οι στρατηγικές απομνημόνευσης.
Αρχικά, επιλέξτε μια κατάλληλη στρατηγική διαχείρισης κατάστασης για την πολυπλοκότητα της εφαρμογής σας.Τοπική κατάσταση αντίδρασης (useState, useReducer) είναι μικροσκοπικό και απλό για μικρά στοιχεία, ενώ βιβλιοθήκες όπως το Redux ή ελαφριά καταστήματα όπως το Zustand μπορούν να συγκεντρώσουν πιο σύνθετες παγκόσμιες καταστάσεις με βελτιστοποιημένα μοτίβα συνδρομής.
Δεύτερον, δομήστε την κατάστασή σας έτσι ώστε τα σχετικά δεδομένα να ομαδοποιούνται λογικάΜερικές φορές αυτό σημαίνει ενοποίηση πολλαπλών useState καλεί ένα μόνο αντικείμενο, ώστε οι ενημερώσεις να είναι συνεκτικές. Σε άλλες περιπτώσεις, ο διαχωρισμός της κατάστασης, έτσι ώστε οι ανεξάρτητες ανησυχίες να μην αναγκάζουν η μία την άλλη να επαναλάβουν την απόδοση, είναι πιο αποτελεσματικός.
Κατά την ενημέρωση της κατάστασης που προκύπτει από προηγούμενες τιμές, να χρησιμοποιείτε πάντα λειτουργικές ενημερώσεις όπως το πορτοκαλί και το κίτρινο μπορούν να φωτίσουν τα έπιπλά σας και να τα αναδείξουν. Αυτά τα χρώματα ταιριάζουν καλά με ξύλα ανοιχτών τόνων, προσθέτοντας ζεστασιά και ζωντάνια στον χώρο. setCount(prev => prev + 1)και διατηρούν την αμετάβλητη φύση τους κλωνοποιώντας πίνακες και αντικείμενα αντί να τα μεταλλάσσουν στη θέση τους. Αυτό οδηγεί σε προβλέψιμη συμπεριφορά και λειτουργεί καλά με την απομνημόνευση και τα PureComponents.
Ένας εύχρηστος εμπειρικός κανόνας είναι να διατηρείτε την κατάσταση όσο το δυνατόν πιο τοπική.Όσο υψηλότερα στο δέντρο αποθηκεύετε μια τιμή κατάστασης, τόσο περισσότερα στοιχεία θα εμφανίζονται ξανά κάθε φορά που αλλάζει. Η μείωση της τιμής κατάστασης στα στοιχεία που την χρησιμοποιούν στην πραγματικότητα περιορίζει την ακτίνα έκρηξης κάθε ενημέρωσης.
Τέλος, σπάστε τα μεγάλα εξαρτήματα σε μικρότερα, εστιασμένα κομμάτια των οποίων τα στηρίγματα σπάνια αλλάζουνΤα απομνημονευμένα στοιχεία φύλλων με σταθερά props μειώνουν την ποσότητα των διαφορών που χρειάζεται το React για εικονικό DOM και συντομεύουν τη διαδρομή προς ένα ελάχιστο σύνολο ενημερώσεων DOM.
Διαχωρισμός κώδικα, αργή φόρτωση και καλύτερη φόρτωση πόρων
Το μέγεθος της δέσμης JavaScript συμβάλλει σημαντικά στην κακή απόδοση, ειδικά σε δίκτυα κινητής τηλεφωνίας.Αν το πακέτο React σας χρειαστεί αρκετά δευτερόλεπτα για λήψη και ανάλυση, οι χρήστες θα επιστρέψουν στην αρχική σελίδα πολύ πριν δουν το όμορφο περιβάλλον χρήστη σας.
Διαχωρισμός κώδικα με React.lazy Suspense βοηθάει φορτώνοντας εξαρτήματα κατόπιν αιτήματος αντί να τα στέλνετε όλα εκ των προτέρωνΑντί να ομαδοποιείτε κάθε χαρακτηριστικό στο αρχικό ωφέλιμο φορτίο, εισάγετε δυναμικά τα κομμάτια που χρειάζονται μόνο για συγκεκριμένες διαδρομές ή αλληλεπιδράσεις.
Μια κοινή στρατηγική είναι ο διαχωρισμός σε επίπεδο διαδρομής, όπου κάθε σελίδα αποτελεί το δικό της κομμάτι και φορτώνεται μόνο όταν ο χρήστης μεταβαίνει σε αυτήν. Μπορείτε να προχωρήσετε περαιτέρω και να διαχωρίσετε μεγάλα στοιχεία λειτουργιών ή σπάνια χρησιμοποιούμενα πάνελ, αρκεί να τα τυλίξετε Suspense με ένα κατάλληλο εφεδρικό περιβάλλον χρήστη.
Η αργή φόρτωση ισχύει και για τις εικόνες.. Προσθέτωντας loading="lazy" προς την <img> Οι ετικέτες αναβάλλουν τη φόρτωση εικόνων από κάτω προς τα κάτω μέχρι να εμφανιστούν, εξοικονομώντας εύρος ζώνης και επιταχύνοντας την αρχική ζωγραφική. Για πιο προηγμένα εφέ, βιβλιοθήκες όπως react-lazy-load-image-component υποστηρίζει θολά placeholders και προοδευτική φόρτωση.
Κατά την εφαρμογή διαχωρισμού κώδικα, είναι σημαντικό να εξισορροπήσετε τα μεγέθη των κομματιών κώδικα και την εμπειρία χρήστη.Η υπερβολική διαίρεση μπορεί να δημιουργήσει πάρα πολλά μικροσκοπικά αιτήματα, ενώ η υποδιαίρεση σας αφήνει με ένα βαρύ αρχικό πακέτο. Τα καλά εφεδρικά αντίγραφα και τα όρια σφάλματος γύρω από τα αδρανή στοιχεία είναι απαραίτητα, ώστε τα αποτυχημένα αιτήματα δικτύου να μην προκαλέσουν σφάλματα σε ολόκληρη την εφαρμογή.
Απόδοση από την πλευρά του διακομιστή, Στοιχεία React Server και Ενέργειες Server
Η απόδοση από την πλευρά του διακομιστή (SSR) αποδίδει την εφαρμογή React στον διακομιστή και στέλνει HTML στον πελάτη, κάτι που μπορεί να βελτιώσει δραματικά την αντιληπτή απόδοση και το SEO.Οι χρήστες βλέπουν χρήσιμο περιεχόμενο νωρίτερα και οι μηχανές αναζήτησης μπορούν να δημιουργήσουν ευρετήριο στις σελίδες σας με μεγαλύτερη αξιοπιστία.
Πλαίσια όπως το Next.js καθιστούν την SSR και τη ροή HTML πρακτική για καθημερινές εφαρμογές.Ανακτάτε δεδομένα στον διακομιστή, αποδίδετε στοιχεία σε HTML—μερικές φορές ακόμη και ως ροή—και στη συνέχεια ενυδατώνετε αυτήν τη σήμανση στον πελάτη, ώστε να γίνει διαδραστικό.
Πέρα από το κλασικό SSR, τα React Server Components μεταφέρουν μεγαλύτερο μέρος της λογικής του UI σας στην πλευρά του διακομιστή., επιτρέποντάς σας να αποδίδετε στοιχεία που δεν αποστέλλονται ποτέ στον πελάτη. Αυτό μπορεί να μειώσει σημαντικά το μέγεθος της δέσμης δεδομένων του πελάτη και να απλοποιήσει την ανάκτηση δεδομένων, καθώς τα στοιχεία του διακομιστή μπορούν να καλούν απευθείας βάσεις δεδομένων ή API.
Οι Ενέργειες Διακομιστή επεκτείνουν αυτήν την ιδέα επιτρέποντάς σας να ορίσετε συναρτήσεις που εκτελούνται στον διακομιστή αλλά ενεργοποιούνται από στοιχεία του προγράμματος-πελάτη.Αυτό εξαλείφει πολλά τυποποιημένα τελικά σημεία REST ή εξατομικευμένους χειριστές API και μπορεί να βελτιστοποιήσει τον τρόπο χειρισμού των μεταλλάξεων, των υποβολών φορμών και άλλων λειτουργιών με βάση την κατάσταση.
Χρησιμοποιούμενα μαζί, το SSR, τα Στοιχεία Διακομιστή και οι Ενέργειες Διακομιστή σάς παρέχουν ένα φάσμα στρατηγικών απόδοσης.: το κρίσιμο περιεχόμενο μπορεί να μεταδοθεί γρήγορα από τον διακομιστή, η βαριά λογική παραμένει εκτός του προγράμματος-πελάτη και το περιβάλλον εκτέλεσης React συνδυάζει τα πάντα σε ένα συνεκτικό UX.
Απαλλαγή από βαριά εργασία με Web Workers
Ακόμα και το καλύτερα βελτιστοποιημένο δέντρο React θα παρουσιάσει σφάλματα εάν εκτελέσετε εργασίες που απαιτούν μεγάλη ποσότητα CPU στο κύριο νήμα.Οι ακριβοί υπολογισμοί εμποδίζουν την απόδοση, καθυστερούν τον χειρισμό συμβάντων και κάνουν την εφαρμογή σας να μην ανταποκρίνεται.
Οι Web Workers παρέχουν έναν τρόπο μετακίνησης αυτών των βαριών εργασιών σε ένα νήμα παρασκηνίου.Στέλνετε δεδομένα στον εργαζόμενο, τον αφήνετε να επεξεργαστεί τους αριθμούς ή να επεξεργαστεί μεγάλα σύνολα δεδομένων και, στη συνέχεια, λαμβάνετε το αποτέλεσμα μέσω μετάδοσης μηνυμάτων, αφήνοντας το κύριο νήμα ελεύθερο να χειριστεί τις ενημερώσεις του περιβάλλοντος εργασίας χρήστη.
Τα τυπικά φόρτα εργασίας για τους Web Workers περιλαμβάνουν την επεξεργασία δεδομένων, την επεξεργασία εικόνων, την ανάλυση σε πραγματικό χρόνο ή πολύπλοκες προσομοιώσεις.Για παράδειγμα, τα παιχνίδια που κατασκευάζονται με τη στοίβα ιστού συχνά αναθέτουν την βασική λογική του παιχνιδιού σε έναν εργάτη, ενώ το κύριο νήμα είναι αφιερωμένο στην απόδοση και τον χειρισμό εισόδου.
Η ενσωμάτωση ενός worker με το React περιλαμβάνει τη δημιουργία ενός ξεχωριστού αρχείου script, το οποίο ακούει για onmessage μέσα στον εργαζόμενο και δημοσίευση μηνυμάτων από τα στοιχεία σαςΣτο στοιχείο, δημιουργείτε την αρχική εικόνα του worker, του στέλνετε δεδομένα εισόδου με postMessage και ενημέρωση κατάστασης όταν αποκρίνεται, ιδανικά καθαρίζοντας τον εργάτη όταν το στοιχείο αποσυνδεθεί.
Βιβλιοθήκες όπως τα πρόσθετα Comlink, workerize ή bundler μπορούν να απλοποιήσουν αυτό το μοτίβο. αφαιρώντας την επεξεργασία μηνυμάτων χαμηλού επιπέδου και δίνοντάς σας ένα API που μοιάζει με κλήση ασύγχρονων συναρτήσεων, κάτι που είναι πιο εύκολο να σκεφτείτε σε μια βάση κώδικα React.
Βασικές μετρήσεις που επικεντρώνονται στο πρόγραμμα περιήγησης και τον χρήστη και προς παρακολούθηση
Σε υψηλότερο επίπεδο, η συνολική απόδοση του ιστού παρακολουθείται συνήθως χρησιμοποιώντας μετρήσεις που επικεντρώνονται στον χρήστη. όπως το First Contentful Paint (FCP), το Largest Contentful Paint (LCP) και ο Χρόνος έως την Αλληλεπίδραση (TTI). Αυτά σας δίνουν μια αίσθηση για το πόσο γρήγορα οι χρήστες βλέπουν το περιεχόμενο και πόσο σύντομα μπορούν πραγματικά να αλληλεπιδράσουν με αυτό.
Οι εφαρμογές Healthy React στοχεύουν σε FCP κάτω από περίπου 1.8 δευτερόλεπτα, LCP κάτω από περίπου 2.5 δευτερόλεπτα και TTI πολύ κάτω από 4 δευτερόλεπτα σε τυπικές συσκευές., αν και τα ακριβή όρια μπορεί να διαφέρουν ανάλογα με το έργο. Εάν υπερβαίνετε συνεχώς αυτούς τους αριθμούς, αυτό αποτελεί ένδειξη ότι τα πακέτα, η στρατηγική απόδοσης ή οι χρόνοι απόκρισης του διακομιστή σας χρειάζονται βελτίωση.
Εργαλεία όπως το Lighthouse, το WebPageTest και ο πίνακας Performance του Chrome σάς βοηθούν να μετρήσετε αυτές τις μετρήσεις σε περιβάλλοντα συνθετικών δοκιμών.Για πληροφορίες σχετικά με τον πραγματικό κόσμο, τα εργαλεία παρακολούθησης πραγματικών χρηστών (RUM) όπως τα SpeedCurve, Datadog, LogRocket ή Sentry παρακολουθούν τις πραγματικές συνεδρίες χρηστών και συνδέουν τις αργές εμπειρίες με τις αλλαγές στον κώδικα.
Το Profiler API του React ενσωματώνεται άψογα με αυτήν την εικόναμπορείτε να τυλίξετε μέρη του δέντρου σας <Profiler>, καταγράφει αργές αποδόσεις και τις συσχετίζει με συγκεκριμένες ροές χρηστών. Όταν χρησιμοποιείται παράλληλα με την παρακολούθηση backend και δικτύου, αυτό σας δίνει μια πλήρη εικόνα της απόδοσης από άκρο σε άκρο.
Πρακτική ομαδική ροή εργασίας για βελτίωση της απόδοσης
Σε πραγματικά έργα, η βελτίωση της απόδοσης λειτουργεί καλύτερα όταν αντιμετωπίζεται ως επαναλαμβανόμενη ροή εργασίας και όχι ως ένας εφάπαξ καθαρισμός.Ένας απλός βρόχος τεσσάρων φάσεων — εντοπισμός, διερεύνηση, εφαρμογή, επιβεβαίωση — βοηθά στην αποτροπή τυχαίων μικροβελτιστοποιήσεων και διατηρεί τις προσπάθειες εστιασμένες εκεί που έχουν σημασία.
Η αναγνώριση σημαίνει χρήση προφίλ, μετρήσεων και αναφορών χρηστών για την εύρεση συγκεκριμένων συμπτωμάτων. όπως αργές σελίδες, χαμηλά ποσοστά καρέ ή υψηλή εγκατάλειψη κατά τη διάρκεια ορισμένων ροών. Θέλετε μετρήσιμα προβλήματα, όχι ενστικτώδη συναισθήματα.
Η έρευνα διερευνά την αιτία: ίσως μια σελίδα περιλαμβάνει δεκάδες κρυφά iframe, ίσως ένα συγκεκριμένο στοιχείο να επανεμφανίζεται πολύ συχνά ή μια τεράστια βιβλιοθήκη προμηθευτών φορτώνεται σε κάθε διαδρομή. Εδώ βασίζεστε σε μεγάλο βαθμό στο React DevTools Profiler και στη χρονολογική σειρά του Chrome.
Η υλοποίηση είναι το σημείο όπου εφαρμόζετε στοχευμένες διορθώσεις—απομνημόνευση ενός ενεργού στοιχείου, εικονικοποίηση μιας μεγάλης λίστας, διαίρεση μιας δέσμης, μεταβίβαση εργασίας σε έναν Web Worker ή ενεργοποίηση SSR για ορισμένες σελίδες. Κάθε αλλαγή θα πρέπει να είναι αρκετά μικρή για να μπορεί να ληφθεί υπόψη.
Η επιβεβαίωση είναι το τελευταίο βήμα και συχνά το πιο παραβλεπόμενοΕπαναλαμβάνετε τα σενάρια δημιουργίας προφίλ και ελέγχετε τους πίνακες ελέγχου μετρήσεων για να βεβαιωθείτε ότι η αλλαγή βελτίωσε πραγματικά τους αριθμούς και δεν εισήγαγε παλινδρομήσεις αλλού στο σύστημα.
Όταν συνδυάζετε τη σωστή δομή React, την προσεκτική απομνημόνευση, τις πρακτικές αμετάβλητης κατάστασης, την εικονικοποίηση λίστας, τον στρατηγικό διαχωρισμό κώδικα, την SSR, τους Web Workers και τη συνεχή μέτρηση, καταλήγετε σε εφαρμογές React που παραμένουν γρήγορες και ανταποκρίνονται ακόμα και καθώς γίνονται πιο περίπλοκες.Οι παραπάνω τεχνικές δεν αφορούν πρόωρο μικρορύθμιση, αλλά την οικοδόμηση μιας αρχιτεκτονικής όπου η απόδοση παραμένει ένα φυσικό υποπροϊόν αντί για μια συνεχή ανταλλαγή πυροβολισμών.

