Preload, prefetch και preconnect: πότε βοηθά πραγματικά το καθένα
Τα resource hints είναι χρήσιμα όταν αντιστοιχούν σε πραγματικά σημεία συμφόρησης του browser. Όταν χρησιμοποιούνται στα τυφλά, προσθέτουν θόρυβο προτεραιοτήτων και μερικές φορές κάνουν τις σελίδες πιο αργές.
Πίνακας περιεχομένων
- Τα resource hints δεν είναι μαγεία
- Τι κάνει ήδη καλά ο browser
- Preload: για πόρους της τρέχουσας σελίδας που ανακαλύπτονται πολύ αργά
- Preload και LCP images
- Prefetch: για την επόμενη σελίδα, όχι για αυτήν
- Preconnect: για ακριβές συνδέσεις σε σημαντικά origins
- DNS-prefetch: ο ελαφρύτερος συγγενής
- Πώς να αποφασίσετε: μια πρακτική ροή εργασίας
- 1. Εντοπίστε το bottleneck
- 2. Προσθέστε ένα hint κάθε φορά
- 3. Ελέγξτε τις παρενέργειες προτεραιότητας
- 4. Επαληθεύστε headers και caching
- Συνηθισμένα λάθη
- Preloading υπερβολικά πολλών πραγμάτων
- Χρήση prefetch για απαιτούμενους πόρους
- Preconnecting σε κάθε third party
- Ξεχνώντας τις mobile συνθήκες
- Ένας απλός πίνακας αποφάσεων
- Ο ήρεμος κανόνας
Τα resource hints δεν είναι μαγεία
Τα preload, prefetch και preconnect αντιμετωπίζονται συχνά ως checklist απόδοσης. Προσθέτετε μερικά tags στο <head>, τρέχετε ξανά το Lighthouse, νιώθετε καλύτερα. Δεν λειτουργούν έτσι.
Αυτά τα hints είναι οδηγίες προς το pipeline φόρτωσης του browser. Μπορούν να βοηθήσουν όταν γνωρίζετε κάτι που ο browser δεν μπορεί να ανακαλύψει αρκετά νωρίς. Μπορούν να βλάψουν όταν μαντεύετε, δίνετε υπερβολική προτεραιότητα σε μη κρίσιμη εργασία ή προθερμαίνετε συνδέσεις που οι χρήστες δεν θα χρειαστούν ποτέ.
Η σύντομη εκδοχή:
- Χρησιμοποιήστε
preloadγια πόρους που απαιτούνται για την τρέχουσα σελίδα, αλλά ανακαλύπτονται πολύ αργά. - Χρησιμοποιήστε
prefetchγια πιθανούς πόρους μελλοντικής πλοήγησης, όχι για απαραίτητα στοιχεία της τρέχουσας σελίδας. - Χρησιμοποιήστε
preconnectγια σημαντικά third-party origins όπου η εγκατάσταση της σύνδεσης είναι πραγματική καθυστέρηση.
Το πρακτικό ερώτημα δεν είναι «ποιο hint είναι το ταχύτερο;» Είναι «τι περιμένει ο browser και μπορεί αυτό το hint να αφαιρέσει αυτή την αναμονή;»
Τι κάνει ήδη καλά ο browser
Οι σύγχρονοι browsers δεν είναι παθητικοί μηχανισμοί λήψης αρχείων. Κάνουν parse το HTML, σαρώνουν εκ των προτέρων για πόρους, αναθέτουν προτεραιότητες, επαναχρησιμοποιούν συνδέσεις, καθυστερούν εργασία που δεν είναι ορατή και προσαρμόζονται στις συνθήκες δικτύου.
Αυτό σημαίνει ότι τα resource hints πρέπει να είναι επιλεκτικά. Αν ένα stylesheet, script, image ή font ανακαλύπτεται ήδη νωρίς και έχει τη σωστή προτεραιότητα, η προσθήκη ενός hint μπορεί να μην κάνει τίποτα. Ακόμη χειρότερα, μπορεί να ανταγωνιστεί πόρους που έχουν μεγαλύτερη σημασία.
Πριν προσθέσετε hints, κοιτάξτε ένα waterfall trace στο DevTools ή μια εργαστηριακή αναφορά. Αν χρησιμοποιείτε Lighthouse, ξεκινήστε από τα diagnostics και όχι από τη βαθμολογία· έχουμε ξεχωριστό οδηγό για την ανάγνωση μιας αναφοράς Lighthouse χωρίς πανικό — αλλά σημειώστε ότι το σωστό URL είναι case-sensitive, οπότε χρησιμοποιήστε το συνδεδεμένο άρθρο από την πλοήγηση του site σας αν χρειαστεί.
Τα πραγματικά στοιχεία είναι συνήθως ορατά σε τρία σημεία:
- Ένας κρίσιμος πόρος ξεκινά αργά επειδή ο browser τον ανακαλύπτει αργά.
- Μια σύνδεση σε ένα σημαντικό origin χρειάζεται αισθητό χρόνο πριν από το πρώτο request.
- Ένας πόρος της επόμενης σελίδας είναι πολύ προβλέψιμος και φθηνός για λήψη σε idle time.
Αν τίποτα από αυτά δεν ισχύει, ένα hint είναι πιθανότατα διακοσμητικό.
Preload: για πόρους της τρέχουσας σελίδας που ανακαλύπτονται πολύ αργά
Το preload λέει στον browser: «Φέρε αυτόν τον πόρο τώρα, επειδή η τρέχουσα σελίδα θα τον χρειαστεί.»
Ένα τυπικό παράδειγμα είναι ένα web font που αναφέρεται μέσα στο CSS. Ο browser πρέπει να κατεβάσει το HTML, να ανακαλύψει το CSS, να κατεβάσει το CSS, να το κάνει parse, να ανακαλύψει το font και μετά να ζητήσει το font. Αν αυτό το font είναι σημαντικό για κείμενο above-the-fold, η ανακάλυψη μπορεί να είναι αρκετά αργή ώστε να προκαλέσει layout shifts ή καθυστερημένη απόδοση κειμένου.
Ένα preload μπορεί να μετακινήσει αυτό το request νωρίτερα:
<link rel='preload' href='/fonts/inter-var.woff2' as='font' type='font/woff2' crossorigin>
Το attribute as έχει σημασία. Λέει στον browser τι είδους πόρος είναι αυτός, κάτι που επηρεάζει την προτεραιότητα, το caching, το content security policy και τα request headers. Τα fonts συνήθως χρειάζονται επίσης crossorigin, ακόμη κι όταν σερβίρονται από το ίδιο site, επειδή η λήψη fonts χρησιμοποιεί CORS mode.
Καλοί υποψήφιοι για preload περιλαμβάνουν:
- Το κύριο web font που χρησιμοποιείται για ορατό κείμενο.
- Ένα hero image που είναι το Largest Contentful Paint element και δεν είναι νωρίς ανακαλύψιμο.
- Ένα κρίσιμο CSS file που φορτώνεται έμμεσα.
- Ένα module ή script που χρειάζεται πολύ νωρίς, αλλά κρύβεται πίσω από άλλο script.
Κακοί υποψήφιοι για preload περιλαμβάνουν:
- Κάθε font weight στο design system.
- Images below the fold.
- Scripts που δεν χρειάζονται για την αρχική απόδοση.
- Πόρους που ο browser ανακαλύπτει ήδη στο πρώτο HTML chunk.
Το preload είναι ισχυρό επειδή επηρεάζει την προτεραιότητα της τρέχουσας σελίδας. Αυτός είναι και ο λόγος που είναι εύκολο να χρησιμοποιηθεί λάθος. Αν κάνετε preload πέντε μεγάλα assets, δεν βοηθάτε πλέον τον browser. Διαφωνείτε μαζί του.
Τα fonts είναι η κλασική περίπτωση. Το preload ενός κύριου font file μπορεί να βοηθήσει. Το preload έξι weights και italics συνήθως κάνει τα πράγματα χειρότερα. Αν τα fonts είναι το bottleneck σας, διορθώστε πρώτα το font set· ο οδηγός μας για το γιατί τα web fonts παραμένουν η πιο εύκολη νίκη απόδοσης στα περισσότερα sites καλύπτει αυτό το cleanup με περισσότερες λεπτομέρειες.
Preload και LCP images
Το preload ενός LCP image μπορεί να είναι χρήσιμο όταν το image δεν είναι ορατό στο αρχικό HTML. Συνηθισμένες αιτίες περιλαμβάνουν CSS background images, client-rendered components ή responsive image logic που εμφανίζεται αργά.
Αλλά αν το hero image σας βρίσκεται ήδη στο HTML ως <img> με λογικά srcset, sizes, dimensions και χωρίς lazy loading, ο browser πιθανότατα μπορεί να το βρει γρήγορα. Σε αυτή την περίπτωση, η προσθήκη fetchpriority='high' μπορεί να είναι καταλληλότερη από το preload, ανάλογα με τη σελίδα.
Ένα καλό τεστ: αν το image request ξεκινά αργά στο waterfall και γίνεται το LCP element, εξετάστε το preload. Αν ξεκινά νωρίς αλλά κατεβαίνει αργά, το πρόβλημα είναι το μέγεθος, το format, η συμπεριφορά του CDN ή το server latency — όχι η ανακάλυψη. Για αποφάσεις γύρω από image formats, δείτε πότε το AVIF ξεπερνά το WebP και πότε όχι.
Prefetch: για την επόμενη σελίδα, όχι για αυτήν
Το prefetch λέει στον browser: «Αυτός ο πόρος μπορεί να χρειαστεί σύντομα, αλλά δεν απαιτείται αυτή τη στιγμή.»
Αυτή η διάκριση είναι σημαντική. Το prefetch είναι σκόπιμα χαμηλής προτεραιότητας. Ο browser μπορεί να το φέρει σε idle time και να το αποθηκεύσει για μεταγενέστερη χρήση. Μπορεί επίσης να το παραλείψει σε κακές συνδέσεις, data-saving modes ή υπό πίεση μνήμης.
Χρησιμοποιήστε prefetch όταν η πρόθεση του χρήστη είναι αρκετά ισχυρή ώστε να κάνει πιθανό τον επόμενο πόρο.
Καλοί υποψήφιοι για prefetch περιλαμβάνουν:
- Το επόμενο βήμα σε ένα multi-page checkout.
- Αποτελέσματα αναζήτησης αφού ο χρήστης αρχίσει να πληκτρολογεί ένα query, αν το επόμενο route είναι προβλέψιμο.
- Σελίδες documentation που συνδέονται από έναν πίνακα περιεχομένων όταν ο χρήστης διαβάζει ενεργά κοντινό περιεχόμενο.
- Route chunks σε ένα single-page app αφού ο χρήστης κάνει hover ή εστιάσει σε ένα navigation item.
Κακοί υποψήφιοι για prefetch περιλαμβάνουν:
- Ολόκληρο το navigation tree σας.
- Μεγάλα videos ή image galleries.
- Third-party scripts «για κάθε ενδεχόμενο».
- Σελίδες που οι χρήστες σπάνια επισκέπτονται στη συνέχεια.
Στο prefetch, η αυτοσυγκράτηση αποδίδει. Ένας πόρος που λαμβάνεται και δεν χρησιμοποιείται ποτέ δεν είναι δωρεάν. Καταναλώνει bandwidth, server capacity, ενέργεια και πιθανώς user data. Σε mobile networks, η speculative fetching μπορεί να είναι ενεργά μη φιλική.
Για πολλά sites, η καλύτερη στρατηγική prefetch είναι βασισμένη στην πρόθεση. Μην κάνετε prefetch τη σελίδα pricing μόλις φορτώσει η home page. Κάντε prefetch όταν ο χρήστης ανοίγει το pricing menu, κάνει hover στο pricing link ή κάνει scroll κοντά σε ένα call-to-action που προβλέπει ισχυρά πλοήγηση.
Να θυμάστε επίσης ότι η συμπεριφορά των browsers διαφέρει. Ορισμένοι browsers είναι συντηρητικοί με το prefetch· ορισμένες ρυθμίσεις privacy μειώνουν ή απενεργοποιούν τη speculative loading. Αντιμετωπίστε το prefetch ως ευκαιριακή βελτίωση, όχι ως μηχανισμό ορθότητας.
Preconnect: για ακριβές συνδέσεις σε σημαντικά origins
Το preconnect λέει στον browser: «Ξεκίνα τώρα την εγκατάσταση μιας σύνδεσης σε αυτό το origin.»
Αυτό μπορεί να περιλαμβάνει DNS lookup, TCP connection και TLS negotiation. Για third-party origins, αυτή η εγκατάσταση μπορεί να πάρει εκατοντάδες milliseconds, ειδικά σε high-latency networks. Αν η σελίδα θα χρειαστεί σύντομα ένα κρίσιμο request από αυτό το origin, το preconnect μπορεί να κάνει το μεταγενέστερο request ταχύτερο.
Παράδειγμα:
<link rel='preconnect' href='https://fonts.gstatic.com' crossorigin>
Καλοί υποψήφιοι για preconnect περιλαμβάνουν:
- Ένα font origin που χρησιμοποιείται για render-blocking text.
- Ένα κρίσιμο API origin που χρειάζεται κατά την αρχική αλληλεπίδραση.
- Ένα CDN origin που σερβίρει above-the-fold assets.
- Έναν payments ή identity provider που χρειάζεται αμέσως μετά από user action.
Κακοί υποψήφιοι για preconnect περιλαμβάνουν:
- Analytics και advertising endpoints που δεν είναι κρίσιμα για τον χρήστη.
- Origins που χρησιμοποιούνται μόνο σε ορισμένα sessions.
- Μεγάλες λίστες third parties.
- Same-origin resources, όπου ο browser έχει ήδη ή σύντομα θα ανοίξει τη σύνδεση.
Το preconnect έχει κόστος διατήρησης. Τα ανοιχτά sockets καταναλώνουν μνήμη και network resources. Οι browsers θα κλείσουν αχρησιμοποίητες συνδέσεις, αλλά αυτό δεν κάνει τα περιττά preconnects ακίνδυνα.
Ένας χρήσιμος κανόνας: κάντε preconnect το πολύ σε ένα ή δύο high-confidence third-party origins σε μια σελίδα. Αν μπαίνετε στον πειρασμό να προσθέσετε περισσότερα, η third-party architecture σας πιθανότατα χρειάζεται περισσότερο αναθεώρηση απ’ ό,τι τα hints σας χρειάζονται επέκταση.
DNS-prefetch: ο ελαφρύτερος συγγενής
Μπορεί επίσης να δείτε dns-prefetch:
<link rel='dns-prefetch' href='https://example-cdn.com'>
Αυτό επιλύει μόνο το domain name. Δεν ανοίγει TCP ή TLS connection. Είναι φθηνότερο από το preconnect, αλλά και λιγότερο χρήσιμο.
Το DNS-prefetch μπορεί να είναι λογικό για lower-confidence third-party origins όπου το πλήρες preconnect φαίνεται υπερβολικά επιθετικό. Στην πράξη, αν ένα origin είναι κρίσιμο και σίγουρα θα χρησιμοποιηθεί σύντομα, προτιμήστε preconnect. Αν είναι απλώς πιθανό, χρησιμοποιήστε είτε DNS-prefetch είτε τίποτα.
Πώς να αποφασίσετε: μια πρακτική ροή εργασίας
Ξεκινήστε με μέτρηση, όχι με tags.
1. Εντοπίστε το bottleneck
Ανοίξτε ένα performance trace και αναζητήστε late discovery. Ξεκίνησε το font, hero image ή script request μόνο αφού κατέβηκε και έγινε parse κάποιο άλλο αρχείο; Αυτό είναι υποψήφιο για preload.
Αν ένα request ξεκινά μόνο μετά από μια μακρά εγκατάσταση DNS/TCP/TLS προς ένα third-party origin, αυτό είναι υποψήφιο για preconnect.
Αν η τρέχουσα σελίδα είναι εντάξει αλλά η επόμενη πλοήγηση είναι προβλέψιμα αργή, το prefetch μπορεί να βοηθήσει.
2. Προσθέστε ένα hint κάθε φορά
Τα resource hints αλληλεπιδρούν. Προσθέστε ένα, δοκιμάστε το και κρατήστε το μόνο αν το waterfall βελτιώνεται και τα user-facing metrics δεν υποχωρούν.
Για το preload, παρακολουθήστε αν ο hinted resource χρησιμοποιείται πράγματι σύντομα. Το Chrome μπορεί να προειδοποιήσει όταν ένας preloaded resource δεν χρησιμοποιείται λίγο μετά το load. Πάρτε αυτή την προειδοποίηση στα σοβαρά.
3. Ελέγξτε τις παρενέργειες προτεραιότητας
Ένα preload μπορεί να τραβήξει bandwidth μακριά από CSS, JavaScript ή images που έχουν μεγαλύτερη σημασία. Ένα preconnect μπορεί να καταλάβει ένα connection slot. Ένα prefetch μπορεί να προσθέσει background traffic.
Το σωστό αποτέλεσμα δεν είναι «το hinted file ξεκινά νωρίτερα». Το σωστό αποτέλεσμα είναι «η σελίδα γίνεται ουσιαστικά καλύτερη για τους χρήστες». Κοιτάξτε LCP, INP, CLS και real-user monitoring όπου είναι δυνατό.
4. Επαληθεύστε headers και caching
Τα hints μπορούν να σταλούν σε HTML ή HTTP Link headers. Τα headers είναι χρήσιμα όταν ο server γνωρίζει νωρίς τι θα χρειαστεί η σελίδα, αλλά είναι πιο δύσκολο να επιθεωρηθούν πρόχειρα. Αν κάνετε debugging για το αν ένα hint υπάρχει πράγματι στην παραγωγή, τα raw headers έχουν σημασία· αυτή είναι ακριβώς η περίπτωση που καλύπτεται στον οδηγό μας για debugging redirects και HTTP headers.
Το caching έχει επίσης σημασία. Το preloading ενός πόρου με mismatched credentials, λάθος as ή διαφορετικά URL parameters μπορεί να προκαλέσει duplicate downloads. Αυτός είναι ένας από τους πιο συνηθισμένους τρόπους με τους οποίους ένα καλοπροαίρετο preload γίνεται performance bug.
Συνηθισμένα λάθη
Preloading υπερβολικά πολλών πραγμάτων
Αν όλα είναι κρίσιμα, τίποτα δεν είναι. Περιορίστε το preload σε πόρους που χρειάζονται για την αρχική απόδοση ή την άμεση interactivity. Μια τυπική σελίδα θα πρέπει να έχει μηδέν έως τρία preloads, όχι είκοσι.
Χρήση prefetch για απαιτούμενους πόρους
Το prefetch είναι χαμηλής προτεραιότητας και προαιρετικό. Μην το χρησιμοποιείτε για assets που απαιτούνται από την τρέχουσα σελίδα. Αν η σελίδα το χρειάζεται τώρα, εξετάστε το preload ή την κανονική ανακάλυψη μέσω HTML.
Preconnecting σε κάθε third party
Οι σελίδες με πολλά third parties συχνά έχουν δέκα ή περισσότερα external origins. Το preconnecting σε όλα δημιουργεί θόρυβο. Επιλέξτε το ένα ή δύο που είναι και κρίσιμα και προβλέψιμα χρησιμοποιούμενα.
Ξεχνώντας τις mobile συνθήκες
Τα resource hints είναι πιο πολύτιμα σε πιο αργές συνδέσεις, αλλά και πιο επικίνδυνα εκεί. Ένα χαμένο prefetch σε μια γρήγορη desktop connection είναι αμελητέο. Σε ένα constrained mobile plan, είναι κακή ανταλλαγή.
Ένας απλός πίνακας αποφάσεων
| Κατάσταση | Καλύτερο hint | Γιατί | |---|---:|---| | Κρίσιμο font που ανακαλύπτεται μέσω CSS | preload | Η τρέχουσα σελίδα το χρειάζεται, η ανακάλυψη είναι αργή | | Hero image κρυμμένο πίσω από CSS ή client rendering | preload | Μπορεί να βελτιώσει το LCP αν το image ξεκινά αργά | | Πιθανό επόμενο route μετά από user intent | prefetch | Βοηθά τη μελλοντική πλοήγηση χωρίς να μπλοκάρει την τρέχουσα σελίδα | | Κρίσιμο third-party font/API origin | preconnect | Αφαιρεί την εγκατάσταση σύνδεσης από το critical path | | Πιθανό αλλά αβέβαιο third-party origin | dns-prefetch ή κανένα | Χαμηλότερο κόστος, χαμηλότερη βεβαιότητα | | Below-the-fold image | κανένα | Αφήστε το lazy loading και την προτεραιότητα του browser να λειτουργήσουν |
Ο ήρεμος κανόνας
Τα resource hints λειτουργούν καλύτερα όταν είναι βαρετά και συγκεκριμένα. Ένα font. Ένα LCP image. Ένα σημαντικό third-party origin. Ένα πιθανό επόμενο route μετά από πρόθεση.
Λειτουργούν άσχημα όταν χρησιμοποιούνται ως αισιοδοξία: ίσως ο χρήστης χρειαστεί αυτό, ίσως ο browser πρέπει να φέρει εκείνο, ίσως περισσότερα hints σημαίνουν περισσότερη ταχύτητα.
Οι browsers ήδη βελτιστοποιούν επιθετικά. Η δουλειά σας δεν είναι να μικροδιαχειρίζεστε κάθε request. Η δουλειά σας είναι να διορθώσετε τις λίγες περιπτώσεις όπου ο browser στερείται πληροφορίας τη σωστή στιγμή.