KIếN THứC WEBSITE › PERFORMANCE

Defer vs async — so sánh 2 attribute script cho WordPress

Defer vs async — so sánh 2 attribute script cho WordPress 2026

defer và async là 2 thuộc tính trên thẻ <script> kiểm soát thời điểm trình duyệt thực thi JS mà không chặn parse HTML. Chọn sai thuộc tính gây lỗi script hoặc làm FCP không cải thiện được.

Vấn đề với script mặc định

defer vs async — Vấn đề với script mặc định
Vấn đề với script mặc định

Thẻ <script src="..."> không có thuộc tính chặn parser HTML theo mặc định. Trình duyệt dừng parse, tải JS, thực thi xong rồi mới tiếp tục parse — gây trễ FCP và LCP trực tiếp.

Một file JS 100KB qua mạng 4G có thể chặn hiển thị 500–800ms. defer và async giải quyết điểm chặn này — mỗi thuộc tính theo cách riêng.

defer — thực thi sau khi DOM parse xong

Trình duyệt tải JS song song với parse HTML. Thực thi SAU khi DOM parse xong, ngay trước sự kiện DOMContentLoaded.

Nhiều script defer thực thi theo đúng thứ tự khai báo trong HTML.

Phù hợp cho: script cần truy cập DOM, script có phụ thuộc lẫn nhau, plugin và theme JS trong WordPress.

async — thực thi ngay khi tải xong

Trình duyệt tải JS song song với parse HTML. Thực thi NGAY KHI tải xong — bất kể HTML đã parse xong chưa.

Nhiều script async thực thi không theo thứ tự (ai tải xong trước thực thi trước).

Phù hợp cho: script độc lập, không cần DOM, không có phụ thuộc với script khác.

So sánh defer và async — 7 khía cạnh

So sánh defer và async — 7 khía cạnh
So sánh defer và async — 7 khía cạnh
Khía cạnh defer async
Tải HTML Song song, không chặn Song song, không chặn
Thời điểm thực thi Sau khi DOM parse xong Ngay khi tải xong
Thứ tự nhiều script Theo thứ tự khai báo Ngẫu nhiên (ai xong trước chạy trước)
Sự kiện DOMContentLoaded Thực thi trước sự kiện này Có thể thực thi sau sự kiện này
Truy cập DOM an toàn Có — DOM đã sẵn sàng Không — DOM có thể chưa parse xong
Hỗ trợ phụ thuộc script Có (theo thứ tự) Không
Hỗ trợ trình duyệt 2026 99%+ 99%+

Dòng thời gian thực thi — hình dung rõ hơn

Dòng thời gian thực thi — hình dung rõ hơn
Dòng thời gian thực thi — hình dung rõ hơn
Giai đoạn Mặc định defer async
Parse HTML Dừng khi gặp script Tiếp tục bình thường Tiếp tục bình thường
Tải JS Tuần tự, chặn Song song với parse Song song với parse
Thực thi JS Ngay, chặn parse Sau khi parse xong Ngay khi tải xong
DOMContentLoaded Sau khi script xong Sau defer scripts Có thể trước async

Khuyến nghị theo loại script cho shop WordPress

Loại script Thuộc tính Lý do
jQuery (phụ thuộc theme/plugin) Mặc định (không dùng) Theme/plugin phụ thuộc jQuery cần thực thi theo thứ tự
Theme JS tùy biến (slider, menu) defer Cần DOM sẵn sàng, không cần thực thi ngay
Plugin WooCommerce (mini cart AJAX) defer Phụ thuộc container DOM của giỏ hàng
Google Analytics / GTM async Độc lập, không cần DOM, không ảnh hưởng thứ tự
Facebook Pixel async Script theo dõi độc lập
Chat widget (Tawk.to, Crisp) defer hoặc async defer nếu cần tạo DOM, async nếu hoàn toàn độc lập
Công cụ A/B test (Optimizely) Mặc định (chặn) Phải thực thi trước khi hiển thị để tránh giật giao diện
Bộ tải font web async Độc lập, font swap không chặn hiển thị

Triển khai trong WordPress

WordPress core không hỗ trợ defer/async trong hàm wp_enqueue_script(). Cần thêm thuộc tính qua hook script_loader_tag hoặc dùng plugin.

4 phương pháp triển khai

Phương pháp Thiết lập Phù hợp khi nào
Thủ công trong functions.php Thêm filter custom Lập trình viên tùy chỉnh theme
Plugin “Async JavaScript” Miễn phí, có giao diện cài đặt Trang WordPress thông thường
WP Rocket $59/năm, 1 click Shop trên 100 đơn/ngày
Plugin “Defer Js” Miễn phí Chỉ cần defer, không cần async

Ví dụ filter thủ công

// Thêm defer/async thủ công vào functions.php
add_filter( 'script_loader_tag', function( $tag, $handle, $src ) {
  $defer_scripts = [ 'theme-slider', 'theme-menu', 'wc-cart-fragments' ];
  $async_scripts  = [ 'google-analytics', 'facebook-pixel' ];

  if ( in_array( $handle, $defer_scripts ) ) {
    return str_replace( '<script ', '<script defer ', $tag );
  }
  if ( in_array( $handle, $async_scripts ) ) {
    return str_replace( '<script ', '<script async ', $tag );
  }
  return $tag;
}, 10, 3 );

Kết hợp với preload để tăng hiệu quả

defer/async loại bỏ điểm chặn — nhưng trình duyệt vẫn phát hiện script muộn trong quá trình parse. Preload script quan trọng giúp tải song song từ sớm hơn.

Pattern preload kết hợp defer

<!-- Preload để tải sớm, defer để không chặn -->
<link rel="preload" href="/theme.js" as="script">
<script src="/theme.js" defer></script>

Đọc thêm về preload và prefetch resource hint và cách kết hợp với CSS quan trọng để loại bỏ toàn bộ điểm chặn hiển thị.

Checklist triển khai defer/async cho shop WordPress

  1. Mở DevTools → Network → lọc JS — xem script nào load ở thứ tự cao nhất.
  2. Liệt kê tất cả script đang enqueue: wp_print_scripts() trong theme hoặc dùng Query Monitor.
  3. Phân loại từng script: cần DOM không? Có phụ thuộc với script khác không?
  4. Script theo dõi độc lập (Analytics, Pixel) — phân loại riêng để thêm async.
  5. Giữ jQuery mặc định (không thêm defer/async) nếu có plugin phụ thuộc.
  6. Thêm defer cho toàn bộ theme JS tùy biến và plugin cần DOM.
  7. Thêm async cho script theo dõi (Analytics, Pixel) và font loader.
  8. Test kỹ trên staging trước: kiểm tra console không có lỗi X is not defined.
  9. Đo lại FCP và LCP qua Google PageSpeed Insights sau khi triển khai.
  10. Kết hợp với tách bundle cho frontend Next.js nếu có.

Bài liên quan

Câu hỏi thường gặp

Đặt cả defer lẫn async cùng lúc — trình duyệt xử lý thế nào?

async thắng nếu cả hai cùng được đặt. Trình duyệt xử lý theo ưu tiên: async > defer > mặc định.

Nên chọn một trong hai, không đặt cả hai cùng lúc để tránh nhầm lẫn.

Script nhúng trực tiếp (không có src) có dùng defer/async được không?

Không. defer và async chỉ hoạt động với script có thuộc tính src (script ngoài). Script nhúng trực tiếp trong HTML thực thi ngay khi parser gặp — chặn parse.

Giải pháp: chuyển code ra file ngoài, hoặc đặt code nhúng trong listener DOMContentLoaded.

jQuery có thể thêm defer không?

Về lý thuyết được, nhưng rủi ro cao. Rất nhiều theme và plugin dùng thẳng biến $ hoặc jQuery mà không khai báo phụ thuộc đúng cách.

Defer jQuery nhưng không defer đúng cách các script phụ thuộc gây lỗi jQuery is not defined. Giữ jQuery mặc định là an toàn nhất — defer các script khác.

WordPress 6.3+ có hỗ trợ defer native chưa?

WordPress 6.3 (tháng 8/2023) thêm hàm wp_enqueue_script_module() hỗ trợ ES module với defer tự động. Theme và plugin mới có thể dùng API này thay vì filter thủ công.

Theme cũ dùng wp_enqueue_script() vẫn cần filter script_loader_tag để thêm defer/async.

Web22 audit toàn bộ script đang load, phân loại và triển khai defer/async đúng chuẩn — bao gồm test staging và đo FCP trước/sau. Xem dịch vụ tối ưu hiệu năng Core Web Vitals để bắt đầu.