Από την αρχική της παρουσίαση, το React άλλαξε τη νοοτροπία των προγραμματιστών front-end κατά τη δημιουργία εφαρμογών ιστού. Με το Virtual DOM, το React καθιστά τις ενημερώσεις διεπαφής χρήστη (διεπαφή χρήστη) όσο πιο αποτελεσματικές από ποτέ, ενώ καθιστά την εφαρμογή ιστού σας πιο ακριβή. Γιατί όμως οι εφαρμογές ιστού React σε μεγάλο μέγεθος εξακολουθούν να έχουν κακή απόδοση;
Λοιπόν το κλειδί είναι πώς χρησιμοποιείτε το React.
Μια σύγχρονη βιβλιοθήκη front-end όπως Αντιδρώ δεν κάνει μαγικά την εφαρμογή σας πιο γρήγορη. Ο προγραμματιστής οφείλει να κατανοήσει πώς λειτουργεί το React και πώς τα συστατικά ζουν μέσω των διαφορετικών φάσεων του κύκλου ζωής των συστατικών.
Με το React, μπορείτε να αποκτήσετε πολλές από τις βελτιώσεις που προσφέρει μετρώντας και βελτιστοποιώντας τον τρόπο και τον χρόνο επιστροφής των στοιχείων σας. Το React παρέχει μόνο τα απαραίτητα εργαλεία και λειτουργίες για να γίνει πιο εύκολο.
Σε αυτό το σεμινάριο React, θα μάθετε πώς μπορείτε να μετρήσετε την απόδοση των στοιχείων του React και να τα βελτιστοποιήσετε για να δημιουργήσετε μια εφαρμογή Ιστού React υψηλότερης και καλύτερης απόδοσης. Ομοίως, θα μάθετε πώς μερικές βέλτιστες πρακτικές JavaScript βοηθούν επίσης την εφαρμογή ιστού React να παρουσιάσει μια απρόσκοπτη εμπειρία χρήστη.
Πριν μπείτε σε τεχνικές βελτιστοποίησης, πρέπει να κατανοήσουμε καλύτερα πώς λειτουργεί το React.
Στην καρδιά του React βρίσκεται η σύνταξη JSX και η ικανότητα του React να χτίζει και να συγκρίνει. Εικονικό DOM . Από την κυκλοφορία του, το React έχει επηρεάσει πολλές άλλες βιβλιοθήκες front-end. Βιβλιοθήκες όπως το Vue.js βασίζονται επίσης στην ιδέα των εικονικών DOM.
Δείτε πώς λειτουργεί το React:
Κάθε εφαρμογή React ξεκινά με ένα συστατικό ρίζας και αποτελείται από πολλά συστατικά σε έναν σχηματισμό δέντρου. Τα στοιχεία στο React είναι 'συναρτήσεις' που αφήνουν τη διεπαφή χρήστη βάσει των δεδομένων (υποστήριξη και κατάσταση) που λαμβάνει.
Μπορούμε να το συμβολίσουμε ως F
.
UI = F(data)
Οι χρήστες αλληλεπιδρούν με το περιβάλλον εργασίας χρήστη και προκαλούν αλλαγή στα δεδομένα. Είτε η αλληλεπίδραση κάνει κλικ σε ένα κουμπί, αγγίζει μια εικόνα, σύροντας στοιχεία από μια λίστα, αιτήματα AJAX που καλούν API κ.λπ., όλες αυτές οι αλληλεπιδράσεις αλλάζουν μόνο τα δεδομένα. Δεν προκαλούν ποτέ την άμεση αλλαγή του περιβάλλοντος εργασίας χρήστη.
Εδώ, τα δεδομένα είναι ό, τι καθορίζει την κατάσταση της εφαρμογής ιστού και όχι μόνο αυτό που έχετε αποθηκεύσει στη βάση δεδομένων σας. Ακόμη και κομμάτια των καταστάσεων του εμπρόσθιου άκρου (π.χ. ποιο παράθυρο έχει επιλεγεί αυτή τη στιγμή ή εάν έχει επιλεγεί ένα πλαίσιο αυτή τη στιγμή) αποτελούν μέρος αυτών των δεδομένων.
Όταν υπάρχει αλλαγή σε αυτά τα δεδομένα, το React χρησιμοποιεί τις λειτουργίες των στοιχείων για να αποχωρήσει από το περιβάλλον εργασίας χρήστη, αλλά μόνο ουσιαστικά:
UI1 = F(data1) UI2 = F(data2)
Το React υπολογίζει τις διαφορές μεταξύ της τρέχουσας διεπαφής χρήστη και της νέας διεπαφής χρήστη εφαρμόζοντας έναν συγκριτικό αλγόριθμο στις δύο εκδόσεις του εικονικού DOM.
Changes = Diff(UI1, UI2)
Το React στη συνέχεια προχωρά για να εφαρμόσει μόνο τις αλλαγές στο πραγματικό περιβάλλον χρήστη του προγράμματος περιήγησης.
Όταν τα δεδομένα που σχετίζονται με το στοιχείο αλλάζουν, το React καθορίζει εάν απαιτείται πραγματικά μια ενημέρωση DOM. Αυτό επιτρέπει στο React να αποφεύγει δαπανηρές λειτουργίες χειρισμού DOM στο πρόγραμμα περιήγησης, όπως η δημιουργία κόμβων DOM και η πρόσβαση σε ορισμένες από τις υπάρχουσες περισσότερο από το απαραίτητο.
Αυτός ο επαναλαμβανόμενος υπολογισμός διαφοροποίησης και η αποχώρηση στοιχείων μπορεί να είναι μία από τις πρωταρχικές πηγές των προβλημάτων απόδοσης του React σε οποιαδήποτε εφαρμογή React. Η δημιουργία μιας εφαρμογής React στην οποία η διαφοροποίηση του αλγορίθμου δεν μπορεί να συμβιβαστεί αποτελεσματικά, προκαλώντας έτσι την πλήρη επαναφορά ολόκληρης της εφαρμογής, μπορεί να οδηγήσει σε απογοητευτική και χρονοβόρα εμπειρία.
Αλλά τι ακριβώς βελτιστοποιούμε;
Λοιπόν, κατά την αρχική διαδικασία της αποχώρησης, η React δημιουργεί ένα δέντρο DOM όπως αυτό:
Δεδομένου ότι ορισμένες από τις αλλαγές δεδομένων, αυτό που θέλουμε να κάνει το React είναι να επιστρέψει μόνο τα στοιχεία που επηρεάζονται άμεσα από την αλλαγή (και πιθανώς να παραλείψει τη διαδικασία διαφοράς για τα υπόλοιπα στοιχεία):
Ωστόσο, αυτό που καταλήγει να κάνει το React είναι:
Στην παραπάνω εικόνα, όλοι οι κίτρινοι κόμβοι αποδίδονται και διαφοροποιούνται (diff), με αποτέλεσμα την απώλεια χρόνου / πόρων υπολογιστών. Εδώ θα κάνουμε τις προσπάθειές μας βελτιστοποίησης, κυρίως. Η ρύθμιση κάθε στοιχείου σε απόδοση-διαφοροποίηση (διαφορά) μόνο όταν είναι απαραίτητο θα μας επιτρέψει να ανακτήσουμε αυτούς τους χαμένους κύκλους CPU.
Οι προγραμματιστές της βιβλιοθήκης React το έλαβαν υπόψη και παρείχαν ένα άγκιστρο για να μπορούμε να κάνουμε ακριβώς αυτό: μια λειτουργία που μας επιτρέπει να πούμε στο React πότε είναι εντάξει να παρακάμψουμε την απόδοση ενός στοιχείου.
Όπως ο Rob Pike το θέτει χαριτωμένα ως ένα από τα δικά του κανόνες προγραμματισμού :
Στο μέγεθος. Μην προσαρμόζετε την ταχύτητα έως ότου μετρήσετε και ακόμη και τότε μην το κάνετε, εκτός εάν ένα μέρος του κώδικα επισκιάζει το υπόλοιπο.
Μην βελτιστοποιείτε τον κώδικα που πιστεύετε ότι μπορεί να επιβραδύνει την εφαρμογή σας. Αντ 'αυτού, αφήστε τα εργαλεία μέτρησης απόδοσης της React να σας καθοδηγήσουν στην πορεία.
Το React έχει ένα ισχυρό εργαλείο για αυτό. Όταν χρησιμοποιείτε το react-addons-perf
μπορείτε να λάβετε μια σύνοψη της συνολικής απόδοσης της αίτησής σας.
Η χρήση είναι πολύ απλή:
Import Perf from 'react-addons-perf' Perf.start(); // use the app Perf.stop(); Perf.printWasted();
Αυτό θα εκτυπώσει έναν πίνακα με το χρονικό διάστημα που χάνονται τα στοιχεία κατά την απόδοση.
Η βιβλιοθήκη παρέχει άλλες λειτουργίες που σας επιτρέπουν να εκτυπώνετε διαφορετικές πτυχές του σπαταλημένου χρόνου ξεχωριστά (π.χ., χρησιμοποιώντας τις λειτουργίες printInclusive()
ή printExclusive()
) ή ακόμη και εκτυπώσεις χειρισμών DOM (χρησιμοποιώντας το printOperations()
) .
Εάν είστε οπτικό άτομο τότε react-perf-tool
είναι ακριβώς αυτό που χρειάζεστε.
react-perf-tool
Βασίζεται στη βιβλιοθήκη react-addons-perf
. Σας δίνει έναν πιο οπτικό τρόπο για να διορθώσετε την απόδοση της εφαρμογής σας με το React. Χρησιμοποιεί την υποκείμενη βιβλιοθήκη για τη λήψη μετρήσεων και στη συνέχεια τις εμφανίζει ως γραφήματα.
Πολύ συχνά, αυτός είναι ένας πολύ πιο βολικός τρόπος για να παρατηρήσετε τις μπάρες. Μπορείτε εύκολα να το χρησιμοποιήσετε προσθέτοντας το ως συστατικό στην εφαρμογή σας.
Από προεπιλογή, το React θα εκτελείται, θα αποδίδει το εικονικό DOM και θα συγκρίνει τη διαφορά για κάθε στοιχείο στο δέντρο για κάθε αλλαγή στα στηρίγματα και τις καταστάσεις τους. Αλλά αυτό δεν είναι λογικό, προφανώς.
Καθώς η εφαρμογή σας μεγαλώνει, η προσπάθεια εκ νέου απόδοσης και σύγκρισης ολόκληρου του εικονικού DOM σε κάθε ενέργεια θα επιβραδυνθεί τελικά.
Το React παρέχει έναν απλό τρόπο για τον προγραμματιστή να υποδείξει εάν ένα στοιχείο πρέπει να επανασχεδιαστεί. Εδώ είναι το shouldComponentUpdate
μπαίνει στο παιχνίδι.
function shouldComponentUpdate(nextProps, nextState) { return true; }
Όταν αυτή η συνάρτηση επιστρέφει αληθινή για οποιοδήποτε στοιχείο, επιτρέπει την ενεργοποίηση της διαδικασίας διαφοροποίησης απόδοσης.
Αυτό σας δίνει έναν εύκολο τρόπο ελέγχου της διαδικασίας απόδοσης-απόδοσης. Όταν πρέπει να αποτρέψετε την εκ νέου απόδοση ενός στοιχείου, είναι απλώς ένα αποτέλεσμα falso
της συνάρτησης. Μέσα στη συνάρτηση, μπορείτε να συγκρίνετε το σύνολο υποστηρίξεων και την τρέχουσα κατάσταση, καθώς και τα ακόλουθα για να προσδιορίσετε εάν απαιτείται εκ νέου απόδοση
function shouldComponentUpdate(nextProps, nextState) { return nextProps.id !== this.props.id; }
Για να κάνει αυτή την τεχνική βελτιστοποίησης λίγο πιο εύκολη και πιο αυτοματοποιημένη, το React παρέχει αυτό που είναι γνωστό ως «καθαρό» συστατικό. Α React.PureComponent
είναι ακριβώς σαν ένα React.Component
που εφαρμόζει μια συνάρτηση shouldComponentUpdate()
με μια κενή σύγκριση υποστήριξης και κατάστασης.
Α React.PureComponent
είναι περίπου ισοδύναμο με αυτό:
class MyComponent extends React.Component { shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this.props, nextProps) && shallowCompare(this.state, nextState); } … }
Δεδομένου ότι εκτελεί μια κενή σύγκριση, μπορεί να σας φανεί χρήσιμο μόνο όταν:
forceUpdate()
για να ενημερώσετε το στοιχείο σας.Τι γίνεται αν θα μπορούσατε να χρησιμοποιήσετε React.PureComponent
και εξακολουθείτε να έχετε έναν αποτελεσματικό τρόπο για να δείτε πότε άλλαξε αυτόματα κάποια υποστήριξη ή σύνθετη κατάσταση; Αυτό είναι όπου οι αμετάβλητες δομές δεδομένων κάνουν τη ζωή πιο εύκολη για εμάς.
Η ιδέα πίσω από τη χρήση αμετάβλητων δομών δεδομένων είναι απλή. Όταν ένα αντικείμενο που περιέχει πολύπλοκα δεδομένα αλλάζει, αντί να κάνει τις αλλαγές σε αυτό το αντικείμενο, δημιουργεί ένα αντίγραφο αυτού του αντικειμένου με τις αλλαγές. Αυτό καθιστά την ανίχνευση αλλαγών στα δεδομένα τόσο απλή όσο η σύγκριση της αναφοράς των δύο αντικειμένων.
Μπορείτε να χρησιμοποιήσετε το Object.assign
ή _.extend
(από Underscore.js ή Lodash):
const newValue2 = Object.assign({}, oldValue); const newValue2 = _.extend({}, oldValue);
Ακόμα καλύτερα, μπορείτε να χρησιμοποιήσετε μια βιβλιοθήκη που παρέχει αμετάβλητες δομές δεδομένων:
var map1 = Immutable.Map({a:1, b:2, c:3}); var map2 = map1.set('b', 2); assert(map1.equals(map2) === true); var map3 = map1.set('b', 50); assert(map1.equals(map3) === false);
Εδώ, Immutable.Map
παρέχεται από τη βιβλιοθήκη Αμετάβλητο.js .
Κάθε φορά που ένας χάρτης ενημερώνεται με τη μέθοδο set
, ένας νέος χάρτης επιστρέφεται μόνο εάν η καθορισμένη λειτουργία άλλαξε την υποκείμενη τιμή. Διαφορετικά, επιστρέφεται ο ίδιος χάρτης.
Μπορείτε να μάθετε περισσότερα σχετικά με τη χρήση αμετάβλητων δομών δεδομένων εδώ .
Όταν αναπτύσσετε μια εφαρμογή με το React, λαμβάνετε πολύ χρήσιμες προειδοποιήσεις και μηνύματα σφάλματος. Αυτά καθιστούν τον εντοπισμό σφαλμάτων και προβλημάτων κατά την ανάπτυξη πολύ εύκολο. Αλλά κόστισαν επίσης μέρος της παράστασης.
Αν κοιτάξετε τον πηγαίο κώδικα React, θα δείτε πολλά σημάδια if (process.env.NODE_ENV != 'production')
. Αυτά τα κομμάτια κώδικα που εκτελείται στο React στο περιβάλλον ανάπτυξης δεν είναι κάτι που χρειάζεται ο χρήστης. Για περιβάλλοντα παραγωγής, αυτός ο περιττός κωδικός μπορεί να απορριφθεί.
Εάν προωθήσατε το έργο σας χρησιμοποιώντας create-react-app
, τότε μπορείτε να εκτελέσετε npm run build
για την παραγωγή της παραγωγής χωρίς αυτόν τον επιπλέον κωδικό. Εάν χρησιμοποιείτε απευθείας το Webpack, μπορείτε να εκτελέσετε webpack -p
(που είναι το ισοδύναμο του webpack --optimize-minimize --define process.env.NODE_ENV=''production''
.
Είναι πολύ συνηθισμένο να βλέπουμε συναρτήσεις που συνδέονται με το περιεχόμενο του στοιχείου μέσα στη συντελεσμένη απόδοση. Αυτό συμβαίνει συχνά όταν χρησιμοποιούμε αυτές τις λειτουργίες για τον χειρισμό συμβάντων πρώιμου σταδίου.
// Creates a new `handleUpload` function during each render() // ...as do inlined arrow functions this.handleUpload(files)} />
Αυτό θα προκαλέσει το render()
δημιουργήστε μια νέα συνάρτηση σε κάθε απόδοση. Ένας καλύτερος τρόπος για να κάνετε το ίδιο είναι:
class App extends React.Component { constructor(props) { super(props); this.handleUpload = this.handleUpload.bind(this); } render() { … … } }
Για εφαρμογές ιστού σελίδας React, συνήθως καταλήγουμε να συνδυάζουμε όλο τον κώδικα JavaScript front-end σε ένα μόνο ελαχιστοποιημένο αρχείο. Αυτό λειτουργεί ιδανικά για μεσαίου μεγέθους εφαρμογές ιστού. Αλλά καθώς η εφαρμογή αρχίζει να μεγαλώνει, η παράδοση αυτού του αρχείου JavaScript που είναι συνδεδεμένο στο πρόγραμμα περιήγησης μπορεί να είναι μια πολύ χρονοβόρα διαδικασία.
Εάν χρησιμοποιείτε το Webpack για να δημιουργήσετε την εφαρμογή σας, μπορείτε να ενισχύσετε τον κωδικό σας διαχωρίζοντας τις δυνατότητές του για να διαχωρίσετε επίσης τον ενσωματωμένο κωδικό εφαρμογής σας σε πολλά 'κομμάτια' και να τα παραδώσετε στο πρόγραμμα περιήγησης στις απαραίτητες ώρες.
Υπάρχουν δύο τύποι διαχωρισμού: διαχωρισμός πόρων και διαχωρισμός κωδικών κατά παραγγελία.
Με το διαχωρισμό πόρων, διαχωρίζετε το περιεχόμενο πόρου σε πολλά αρχεία. Για παράδειγμα, χρησιμοποιώντας το CommonsChunkPlugin, μπορείτε να εξαγάγετε κοινό κώδικα (όπως όλες οι εξωτερικές βιβλιοθήκες) σε ένα σωστό κομμάτι αρχείο. Χρησιμοποιώντας το ExtractTextWebpackPlugin, μπορείτε να εξαγάγετε όλο τον κώδικα CSS σε ένα ξεχωριστό αρχείο CSS.
Αυτός ο τύπος διαχωρισμού θα σας βοηθήσει με δύο τρόπους. Βοηθά τη μηχανή αναζήτησης να αποθηκεύει αυτούς τους πόρους που αλλάζουν λιγότερο συχνά. Θα βοηθήσει επίσης τον ερευνητή να εκμεταλλευτεί την παράλληλη λήψη για να μειώσει ενδεχομένως το χρόνο φόρτωσης.
Ένα πιο αξιοσημείωτο χαρακτηριστικό του Webpack είναι ο διαχωρισμός του κώδικα κατά παραγγελία. Αυτό μπορεί να διατηρήσει μικρή την αρχική λήψη μειώνοντας το χρόνο που απαιτείται για τη φόρτωση της εφαρμογής. Το πρόγραμμα περιήγησης μπορεί, κατά συνέπεια, να κατεβάσει κομμάτια κώδικα κατ 'απαίτηση όταν το χρειάζεται η εφαρμογή.
Μπορείτε να μάθετε περισσότερα για το διαχωρισμό κώδικα Webpack εδώ .
Η ομάδα αρχείων JS της εφαρμογής React είναι συνήθως πολύ μεγάλη, έτσι ώστε να γίνει πιο γρήγορη η φόρτωση της ιστοσελίδας, μπορούμε να ενεργοποιήσουμε το Gzip στον διακομιστή ιστού (Apache, Nginx κ.λπ.)
Όλες οι σύγχρονες μηχανές αναζήτησης υποστηρίζουν και διαπραγματεύονται αυτόματα τη συμπίεση Gzip για αιτήματα HTTP. Η ενεργοποίηση της συμπίεσης Gzip μπορεί να μειώσει το μέγεθος της απόκρισης που μεταφέρθηκε κατά 90%, γεγονός που μπορεί να μειώσει τον χρόνο λήψης ενός πόρου, να μειώσει τη χρήση δεδομένων για τον πελάτη και να βελτιώσει τον χρόνο απόδοσης των σελίδων σας.
Ελέγξτε την τεκμηρίωση για τον διακομιστή ιστού σας για να δείτε πώς να ενεργοποιήσετε τη συμπίεση:
Θα πρέπει να χρησιμοποιήσετε το ESLint για σχεδόν όλα τα έργα JavaScript. Το React δεν είναι η διαφορά.
Με eslint-plugin-react
, θα αναγκάσετε τον εαυτό σας να προσαρμοστεί σε πολλούς από τους κανόνες προγραμματισμού της React, οι οποίοι μπορούν να ωφελήσουν τον κώδικά σας μακροπρόθεσμα και να αποφύγουν πολλά κοινά προβλήματα και ταλαιπωρίες που προκύπτουν λόγω κακής σύνταξης κώδικα.
Για να αξιοποιήσετε στο έπακρο το React, πρέπει να αξιοποιήσετε τα εργαλεία και τις τεχνικές του. Η απόδοση μιας διαδικτυακής εφαρμογής React έγκειται στην απλότητα των στοιχείων της. Η υπερβολή του αλγορίθμου διαφοροποίησης και απόδοσης μπορεί να κάνει την εφαρμογή σας να έχει χαμηλή απόδοση με πολύ απογοητευτικό τρόπο.
Προτού μπορέσετε να βελτιστοποιήσετε την εφαρμογή σας, πρέπει να καταλάβετε πώς λειτουργούν τα στοιχεία React και πώς αποδίδονται στο πρόγραμμα περιήγησής σας. Οι μέθοδοι κύκλου ζωής της React σάς δίνουν τρόπους για να αποτρέψετε την εκ νέου απόδοση του συστατικού σας άσκοπα. Εξαλείψτε αυτά τα εμπόδια και θα έχετε την απόδοση της εφαρμογής που αξίζουν οι χρήστες σας.
Παρόλο που υπάρχουν περισσότεροι τρόποι βελτιστοποίησης μιας εφαρμογής ιστού με το React, η βελτίωση των στοιχείων για ενημέρωση μόνο όταν απαιτείται αποτρέπει τη βελτίωση της απόδοσης.
Πώς μετράτε και βελτιστοποιείτε την απόδοση της εφαρμογής ιστού σας με το React; Μοιραστείτε το στα παρακάτω σχόλια.