Tối ưu hình ảnh và code trong WordPress phải bắt đầu từ đường tải của trang, không bắt đầu từ một ngưỡng KB hay một nút "Optimize" trong plugin. Ảnh đầu màn hình cần được phát hiện và tải sớm; ảnh ngoài màn hình mới nên lazy-load. CSS, JavaScript và mã bên thứ ba chỉ nên xuất hiện khi template hoặc hành vi người dùng thật sự cần chúng.
Bài số 15 trong series SEO WordPress chuyển 10 tiêu chí từ 114 đến 123 thành quy trình kiểm tra có thể làm lại: đo hiện trạng, khoanh tài nguyên gây chậm, sửa một nhóm biến, kiểm giao diện và đo lại trên cùng điều kiện.
Nguyên tắc: gửi đúng tài nguyên, đúng kích thước, đúng thời điểm và chỉ cho trang thật sự cần nó.
1. Hình ảnh và code ảnh hưởng SEO WordPress như thế nào?
Hình ảnh thường chiếm phần lớn byte tải xuống, còn JavaScript quyết định bao nhiêu thời gian CPU phải bỏ ra trước khi trang phản hồi tốt. Một ảnh hero nặng có thể kéo dài Largest Contentful Paint. Một bundle JavaScript lớn có thể tải nhanh trên mạng mạnh nhưng vẫn tốn thời gian parse, compile và thực thi trên điện thoại yếu.
Nếu bạn mới bắt đầu tách bốn lớp đó, khóa SEO hình ảnh miễn phí đi từ bước đo baseline rồi mới tới nén, responsive và ảnh LCP, nên bạn có thứ tự làm thay vì một danh sách việc phẳng.
SEO không nên đọc hiệu năng bằng một con số duy nhất. Cần tách ít nhất bốn lớp: thời gian phản hồi máy chủ, thời gian tải tài nguyên, thời gian kết xuất nội dung chính và khả năng phản hồi khi người dùng tương tác. Hình ảnh tác động mạnh tới byte truyền và LCP; CSS tác động đường kết xuất; JavaScript tác động main thread, Total Blocking Time trong lab và Interaction to Next Paint ngoài thực tế.
| Nhóm | Rủi ro thường gặp | Tín hiệu cần xem |
|---|---|---|
| Ảnh đầu màn hình | Lazy-load nhầm, tải quá muộn, kích thước quá lớn | LCP element, request priority, resource timing |
| Ảnh trong bài | Gửi ảnh full-size cho khung nhỏ | Properly size images, transferred size |
| CSS | Chặn hiển thị, dùng chung quá rộng | Render-blocking, Coverage, request chain |
| JavaScript | Bundle lớn, long task, plugin tải toàn site | Main thread, Bottom-Up, Coverage |
| Bên thứ ba | Chat, video, quảng cáo chạy trước nhu cầu | Third-party summary, Network domain |
Chốt ý: ảnh nhẹ chưa đủ nếu bị tải sai thời điểm; code đã minify chưa đủ nếu phần lớn code không được dùng.
2. Quy trình đo trước khi tối ưu hình ảnh và code
Nếu bạn muốn đi hết “Quy trình đo trước khi tối ưu hình ảnh và code” mà không bỏ sót khâu nào, Khóa Học SEO liệt kê các chương trình theo độ dài chặng và đầu ra từng giai đoạn.
Đo ít nhất một trang đại diện cho mỗi template quan trọng trên cả mobile và desktop. Trang chủ, bài viết, danh mục, sản phẩm và landing page có đường tải khác nhau. Kết quả của trang chủ không đại diện cho toàn bộ WordPress.
- Chọn URL: mỗi template lấy một URL có traffic hoặc chuyển đổi thật.
- Ghi điều kiện: thiết bị, mạng, vị trí kiểm tra, trạng thái cache và thời điểm.
- Đọc dữ liệu thực tế: xem Core Web Vitals field data nếu URL hoặc origin có đủ mẫu.
- Chạy lab: dùng PageSpeed Insights hoặc Lighthouse để tái hiện và tìm cơ hội.
- Mở DevTools: xác nhận request, initiator, priority, coverage và long task.
- Lưu baseline: LCP, INP hoặc TBT, CLS, byte ảnh, byte JS và số request bên thứ ba.
Điểm Lighthouse có thể thay đổi giữa các lần chạy vì máy, mạng và nội dung động. Hãy chạy nhiều lần, lấy trung vị và so cùng điều kiện. Không nên sửa mười plugin cùng lúc rồi dùng một lần đo duy nhất làm bằng chứng.
Đầu ra cần có: danh sách tài nguyên theo URL, template, chủ sở hữu, byte truyền, thời gian CPU, mức ưu tiên và hành động dự kiến.
3. Tiêu chí 114: Lazy loading ảnh ngoài màn hình
Chỉ thêm loading="lazy" cho ảnh và iframe có khả năng nằm ngoài vùng hiển thị ban đầu. Ảnh hero, ảnh sản phẩm chính hoặc phần tử có khả năng trở thành LCP không nên bị trì hoãn. Web.dev cảnh báo lazy-load ảnh LCP luôn tạo thêm độ trễ không cần thiết.
<!-- Ảnh đầu màn hình, có khả năng là LCP -->
<img src="hero.webp" width="1200" height="675"
loading="eager" fetchpriority="high"
alt="Mô tả đúng nội dung ảnh">
<!-- Ảnh nằm sâu trong bài -->
<img src="step-6.webp" width="800" height="500"
loading="lazy" decoding="async"
alt="Ảnh minh họa bước 6">Trong WordPress hiện đại, thuộc tính tải ảnh được hệ thống tính theo ngữ cảnh. Vấn đề thường xuất hiện khi theme, page builder, plugin lazy-load và CDN cùng can thiệp. Hãy xem HTML cuối cùng trong Elements, không chỉ xem cấu hình trong trang quản trị.
- Kiểm tra ảnh đầu tiên của từng template có bị gắn
loading="lazy"không. - Kiểm tra ảnh nền CSS vì chúng không đi qua cơ chế
loadingcủa thẻimg. - Kiểm tra iframe video, bản đồ và widget ngoài màn hình có được trì hoãn không.
- Không dùng
fetchpriority="high"cho nhiều ảnh cùng lúc vì các request sẽ cạnh tranh nhau.
Trọng số: Bắt buộc. Công cụ: PageSpeed Checker của Novaverb, PageSpeed Insights, Chrome DevTools Network và Performance.
4. Cách xác định ảnh hero và phần tử LCP
Không được đoán LCP chỉ bằng vị trí của ảnh. LCP có thể là ảnh, poster video hoặc một khối chữ lớn. Nó cũng có thể khác giữa mobile và desktop, giữa người đã đăng nhập và người chưa đăng nhập, hoặc sau khi banner cookie xuất hiện.

Trong PageSpeed Insights, mở phần Largest Contentful Paint element để biết phần tử được chọn trong lần chạy. Trong Chrome DevTools Performance, ghi một trace tải lại trang, chọn mốc LCP và lần theo request tương ứng trong Network. Ba câu hỏi cần trả lời là:
- Phần tử LCP có xuất hiện ngay trong HTML ban đầu không?
- Request ảnh bắt đầu ở thời điểm nào và ai khởi tạo nó?
- Ảnh được tải với priority nào, có bị CSS hoặc JavaScript làm chậm việc phát hiện không?
Nếu ảnh LCP là background-image, trình duyệt chỉ phát hiện sau khi tải và phân tích CSS. Có thể cân nhắc chuyển sang img hoặc picture. Nếu bắt buộc giữ ảnh nền, preload có chọn lọc và đo lại, không preload mọi ảnh banner.
Chốt ý: sửa đúng LCP element thường hiệu quả hơn nén thêm hàng chục ảnh chưa xuất hiện trong màn đầu.
5. Tiêu chí 115: Kích thước ảnh theo vùng hiển thị
Ảnh phải được resize và nén gần với kích thước hiển thị thực tế, nhưng không có một ngưỡng KB đúng cho mọi ảnh. Một ảnh chụp nhiều chi tiết cần ngân sách khác logo phẳng; ảnh hero toàn chiều ngang cần nhiều pixel hơn thumbnail 320px.
Đánh giá bằng tỉ lệ giữa kích thước nội tại và kích thước khung hiển thị, đồng thời xét mật độ điểm ảnh. Ví dụ, khung 400 CSS pixel trên màn hình DPR 2 có thể cần nguồn khoảng 800 pixel để sắc nét. Gửi ảnh 2400 pixel cho khung đó thường là lãng phí; ép xuống đúng 400 pixel lại có thể mờ trên màn hình mật độ cao.
| Vùng dùng ảnh | Nguồn nên chuẩn bị | Điều cần tránh |
|---|---|---|
| Thumbnail bài viết | Nhiều cỡ gần các breakpoint thẻ | Dùng ảnh gốc 2000px cho ô 320px |
| Ảnh hero | Nguồn đủ rộng cho layout và DPR mục tiêu | Nén quá mạnh làm bệt chữ, mặt người |
| Ảnh trong nội dung | Cỡ bám max-width của cột đọc | Nhúng full-size từ Media Library |
| Logo và biểu tượng | SVG khi phù hợp hoặc raster nhỏ đúng cỡ | Đổi ảnh vector thành PNG rất lớn |
Trong Network, bật cột Img Size hoặc xem Dimensions để so natural size với rendered size. Lighthouse mục Properly size images giúp tìm nhanh, nhưng DevTools mới cho biết ảnh nào do theme, block hoặc plugin tạo.
Trọng số: Bắt buộc. Công cụ: Image Resizer của Novaverb, Image Compressor của Novaverb, PageSpeed Insights và Chrome DevTools.
6. Dùng srcset, sizes và picture đúng trong WordPress
srcset cung cấp các ứng viên ảnh, còn sizes mô tả bề rộng hiển thị để trình duyệt chọn ứng viên phù hợp. Chỉ tạo nhiều file rồi bỏ trống hoặc khai sai sizes có thể khiến trình duyệt vẫn lấy ảnh quá lớn.

<picture>
<source type="image/avif"
srcset="cover-480.avif 480w, cover-960.avif 960w, cover-1440.avif 1440w">
<source type="image/webp"
srcset="cover-480.webp 480w, cover-960.webp 960w, cover-1440.webp 1440w">
<img src="cover-960.jpg"
srcset="cover-480.jpg 480w, cover-960.jpg 960w, cover-1440.jpg 1440w"
sizes="(min-width: 1024px) 760px, calc(100vw - 32px)"
width="1440" height="900" alt="Mô tả ảnh">
</picture>WordPress có sẵn nhiều image size và có thể sinh srcset, sizes khi theme dùng API ảnh đúng cách. Khi viết theme, ưu tiên hàm xuất attachment image thay vì lấy URL full-size rồi tự viết thẻ img. Với page builder, kiểm tra HTML thực tế vì một số module đặt sizes="100vw" dù ảnh chỉ chiếm một phần ba màn hình.
- Dùng
picturekhi cần đổi crop hoặc định dạng theo khả năng trình duyệt. - Dùng width descriptor như
480w,960wkhi layout thay đổi theo viewport. - Khai
widthvàheightđể trình duyệt giữ trước tỉ lệ, hạn chế layout shift. - Đừng preload nhiều định dạng của cùng một ảnh vì trình duyệt có thể tải thừa.
Chốt ý: responsive image tốt không phải ảnh co giãn bằng CSS, mà là trình duyệt thật sự tải file phù hợp với vùng hiển thị.
7. Chọn WebP, AVIF, JPEG, PNG và SVG theo loại hình
Định dạng ảnh nên được chọn theo nội dung và khả năng tương thích, không theo trào lưu. WebP là lựa chọn thực dụng cho nhiều website; AVIF có thể giảm thêm dung lượng ở một số ảnh nhưng chi phí encode và chất lượng chi tiết cần được kiểm. JPEG vẫn hữu ích làm fallback cho ảnh chụp. PNG phù hợp ảnh cần alpha hoặc đồ họa mà WebP chưa thay thế trong quy trình. SVG phù hợp logo, icon và hình vector đáng tin cậy.
- Ảnh chụp: so WebP, AVIF và JPEG bằng chất lượng nhìn thấy ở đúng kích thước hiển thị.
- Ảnh có chữ: kiểm cạnh chữ ở mobile, tránh nén làm viền rung hoặc bệt.
- Ảnh minh họa phẳng: thử WebP lossless hoặc SVG nếu nguồn thật sự là vector.
- Ảnh có trong suốt: kiểm alpha và viền halo trên cả nền sáng lẫn nền tối.
Không nên dùng một luật như "mọi ảnh dưới 100 KB". Thay vào đó, đặt ngân sách theo vai trò: hero, card, ảnh bài, avatar, icon. Theo dõi tổng byte ảnh trong màn đầu và thời gian tải của ảnh LCP, vì hai chỉ số này gần mục tiêu người dùng hơn kích thước một file riêng lẻ.
Chốt ý: định dạng mới chỉ có giá trị khi file người dùng nhận nhỏ hơn, đủ nét và không làm quy trình xuất bản dễ sai.
8. Tiêu chí 116: Minify CSS, JavaScript và HTML
Minify loại khoảng trắng, comment và ký tự không cần cho production, nhưng không loại bỏ logic thừa. Một bundle 400 KB minify còn 280 KB vẫn có thể chứa 200 KB mã không dùng. Vì vậy minify là lớp hoàn thiện sau khi đã kiểm phạm vi tài nguyên.
Trên WordPress, minify có thể diễn ra ở build theme, plugin tối ưu, CDN hoặc reverse proxy. Chỉ nên có một nơi chịu trách nhiệm rõ. Xếp chồng nhiều công cụ có thể tạo file cache trùng, đổi thứ tự script, phá source map hoặc làm khó rollback.
| Tài nguyên | Kiểm trước | Kiểm sau |
|---|---|---|
| CSS | Thứ tự cascade, import, URL font và ảnh | Menu, breakpoint, hover, focus, print |
| JavaScript | Dependency, module, inline config | Form, giỏ hàng, popup, analytics, lỗi console |
| HTML | Whitespace có ý nghĩa, pre/code, inline script | DOM, schema, nội dung, chức năng nhúng |
Giữ bản build và cache cũ đủ lâu để rollback. Sau khi bật minify, xóa cache theo thứ tự có kiểm soát, thử ở cửa sổ ẩn danh và thiết bị thật. Không kết luận thành công chỉ vì PageSpeed bỏ một cảnh báo.
Trọng số: Quan trọng. Công cụ: Online HTML Editor của Novaverb, PageSpeed Insights và Chrome DevTools.
9. Tiêu chí 117: Giảm tài nguyên chặn hiển thị
Mục tiêu là để trình duyệt dựng được phần đầu trang với ít phụ thuộc nhất. CSS cần cho màn đầu có thể được inline ở mức nhỏ và ổn định; CSS còn lại tải sau theo template. JavaScript không cần cho lần vẽ đầu nên trì hoãn, nhưng không được làm mất chức năng hoặc tạo nội dung nhảy muộn.
Hãy mở request waterfall và tìm chuỗi phụ thuộc trước First Contentful Paint hoặc LCP. Một stylesheet có thể nhỏ nhưng nhập thêm nhiều font và CSS khác. Một script có thể chỉ 20 KB nhưng chạy đồng bộ trong head và chặn parser.
- Liệt kê CSS và JS xuất hiện trước nội dung chính.
- Xác định tài nguyên nào thật sự cần để dựng header, hero và điều hướng đầu trang.
- Đưa critical CSS nhỏ vào HTML nếu quy trình build kiểm soát được.
- Tách CSS theo template hoặc component cho phần còn lại.
- Đổi cách tải script theo dependency, không đổi hàng loạt bằng một toggle.
- Đo lại LCP, CLS, lỗi console và tương tác đầu tiên.
Critical CSS quá lớn làm HTML phình ra và lặp lại trên mọi trang. Critical CSS sinh tự động nhưng không xét trạng thái menu, cookie banner hoặc font có thể tạo flash, sai layout hoặc CLS.
Trọng số: Bắt buộc. Công cụ: PageSpeed Checker của Novaverb, PageSpeed Insights và Chrome DevTools Coverage.
10. Async, defer và module khác nhau ở đâu?
async phù hợp script độc lập; defer phù hợp script cần giữ thứ tự hoặc chờ DOM được phân tích. Theo MDN, script async thực thi ngay khi tải xong và không bảo đảm thứ tự. Script defer chạy sau khi tài liệu được parse và giữ thứ tự xuất hiện. Module script mặc định có hành vi trì hoãn.
<!-- Độc lập, không dựa vào script khác -->
<script async src="independent.js"></script>
<!-- Hai file có quan hệ thứ tự -->
<script defer src="vendor.js"></script>
<script defer src="theme.js"></script>
<!-- Module được trì hoãn theo mặc định -->
<script type="module" src="app.js"></script>Không nên tự động thêm async cho mọi script WordPress. jQuery, thư viện slider, addon của page builder và inline config có thể phụ thuộc nhau. Khi thứ tự bị phá, lỗi thường chỉ xuất hiện ở một template hoặc sau khi cache đầy đủ.
Lập một dependency map gồm handle WordPress, file nguồn, trang dùng, dependency và thời điểm cần chạy. Sau đó đổi từng nhóm, theo dõi console và hành vi thật. Nếu plugin đã khai dependency bằng enqueue API, tận dụng dữ liệu đó thay vì thay thẻ script bằng regex ở tầng HTML.
Chốt ý: async và defer là quyết định về quan hệ thực thi, không phải hai nhãn "tăng tốc" có thể dùng thay nhau.
11. Tiêu chí 118: Loại bỏ CSS không sử dụng
Coverage cho biết CSS chưa được dùng trong phiên đo hiện tại, không chứng minh rule đó vô dụng trên toàn website. Menu mở, modal, tab, validation error, trạng thái đăng nhập, giỏ hàng và breakpoint khác có thể chưa được kích hoạt trong lần ghi.
Quy trình an toàn là gom CSS theo nguồn trước: theme, block library, page builder, plugin form, commerce và custom. Với mỗi file, xác định template nào cần. Ưu tiên dừng enqueue trên trang không dùng thay vì chạy một bộ purge toàn site rồi cố thêm safelist vô hạn.
- Ghi Coverage khi tải trang, sau đó mở menu, popup, accordion và form error.
- Thử mobile, tablet, desktop, hover, focus-visible và chế độ in nếu có.
- Kiểm trang đăng nhập, trang thanh toán và trang có nội dung do người dùng tạo.
- Lưu ảnh so sánh trước/sau hoặc dùng visual regression cho template quan trọng.
- Giữ một danh sách selector động mà plugin sinh vào runtime.
Mục tiêu không nhất thiết là 0% unused CSS. Một ít CSS dùng chung có thể rẻ hơn việc chia thành quá nhiều file nhỏ. Hãy cân bằng byte tiết kiệm, cache hit, độ phức tạp vận hành và rủi ro giao diện.
Trọng số: Quan trọng. Công cụ: PageSpeed Checker của Novaverb, Chrome DevTools Coverage và PageSpeed Insights.
12. Tiêu chí 119: Loại bỏ JavaScript không sử dụng
JavaScript không dùng tốn cả băng thông lẫn CPU parse và compile. Trên WordPress, nguyên nhân phổ biến là plugin enqueue tài nguyên trên toàn site dù tính năng chỉ xuất hiện ở một vài trang.
Bắt đầu từ Coverage và Network Initiator để gắn file với theme hoặc plugin. Sau đó hỏi theo thứ tự: có thể gỡ tính năng không, có thể dừng tải trên template khác không, có thể thay bằng HTML/CSS không, có thể chia module hay tải khi tương tác không?
| Hiện tượng | Hướng xử lý ưu tiên |
|---|---|
| Script form trên trang không có form | Chỉ enqueue khi block hoặc shortcode tồn tại |
| Slider library chỉ dùng ở trang chủ | Giới hạn theo template trang chủ |
| Icon library rất lớn | Chỉ giữ icon dùng hoặc chuyển sang SVG nội tuyến có kiểm soát |
| Polyfill cho trình duyệt không còn hỗ trợ | Rà browser support và gỡ có kiểm thử |
| Module admin lọt ra frontend | Sửa điều kiện enqueue |
Tree shaking hữu ích với theme hoặc plugin có quy trình build module, nhưng không tự cứu được script toàn cục có side effect. Với plugin bên thứ ba không kiểm soát code, tải theo trang hoặc thay plugin thường thực tế hơn.
Trọng số: Quan trọng. Công cụ: PageSpeed Checker của Novaverb, Chrome DevTools Coverage và PageSpeed Insights.
13. Tiêu chí 120: Giảm Main-thread Work và Long Tasks
Một task kéo dài hơn 50ms được xem là long task; phần vượt quá 50ms tạo thời gian blocking. Trong khoảng đó, main thread bận và không thể phản hồi tương tác kịp thời. Đây là lý do một website có file nhỏ vẫn có thể giật khi mở menu hoặc nhập form.
Trong DevTools Performance, record khi tải trang và khi thực hiện tương tác quan trọng. Tìm vạch đỏ trên task dài, mở Bottom-Up và Call Tree để xác định function, file và domain. Phân biệt thời gian Script Evaluation, Style, Layout, Paint và Garbage Collection trước khi sửa.
- Chia vòng lặp hoặc xử lý lớn thành các phần nhỏ, nhường main thread giữa các phần.
- Trì hoãn khởi tạo widget ngoài màn hình cho tới khi gần viewport hoặc có tương tác.
- Tránh đọc và ghi layout xen kẽ gây layout thrashing.
- Giảm DOM quá lớn do page builder và mega menu.
- Đưa xử lý thuần dữ liệu nặng sang Web Worker khi kiến trúc phù hợp.
- Giảm listener và observer trùng do nhiều plugin cùng theo dõi scroll.
Đừng chỉ nhìn Total Blocking Time trong Lighthouse. TBT là chỉ số lab; để đánh giá trải nghiệm thật cần xem INP trong dữ liệu thực tế và trace những tương tác gây chậm.
Trọng số: Bắt buộc. Công cụ: Website Performance Test của Novaverb, Chrome DevTools Performance và Lighthouse.
14. Tiêu chí 121: Code Splitting và tải theo nhu cầu
Tách mã theo route hoặc tính năng giúp lần tải đầu không phải mang toàn bộ JavaScript của website. Một bundle duy nhất dễ triển khai nhưng buộc trang bài viết tải code của checkout, slider, map hoặc dashboard dù không dùng.
// Chỉ tải module khi người dùng mở công cụ
const trigger = document.querySelector('[data-open-calculator]');
trigger?.addEventListener('click', async () => {
const { openCalculator } = await import('./calculator.js');
openCalculator();
}, { once: true });Với WordPress truyền thống, code splitting thường bắt đầu từ enqueue có điều kiện theo template, block hoặc shortcode. Với theme dùng bundler, có thể thêm dynamic import theo component. Cả hai cách đều cần giữ fallback nếu JavaScript chưa tải và tránh tạo hàng chục chunk quá nhỏ gây thêm request và khó cache.
Đo waterfall sau khi tách. Chunk có được yêu cầu đúng lúc không, có preload nhầm toàn bộ chunk động không, cache key có ổn định không và tương tác đầu tiên có bị chờ quá lâu không? Nếu tính năng có xác suất dùng cao ngay đầu trang, tải trễ quá mức lại tạo trải nghiệm kém.
Trọng số: Quan trọng. Công cụ: Website Performance Test của Novaverb, Lighthouse, Chrome DevTools Coverage và Bundle Analyzer.
15. Tiêu chí 122: Kiểm soát mã bên thứ ba
Mỗi script bên thứ ba phải có chủ sở hữu, mục tiêu đo được và điều kiện tải rõ. Chat, heatmap, video, quảng cáo, A/B testing, social widget và tag marketing đều có thể tạo request, long task, cookie và rủi ro riêng tư.
| Trường cần ghi | Câu hỏi |
|---|---|
| Chủ sở hữu | Ai yêu cầu và ai chịu trách nhiệm kiểm? |
| Mục tiêu | Script tạo dữ liệu hoặc doanh thu nào? |
| Phạm vi | Cần toàn site hay chỉ một số trang? |
| Thời điểm | Cần trước render, sau consent hay sau tương tác? |
| Ngân sách | Byte, request và main-thread time tối đa? |
| Ngày rà lại | Khi nào xác nhận nó vẫn còn giá trị? |
Video nhúng có thể hiển thị poster và chỉ tạo iframe khi người dùng bấm phát. Chat có thể tải sau consent hoặc khi người dùng mở. Tag đo lường cần được kiểm bằng Tag Assistant và một kế hoạch dữ liệu, tránh cài cùng sự kiện qua theme, plugin và tag manager.
Dùng Network lọc theo domain, Lighthouse third-party summary và Performance trace để đo chi phí. Khi thử chặn một domain, kiểm cả trường hợp dịch vụ đó timeout, vì lỗi bên thứ ba không được làm nội dung chính ngừng hiển thị.
Trọng số: Bắt buộc. Công cụ: Website Performance Test của Novaverb, PageSpeed Insights, Chrome DevTools Network và Tag Assistant.
16. Tiêu chí 123: Nén tài nguyên văn bản bằng Brotli và Gzip
HTML, CSS, JavaScript, SVG và JSON nên được nén ở tầng máy chủ hoặc CDN, ưu tiên Brotli khi client hỗ trợ và dùng Gzip làm dự phòng. Đây là nén truyền tải, khác với minify. Minify làm nguồn ngắn hơn; Brotli hoặc Gzip nén byte trên đường truyền.
Máy chủ phải thương lượng theo Accept-Encoding và trả đúng Content-Encoding. Không nên nén lại JPEG, WebP, AVIF, MP4 hoặc file đã nén vì thường không tiết kiệm đáng kể và có thể tốn CPU.
curl -I -H "Accept-Encoding: br, gzip" https://example.com/app.css
# Cần thấy một trong các header phù hợp
Content-Encoding: br
Vary: Accept-EncodingTrong DevTools Network, so cột Size và Transferred. Nếu resource 300 KB nhưng transferred nhỏ hơn nhiều, nén đang hoạt động. Kiểm trên HTML, CSS, JS và JSON từ cả origin lẫn CDN, vì mỗi lớp có thể cấu hình khác nhau.
Với nội dung tĩnh, precompress lúc build giúp giảm CPU runtime. Với nội dung động, chọn mức nén cân bằng tài nguyên máy chủ và tỉ lệ giảm. Sau thay đổi, kiểm cache variant để client không nhận nhầm bản nén.
Trọng số: Bắt buộc. Công cụ: Website Performance Test của Novaverb, Chrome DevTools, cURL và WebPageTest.
17. Thứ tự ưu tiên triển khai trên WordPress
Ưu tiên theo tác động, độ chắc chắn và khả năng rollback, không theo thứ tự cảnh báo trong PageSpeed. Một ảnh LCP lazy-load nhầm thường nên sửa trước việc minify thêm vài KB HTML. Một plugin gửi 300 KB JS và tạo long task trên toàn site đáng xử lý trước vài selector CSS thừa.
| Ưu tiên | Việc | Lý do |
|---|---|---|
| P0 | Gỡ lazy-load khỏi LCP, sửa ảnh vỡ hoặc layout shift lớn | Tác động trực tiếp màn đầu và trải nghiệm |
| P1 | Resize ảnh, responsive image, render-blocking, script toàn site không cần | Giảm byte và đường tải trên nhiều trang |
| P2 | Long task, code splitting, third-party theo consent hoặc tương tác | Giảm CPU và cải thiện phản hồi |
| P3 | Minify, Brotli, dọn CSS/JS nhỏ còn lại | Hoàn thiện sau khi kiến trúc tải đúng |
Mỗi task nên có URL mẫu, baseline, giả thuyết, thay đổi, metric chính, guardrail và cách rollback. Triển khai theo template hoặc phần trăm traffic nếu hệ thống cho phép. Tránh bật cùng lúc lazy-load, combine file, defer JS, remove unused CSS và CDN rewrite vì khi lỗi xảy ra rất khó biết lớp nào gây ra.
Chốt ý: làm đúng việc lớn trước thường tạo kết quả rõ hơn việc cố xóa mọi cảnh báo màu đỏ.
18. Checklist QA sau khi tối ưu hình ảnh và code
Tối ưu “Checklist QA sau khi tối ưu hình ảnh và code” dễ thành chuỗi chỉnh sửa nhỏ lẻ nếu thiếu mốc đo và thứ tự ưu tiên. Khóa Học SEO Master đi vào cách xếp thứ tự đó.
Một thay đổi hiệu năng chỉ hoàn tất khi giao diện, chức năng, tracking và khả năng thu thập dữ liệu vẫn đúng. Điểm lab tăng nhưng menu hỏng, form không gửi hoặc Googlebot không thấy nội dung thì đó không phải tối ưu.
- Giao diện: mobile, tablet, desktop, Safari, Chrome; ảnh không mờ, không méo, không nhảy.
- Tương tác: menu, accordion, popup, slider, tìm kiếm, form, giỏ hàng và thanh toán.
- Trạng thái: chưa đăng nhập, đã đăng nhập, cookie chưa consent, đã consent, cache lạnh và cache ấm.
- Đo lường: pageview, event, conversion và consent state không bị trùng hoặc mất.
- SEO: HTML chính còn trong response hoặc render, canonical, schema, internal link và ảnh alt còn đúng.
- Hiệu năng: đo lại cùng URL và điều kiện, so trung vị nhiều lần, kiểm field data sau đủ thời gian.
- Máy chủ: Content-Encoding, cache-control, content-type và variant cache đúng.
- Rollback: biết file, cấu hình hoặc plugin nào cần hoàn tác nếu guardrail xấu.
Đặc biệt kiểm các component ẩn ban đầu. Coverage rất dễ làm người tối ưu xóa CSS của menu đóng, popup chưa mở hoặc error message chưa xuất hiện. Hãy chạy một kịch bản thao tác đầy đủ trước khi quyết định rule không dùng.
Tiêu chí dừng: metric chính cải thiện, guardrail không xấu vượt ngưỡng và không có lỗi chức năng mới.
19. Bộ công cụ kiểm tra hình ảnh và code
Dùng công cụ tổng hợp để tìm hướng, sau đó dùng DevTools để xác nhận tài nguyên và nguyên nhân cụ thể. Không nên sửa chỉ từ tên một audit vì cùng cảnh báo có thể đến từ theme, plugin, CDN hoặc bên thứ ba.
Công cụ kiểm tra nhanh
- PageSpeed Checker của Novaverb: đọc nhanh nhóm chỉ số và cơ hội tối ưu.
- Image Compressor của Novaverb: so chất lượng và dung lượng sau nén.
- Image Resizer của Novaverb: tạo kích thước gần vùng hiển thị.
- Image Converter của Novaverb: chuyển đổi định dạng ảnh.
- Online HTML Editor của Novaverb: thử markup trước khi đưa vào template.
- Website Performance Test của Novaverb: kiểm tra hiệu năng theo URL.
Tài liệu và công cụ gốc
- Google PageSpeed Insights
- Web.dev: Browser-level image lazy loading
- Web.dev: Optimize Largest Contentful Paint
- Web.dev: Serve responsive images
- Chrome DevTools: Lighthouse và Coverage
- MDN: async, defer và module script
- Web.dev: Optimize long tasks
- WordPress Developer Resources: loading optimization attributes
Có thể đọc thêm hướng dẫn SEO hình ảnh, PageSpeed là gì và Core Web Vitals để nối kỹ thuật tải tài nguyên với mục tiêu SEO.
20. Câu hỏi thường gặp và kết luận
Phần hỏi đáp dưới đây chốt các quyết định dễ làm sai nhất khi tối ưu ảnh và code WordPress.
Có nên lazy-load toàn bộ ảnh trên website không?
Không. Ảnh nằm trong vùng hiển thị ban đầu, đặc biệt ảnh LCP, nên được tải bình thường và có thể dùng fetchpriority="high" khi bằng chứng cho thấy cần ưu tiên. Chỉ lazy-load ảnh và iframe nằm ngoài màn hình đầu.
Một ảnh chuẩn SEO phải dưới bao nhiêu KB?
Không có ngưỡng chung. Hãy xét kích thước hiển thị, DPR, nội dung ảnh, định dạng, chất lượng nhìn thấy và vai trò trong đường tải. Ngân sách ảnh hero khác thumbnail và icon.
Điểm PageSpeed 100 có phải mục tiêu bắt buộc?
Không. Mục tiêu là trải nghiệm nhanh và ổn định trên người dùng thật, chức năng đúng và Core Web Vitals đạt yêu cầu. Điểm lab dùng để chẩn đoán và so sánh có kiểm soát, không thay thế dữ liệu thực tế.
Có nên combine toàn bộ CSS và JavaScript thành một file?
Không mặc định. Một file có thể giảm request nhưng làm trang nào cũng tải code không cần, giảm hiệu quả cache theo phần và cản code splitting. HTTP hiện đại làm lợi ích của combine phụ thuộc kiến trúc cụ thể.
Coverage màu đỏ có nghĩa là có thể xóa ngay không?
Không. Nó chỉ cho biết đoạn code chưa chạy trong phiên ghi hiện tại. Hãy kích hoạt menu, modal, breakpoint, form error và các trạng thái đặc biệt trước khi đánh giá.
Plugin tối ưu có thể làm thay toàn bộ quy trình không?
Plugin có thể tự động hóa minify, cache, lazy loading hoặc defer, nhưng không tự biết ảnh nào là LCP trên mọi template, script nào tạo giá trị kinh doanh và trạng thái nào cần giữ. Vẫn phải đo, khoanh phạm vi và QA.
Kết luận: SEO WordPress ở lớp hình ảnh và code là bài toán phân phối tài nguyên. Ảnh đúng cỡ nhưng tải sai thời điểm vẫn chậm; JavaScript đã nén nhưng không dùng vẫn tốn CPU. Hãy đi theo chuỗi đo hiện trạng, tìm tài nguyên, sửa một nhóm, kiểm hồi quy, đo lại. Khi mỗi thay đổi có bằng chứng và đường rollback, website nhanh hơn mà không đánh đổi giao diện, tracking hay khả năng index.