Repariere es
Blog, WooCommerce

Γιατί το WooCommerce γονατίζει στα 5.000 προϊόντα

Einführung

Το e-shop ήταν γρήγορο. Με οκτακόσια προϊόντα, όλα δούλευαν: η αρχική άνοιγε αμέσως, το admin ανταποκρινόταν, ο υπάλληλος έβρισκε μια παραγγελία σε δευτερόλεπτα. Δύο χρόνια μετά ο κατάλογος έχει πάει στα πέντε χιλιάδες, τίποτα άλλο δεν άλλαξε — και τώρα η λίστα προϊόντων στο διαχειριστικό θέλει δέκα δευτερόλεπτα να φορτώσει, τα φίλτρα στην κατηγορία κολλάνε και ο hoster στέλνει email για υπέρβαση πόρων.

Η πρώτη αντίδραση είναι σχεδόν πάντα η ίδια: «θέλουμε μεγαλύτερο server». Καμιά φορά όντως θέλει. Τις περισσότερες φορές όμως ο server αγοράζει χρόνο, δεν λύνει το πρόβλημα — γιατί το πρόβλημα δεν είναι ο όγκος καθαυτός, αλλά το πόσο ακριβά κοστίζει στο WooCommerce κάθε ερώτηση που κάνεις πάνω σε αυτόν τον όγκο. Παρακάτω είναι τι σπάει συνήθως στην πράξη, με ονόματα, και τι από αυτά διορθώνεται μέσα σε μία μέρα δουλειάς.

Δεν φταίνε τα 5.000 προϊόντα. Φταίει το τι κουβαλάει το καθένα

Στο WooCommerce ένα προϊόν δεν είναι μία γραμμή σε έναν πίνακα προϊόντων. Είναι μία εγγραφή στον πίνακα των άρθρων του WordPress, συν ένα σωρό γραμμές μεταδεδομένων: τιμή, τιμή προσφοράς, SKU, απόθεμα, βάρος, διαστάσεις, ορατότητα, ό,τι προσθέτει κάθε plugin. Δεκάδες γραμμές ανά προϊόν, εύκολα περισσότερες αν τρέχεις feeds, ERP σύνδεση ή προσαρμοσμένα πεδία.

Αν τα προϊόντα έχουν παραλλαγές, ο πολλαπλασιασμός γίνεται σοβαρός: κάθε παραλλαγή είναι ξεχωριστή εγγραφή με δικά της μεταδεδομένα. Ένας κατάλογος πέντε χιλιάδων προϊόντων με μερικές παραλλαγές το καθένα δεν είναι κατάλογος πέντε χιλιάδων εγγραφών — είναι δεκάδες χιλιάδες εγγραφές και ένας πίνακας μεταδεδομένων που ξεπερνά άνετα το εκατομμύριο γραμμές. Ο ακριβής αριθμός εξαρτάται απόλυτα από το τι έχεις εγκατεστημένο, γι’ αυτό η πρώτη δουλειά είναι να τον μετρήσεις στο δικό σου site αντί να τον υποθέσεις.

Γιατί το νιώθεις ξαφνικά και όχι σταδιακά: μέχρι ένα σημείο, τα δεδομένα και οι δείκτες της βάσης χωράνε στη μνήμη του server. Από ένα σημείο και μετά δεν χωράνε, και η βάση αρχίζει να διαβάζει από τον δίσκο. Η καμπύλη δεν είναι ευθεία γραμμή — έχει σκαλοπάτι. Γι’ αυτό ο πελάτης λέει «μια χαρά ήταν, από τη μια μέρα στην άλλη χάλασε».

Το πρώτο ύποπτο: τα autoloaded δεδομένα στις ρυθμίσεις

Ο πίνακας ρυθμίσεων του WordPress έχει μια στήλη που ορίζει αν μια εγγραφή φορτώνεται αυτόματα σε κάθε αίτημα. Όχι στις σελίδες που τη χρειάζονται — σε κάθε αίτημα, από την αρχική μέχρι το AJAX του καλαθιού.

Σε ένα e-shop που ζει χρόνια, εκεί μέσα μαζεύονται πράγματα: ρυθμίσεις από plugins που απεγκαταστάθηκαν αλλά δεν καθάρισαν, ουρές συγχρονισμού, αποθηκευμένα αποτελέσματα που κάποιος έγραψε με λάθος τρόπο, logs που κατέληξαν σε ρύθμιση αντί για αρχείο. Δεν είναι σπάνιο να βρεις μερικά megabytes να φορτώνονται πριν καν αρχίσει να χτίζεται η σελίδα.

Η μέτρηση είναι απλή: ρώτα τη βάση ποιες autoloaded εγγραφές είναι οι μεγαλύτερες και δες τα ονόματά τους. Συνήθως δύο ή τρεις ένοχοι εξηγούν το μεγαλύτερο μέρος. Το καθάρισμα θέλει προσοχή και backup — μερικά από αυτά τα ονόματα ανήκουν σε ενεργά plugins και δεν σβήνονται.

Τα προσωρινά δεδομένα, και γιατί το «καθάρισα τα transients» δεν κρατάει

Το WooCommerce αποθηκεύει προσωρινά αποτελέσματα για να μην ξαναϋπολογίζει τα ίδια πράγματα: μετρήσεις προϊόντων ανά κατηγορία, εύρη τιμών για τα φίλτρα, ό,τι θεωρεί ακριβό. Αν το site δεν έχει μόνιμο object cache, όλα αυτά αποθηκεύονται στη βάση.

Καταλαβαίνεις την ειρωνεία: ο μηχανισμός που υπάρχει για να μη ρωτάς τη βάση, γράφει και διαβάζει από τη βάση. Σε μικρό site δεν φαίνεται. Σε πέντε χιλιάδες προϊόντα με φίλτρα και συνεχείς ενημερώσεις αποθέματος, ο πίνακας ρυθμίσεων γίνεται πεδίο μάχης — και κάθε ενημέρωση προϊόντος ακυρώνει και ξαναγράφει.

Γι’ αυτό το «μπήκα και καθάρισα τα transients, στρώσε λίγο» επαναλαμβάνεται κάθε δύο εβδομάδες. Η πραγματική λύση είναι ένας μόνιμος object cache — Redis ή Memcached — ώστε τα προσωρινά δεδομένα να ζουν στη μνήμη και να μην αγγίζουν τη βάση καθόλου. Είναι και η μοναδική αλλαγή αυτής της λίστας που, σε πολλά e-shops, γίνεται αισθητή την ίδια μέρα.

Το διαχειριστικό πεθαίνει πρώτο, και κανείς δεν το μετράει

Όλα τα εργαλεία ταχύτητας μετρούν τη βιτρίνα. Κανένα δεν μετρά την οθόνη όπου η ομάδα σου περνάει οκτώ ώρες τη μέρα.

Η λίστα προϊόντων στο διαχειριστικό είναι από τα βαρύτερα ερωτήματα ολόκληρου του WordPress: μετράει πόσα προϊόντα υπάρχουν σε κάθε κατάσταση για να δείξει τους αριθμούς στην κορυφή, τραβάει μεταδεδομένα για κάθε γραμμή, και μετά κάθε plugin προσθέτει τη δική του στήλη με τα δικά της ερωτήματα. Αν ταξινομήσεις κατά SKU ή φιλτράρεις με ένα προσαρμοσμένο πεδίο, η βάση συχνά δεν έχει δείκτη για αυτό και σαρώνει.

Το πρακτικό τεστ: άνοιξε τη λίστα προϊόντων και τη λίστα παραγγελιών ενώ το κατάστημα δέχεται κίνηση, με χρονόμετρο. Αν το admin είναι αργό ενώ η βιτρίνα φαίνεται μια χαρά, το πρόβλημα είναι στη βάση και στα plugins — όχι στις εικόνες, όχι στο CDN, όχι στο θέμα.

Οι βοηθητικοί πίνακες που έφτιαξε το WooCommerce ακριβώς γι’ αυτό

Το WooCommerce έχει ήδη αναγνωρίσει το πρόβλημα και κρατά ξεχωριστούς, επίπεδους πίνακες αναζήτησης: έναν με τα βασικά στοιχεία κάθε προϊόντος (τιμή, απόθεμα, βαθμολογία, ορατότητα), έναν για τα χαρακτηριστικά που χρησιμοποιούν τα φίλτρα, και τους πίνακες αναφορών για τις παραγγελίες.

Όταν αυτοί οι πίνακες είναι σωστοί, ένα φίλτρο τιμής είναι ένα γρήγορο ερώτημα σε μία στήλη με δείκτη. Όταν είναι άδειοι, ελλιπείς ή ξεπερασμένοι — και ξεπερνιούνται συχνά μετά από μαζικές εισαγωγές, migration, ή απευθείας ενημερώσεις στη βάση από συγχρονισμό ERP — το WooCommerce επιστρέφει στον παλιό, ακριβό τρόπο. Το σύμπτωμα είναι χαρακτηριστικό: το φίλτρο τιμής δείχνει λάθος εύρος ή γυρίζει προϊόντα που δεν ταιριάζουν, και η κατηγορία αργεί δυσανάλογα σε σχέση με το προϊόν.

Η αναδημιουργία τους γίνεται από τα εργαλεία του WooCommerce και είναι από τα πρώτα πράγματα που πρέπει να ελέγξεις. Το ίδιο ισχύει και για την αποθήκευση παραγγελιών σε ξεχωριστούς πίνακες: αν το κατάστημα έχει χρόνια παραγγελιών και τρέχει ακόμα με τον παλιό τρόπο, το διαχειριστικό των παραγγελιών πληρώνει το τίμημα σε κάθε άνοιγμα.

Τα φίλτρα και η αναζήτηση: εκεί σε τρώει ο κατάλογος

Η αναζήτηση προϊόντων του WordPress ψάχνει με ταίριασμα κειμένου μέσα σε τίτλους και περιγραφές. Αυτό σημαίνει σάρωση: όσο μεγαλώνει ο κατάλογος, τόσο ακριβότερη γίνεται κάθε αναζήτηση — και οι αναζητήσεις δεν αποθηκεύονται σε cache, γιατί κάθε επισκέπτης γράφει κάτι άλλο.

Το ίδιο ισχύει για τα φίλτρα με πολλά χαρακτηριστικά. Κάθε επιπλέον επιλεγμένο φίλτρο προσθέτει ένα ακόμα κομμάτι στο ερώτημα, και ο συνδυασμός «χρώμα και μέγεθος και μάρκα και εύρος τιμής» σε πέντε χιλιάδες προϊόντα είναι σαφώς πιο ακριβός από το άθροισμα των μερών του. Αν επιπλέον το θέμα υπολογίζει μετρητές δίπλα σε κάθε επιλογή, πολλαπλασίασε.

Η κατεύθυνση της λύσης εδώ δεν είναι «γράψε καλύτερο SQL» — είναι να βγάλεις την αναζήτηση και τα φίλτρα από το SQL, σε έναν μηχανισμό που έχει φτιαχτεί για αυτή τη δουλειά και δουλεύει πάνω σε δικό του ευρετήριο. Είναι μεγαλύτερη δουλειά από τις προηγούμενες, αλλά σε κατάλογο αυτού του μεγέθους είναι συνήθως η αλλαγή με τη μεγαλύτερη διαφορά για τον επισκέπτη.

Το χρονοπρόγραμμα που τρέχει πάνω στις πλάτες των επισκεπτών

Το WordPress δεν έχει δικό του χρονοπρογραμματιστή. Σε κάθε επίσκεψη ελέγχει αν υπάρχει προγραμματισμένη εργασία που έπρεπε να είχε τρέξει, και αν υπάρχει, την τρέχει — με τον επισκέπτη να περιμένει.

Σε ένα e-shop με μεγάλο κατάλογο, αυτές οι εργασίες δεν είναι μικρές: συγχρονισμός αποθέματος με το ERP, παραγωγή feeds για τα καταστήματα σύγκρισης, προσφορές που ξεκινούν ή λήγουν, μαζικές ενημερώσεις τιμών, ουρές email. Ένας ατυχής επισκέπτης πέφτει πάνω στη βαριά εργασία και βλέπει σελίδα που δεν φορτώνει — ή, χειρότερα, το σύστημα ξεκινά την ίδια εργασία δεύτερη φορά επειδή η πρώτη δεν πρόλαβε να τελειώσει.

Η διόρθωση είναι τυπική και γρήγορη: απενεργοποιείς τον έλεγχο ανά επίσκεψη και βάζεις τον server να καλεί το χρονοπρόγραμμα σε σταθερό διάστημα. Πάρε πρώτα μια εικόνα του τι τρέχει και πόσο συχνά — συχνά αποκαλύπτεται μια εργασία κάθε λεπτού από ένα plugin που κανείς δεν θυμάται ότι εγκατέστησε.

Τι διορθώνεται πραγματικά σε μία μέρα

Με τη σειρά που τα κάνουμε συνήθως, από το πιο σίγουρο προς το πιο απαιτητικό:

  • Μόνιμος object cache (Redis ή Memcached) — βγάζει τα προσωρινά δεδομένα από τη βάση.
  • Καθάρισμα των autoloaded ρυθμίσεων, με backup και έναν έναν τους ενόχους.
  • Χρονοπρόγραμμα από τον server αντί για κάθε επίσκεψη.
  • Αναδημιουργία των βοηθητικών πινάκων του WooCommerce και έλεγχος αν η αποθήκευση παραγγελιών είναι στη σύγχρονη μορφή.
  • Εντοπισμός των plugins που προσθέτουν ερωτήματα σε κάθε σελίδα του admin, και απενεργοποίηση όσων δεν χρησιμοποιεί κανείς.
  • Δείκτες στα μεταδεδομένα για τα συγκεκριμένα πεδία που όντως φιλτράρετε — με μέτρηση πριν και μετά, όχι στα τυφλά.

Και τι nicht λύνεται σε μία μέρα, για να μην το υποσχεθεί κανείς: η αρχιτεκτονική του συγχρονισμού με το ERP όταν στέλνει χιλιάδες μεμονωμένες ενημερώσεις αντί για παρτίδες, η αντικατάσταση της αναζήτησης και των φίλτρων, και το ξεμπέρδεμα από plugin που έχει χωθεί σε κάθε ερώτημα προϊόντος. Αυτά είναι έργα, όχι ρυθμίσεις — και θέλουν σχεδιασμό πριν από την περίοδο που δεν σηκώνει αλλαγές, όχι μέσα σε αυτήν.

Τι να μετρήσεις πριν αγγίξεις οτιδήποτε

Κάθε μία από τις παραπάνω αλλαγές μπορεί να μη σου κάνει τίποτα, αν το δικό σου πρόβλημα είναι αλλού. Γι’ αυτό η σειρά είναι: μέτρα, άλλαξε ένα πράγμα, ξαναμέτρα.

Τι χρειάζεσαι: ένα εργαλείο που δείχνει τα ερωτήματα ανά σελίδα και ποιο plugin τα κάνει, ενεργοποιημένο για διαχειριστές· το αρχείο καταγραφής αργών ερωτημάτων της βάσης, ανοιχτό για λίγες μέρες· και μετρήσεις σε ώρα κίνησης, όχι Κυριακή πρωί. Μέτρα και τις δύο πλευρές — τη σελίδα κατηγορίας με φίλτρα και τη λίστα προϊόντων στο διαχειριστικό — γιατί πολύ συχνά δείχνουν διαφορετικό ένοχο.

Αν θέλεις την ευρύτερη εικόνα του τι σημαίνει απόδοση σε μεγάλο κατάστημα, από το CDN μέχρι τη διαχείριση παραγγελιών, την έχουμε γράψει ξεχωριστά στο WooCommerce performance optimization για μεγάλα e-shops. Εδώ κρατήσαμε επίτηδες τη ματιά στη βάση και στο διαχειριστικό, γιατί εκεί ζει το συγκεκριμένο σκαλοπάτι των χιλιάδων προϊόντων.

Ο κατάλογος δεν πρόκειται να μικρύνει

Το να φτάσει ένα e-shop τα πέντε χιλιάδες προϊόντα δεν είναι πρόβλημα — είναι το ζητούμενο. Το πρόβλημα είναι ότι οι ρυθμίσεις με τις οποίες στήθηκε στα οκτακόσια δεν αναθεωρήθηκαν ποτέ, και σε αυτό το μέγεθος κάθε κακή απόφαση κοστίζει πολλαπλάσια.

Η καλή είδηση είναι ότι τα μισά από όσα διαβάσατε παραπάνω είναι ρυθμίσεις μιας ημέρας, όχι ανακατασκευή. Η κακή είναι ότι δεν φαίνονται σε κανένα εργαλείο ταχύτητας — χρειάζεται κάποιος να ανοίξει τη βάση και να δει τι πραγματικά τρέχει.

Αν αναγνωρίζεις το e-shop σου σε αυτή την περιγραφή, ξεκίνα από τη βελτιστοποίηση ταχύτητας με μέτρηση, όχι με αγορά μεγαλύτερου server. Κι αν προτιμάς να το κοιτάξει κάποιος που ξέρει πού κρύβονται αυτά τα ερωτήματα, πες μας τι τρέχεις — τι πλατφόρμα, πόσα προϊόντα, πού το νιώθεις να αργεί.

Vorheriger Beitrag
Το Magento zero-day που χτυπά και τα ενημερωμένα καταστήματα