defer και async αλλάζουν πότε ένα εξωτερικό <script> κατεβαίνει και εκτελείται σε σχέση με την ανάλυση HTML. Και τα δύο επιτρέπουν στο script να κατεβαίνει παράλληλα χωρίς να μπλοκάρει τον parser — η διαφορά είναι στο χρονισμό της εκτέλεσης.
defer και async αλλάζουν πότε ένα εξωτερικό <script> κατεβαίνει και εκτελείται σε σχέση με την ανάλυση HTML. Και τα δύο επιτρέπουν στο script να κατεβαίνει παράλληλα χωρίς να μπλοκάρει τον parser — η διαφορά είναι στο χρονισμό της εκτέλεσης.
Normal: parse──stop──[download+exec]──parse──────── (slowest)
async: parse──────────────────exec──parse──────── (runs whenever it arrives)
defer: parse───────────────────────────parse──exec (after parsing, before DOMContentLoaded)
async | defer | |
|---|---|---|
| Download | παράλληλα | παράλληλα |
| Εκτέλεση | όσο το συντομότερο κατεβαίνει | μετά την πλήρη ανάλυση HTML |
| Διατηρείται η σειρά; | Όχι (όποιος τερματίσει πρώτος) | Ναι (σειρά εγγράφου) |
| Μπλοκάρει τον parser; | μόνο συνοπτικά κατά την εκτέλεση | ποτέ |
defer — για scripts που αγγίζουν το DOM ή εξαρτώνται το ένα από το άλλο/σειρά (ο κώδικας της εφαρμογής σας). Εκτελούνται μετά την ύπαρξη του DOM, διαδοχικά, λίγο πριν το DOMContentLoaded.async — για ανεξάρτητα third-party scripts που δεν εξαρτώνται από το DOM ή άλλα scripts (analytics, διαφημίσεις). Η σειρά δεν έχει σημασία, εκτελέστε τα το συντομότερο δυνατό.<script src="analytics.js" async></script> <!-- independent → async -->
<script src="app.js" defer></script> <!-- app logic, ordered → defer -->
Σημείωση: και τα δύο ισχύουν μόνο για εξωτερικά scripts (src). αγνοούνται σε inline scripts. ES modules (type="module") είναι deferred από προεπιλογή.
Η χρήση defer/async αποτρέπει τα scripts από το να μπλοκάρουν την ανάλυση HTML, η οποία βελτιώνει απευθείας την απόδοση φόρτωσης και το First Contentful Paint.
Η επιλογή του σωστού (defer για ταξινομημένο κώδικα εφαρμογής που εξαρτάται από το DOM, async για third-party scripts που δεν περιμένουν απάντηση) αποφεύγει τόσο τις αργές φορτώσεις όσο και τα bugs εξάρτησης σειράς.