§ blog · Optimization Loop18/10/2026
← Tất cả bài viết

Website nhanh trên máy bạn, chậm trên điện thoại khách: đo bằng số của người dùng thật trước khi sửa

Chủ doanh nghiệp mở website trên điện thoại đời mới qua wifi văn phòng thấy trang hiện trong một giây rưỡi. Khách mở bằng điện thoại tầm trung trên 4G có thể phải chờ gấp đôi. Google đánh giá tốc độ bằng con số ở phân vị 75 của người dùng thật, không phải con số trên máy chủ website. Bài này giải thích ba chỉ số Core Web Vitals bằng lời thường, vì sao điểm Lighthouse không phải là chúng, ba phép tính tự làm được, và sáu bước đo–sửa–đo lại.

Core Web VitalsTốc độ websiteOptimization LoopĐo lường15 phút đọc
By KonexForge Engineering Team
BA CHỈ SỐ · NGƯỠNG TỐT Ở PHÂN VỊ 75LCP≤ 2,5 snội dung lớn nhất hiện rakém: > 4 sINP≤ 200 mschạm → màn hình phản hồikém: > 500 msCLS≤ 0,1nội dung nhảy chỗ khi tảikém: > 0,25CÙNG MỘT WEBSITE · LCP THEO AI ĐANG NHÌN (VÍ DỤ MINH HOẠ)0 s1 s2 s3 s4 s5 s6 svượt ngưỡng 2,5 schủ website 1,6p75 sau khi sửa 2,2p75 khách thật 3,238% lượt truy cậpẢNH BANNER · THỜI GIAN TẢI TỐI THIỂU Ở 1,6 Mbps200 KB1 s500 KB2,5 s1,5 MB7,5 s3 MB15 sSÁU BƯỚC ĐO – SỬA – ĐO LẠI1 · SỐ NGƯỜI DÙNG THẬTPageSpeed Insights · Mobile2 · TÌM PHẦN TỬ LCPDevTools · Performance3 · ĐO DUNG LƯỢNG ẢNHcurl -sI · content-length4 · KHÔNG LAZY ẢNH ĐẦUfetchpriority · width/height5 · TỰ THU SỐ THẬTweb-vitals · sendBeacon6 · SỬA MỘT THỨ, CHỜcửa sổ trượt 28 ngàyở p75 của khách thật, trên điện thoại, ba con số đang là bao nhiêu?nguồn: ngưỡng web-vitals · cấu hình Lighthouse · mô phỏng KonexForgekonexforge.com

Một chủ cửa hàng mở website của mình trên chiếc điện thoại mới mua, qua wifi văn phòng. Trang hiện ra trong khoảng một giây rưỡi. Bạn ấy kết luận website nhanh, và hoàn toàn đúng — với chiếc máy đó, trên mạng đó.

Cùng lúc ấy, một khách hàng ở huyện mở cùng trang bằng chiếc điện thoại Android tầm trung mua ba năm trước, qua 4G lúc sóng yếu. Ảnh banner hiện ra sau gần bốn giây. Khi ảnh vừa hiện, đoạn chữ phía dưới bị đẩy xuống, ngón tay đang định bấm nút "Gọi ngay" chạm nhầm vào một liên kết khác.

Hai người đang nhìn hai website khác nhau, dù cùng một địa chỉ. Và khi Google đánh giá tốc độ trang, Google nhìn gần với người thứ hai hơn người thứ nhất.

Ba con số Google dùng, nói bằng lời thường

Core Web Vitals (tạm dịch: các chỉ số sống còn của trang web) là ba chỉ số Google dùng để đo trải nghiệm tải trang từ phía người dùng. Mỗi chỉ số có hai ngưỡng — dưới ngưỡng thứ nhất là tốt, trên ngưỡng thứ hai là kém:

  • LCP (Largest Contentful Paint — thời điểm phần nội dung lớn nhất hiện ra, thường là ảnh banner hoặc khối tiêu đề). Tốt: không quá 2,5 giây. Kém: trên 4 giây.
  • INP (Interaction to Next Paint — độ trễ từ lúc người dùng chạm hoặc bấm tới lúc màn hình phản hồi). Tốt: không quá 200 mili giây. Kém: trên 500 mili giây. INP thay cho chỉ số cũ FID từ ngày 12/3/2024, nên tài liệu nào còn nói về FID là tài liệu cũ.
  • CLS (Cumulative Layout Shift — mức độ nội dung bị nhảy chỗ trong lúc tải). Tốt: không quá 0,1. Kém: trên 0,25.

Điểm quan trọng nhất nằm ở cách lấy con số: Google không lấy trung bình, mà lấy phân vị 75 (p75) — giá trị mà 75% lượt truy cập đạt bằng hoặc tốt hơn. Một trang chỉ được coi là đạt khi cả ba chỉ số ở p75 đều nằm trong ngưỡng tốt. Nói cách khác, một phần tư lượt truy cập chậm nhất được phép kém hơn, nhưng phần còn lại phải tốt.

Vì sao "trên máy tôi nhanh" không phải là câu trả lời

Để thấy p75 khác cảm nhận của chủ website đến mức nào, chúng tôi dựng một ví dụ minh hoạ. Đây là giả định để thấy cơ chế, không phải số đo của một website cụ thể: 60% khách dùng máy khoẻ, mạng tốt, LCP điển hình 1,6 giây; 40% khách dùng máy tầm trung hoặc mạng yếu, LCP điển hình 3,6 giây. Mỗi nhóm có dao động tự nhiên quanh con số điển hình. Mô phỏng một triệu lượt truy cập cho kết quả:

  • Lượt truy cập điển hình của nhóm khoẻ: 1,6 giây — đây là con số chủ website thấy.
  • Trung bình mọi lượt: 2,6 giây. Trung vị: 2,05 giây — nhìn vào trung vị, website có vẻ đạt.
  • p75: 3,2 giây — không đạt, dù chưa chạm ngưỡng kém.
  • 38% lượt truy cập chờ quá 2,5 giây. Trong nhóm máy yếu, tỉ lệ này là 79%.

Website trong ví dụ không chậm với người làm ra nó. Nó chậm với gần bốn trong mười khách. Và đó chính là nhóm mà con số p75 được thiết kế để không bỏ qua.

Hệ quả thực tế: kiểm tra tốc độ bằng cách tự mở trang, dù trên điện thoại, gần như luôn cho kết quả lạc quan hơn thực tế. Máy của người làm website thường khoẻ hơn, mạng tốt hơn, và trình duyệt đã lưu sẵn một phần trang từ những lần mở trước.

Hai loại số: số của người dùng thật và số giả lập

Khi dán địa chỉ trang vào PageSpeed Insights, bạn nhận hai phần rất khác nhau trên cùng một màn hình, và nhầm lẫn giữa hai phần này là nguyên nhân phổ biến nhất khiến việc tối ưu đi sai hướng.

Phần trên cùng là số của người dùng thật (field data). Nó lấy từ Chrome UX Report (CrUX) — báo cáo Google tổng hợp từ một phần người dùng Chrome thật — trong cửa sổ trượt 28 ngày, ở p75, tách riêng điện thoại và máy tính. Đây là con số Google dùng khi xét trải nghiệm trang.

Phần bên dưới là số giả lập (lab data) do Lighthouse chạy một lần trên máy chủ của Google. Với tab điện thoại, Lighthouse giả lập mạng có độ trễ 150 mili giây, tốc độ tải xuống 1,6 Mbps, và làm chậm CPU 4 lần để giống một điện thoại tầm trung. Điểm từ 0 đến 100 là điểm tổng hợp của lần chạy này.

Điểm Lighthouse 0–100 không phải là Core Web Vitals. Một trang có thể đạt 95 điểm mà vẫn trượt ở người dùng thật, hoặc chỉ được 60 điểm mà vẫn đạt — vì người dùng thật không dùng đúng chiếc máy giả lập đó.

Hai loại số có hai việc khác nhau. Số người dùng thật trả lời câu hỏi có vấn đề hay không. Số giả lập trả lời câu hỏi vấn đề nằm ở đâu, vì nó cho xem từng bước tải trang. Quy trình đúng là đọc số thật trước, rồi mới dùng số giả lập để tìm nguyên nhân.

Một lưu ý cho doanh nghiệp nhỏ: CrUX chỉ công bố số cho trang hoặc site có đủ lượt truy cập trong 28 ngày, và Google không công bố ngưỡng cụ thể. Nhiều website doanh nghiệp vừa và nhỏ sẽ thấy dòng "không đủ dữ liệu". Khi đó không phải là không có vấn đề — chỉ là Google không đo hộ bạn. Bước 5 bên dưới chỉ cách tự đo.

Phép tính thứ nhất: ảnh banner tốn bao nhiêu giây

Với phần lớn website doanh nghiệp, phần tử quyết định LCP trên điện thoại là ảnh banner đầu trang. Và thủ phạm phổ biến nhất là ảnh quá nặng, thường do tải nguyên ảnh chụp từ máy ảnh hoặc ảnh thiết kế xuất ra mà không nén.

Phép tính đơn giản: số kilobyte × 8 ÷ tốc độ mạng (kilobit mỗi giây) = số giây tối thiểu để tải ảnh. Trên mạng 1,6 Mbps mà Lighthouse giả lập:

  • 100 KB: 0,5 giây
  • 200 KB: 1 giây
  • 500 KB: 2,5 giây — tiêu hết cả ngân sách LCP chỉ cho việc tải ảnh
  • 1,5 MB: 7,5 giây
  • 3 MB: 15 giây

Đây là mức tối thiểu, chưa tính thời gian kết nối tới máy chủ, tải HTML, CSS, phông chữ và thời gian trình duyệt vẽ ảnh. Ảnh banner 3 MB — chuyện không hiếm khi ảnh được tải thẳng từ máy ảnh — gần như chắc chắn đẩy trang vào vùng kém trên điện thoại, bất kể máy chủ nhanh đến đâu.

Kiểm tra dung lượng một ảnh không cần công cụ đặc biệt. Chuột phải vào ảnh, chọn "Sao chép địa chỉ hình ảnh", rồi chạy trong terminal:

curl -sI <địa-chỉ-ảnh> | grep -i content-length

Con số trả về là số byte. Chia 1.000 để ra kilobyte. Nếu dòng này không có (một số máy chủ nén khi truyền), mở DevTools, tab Network, lọc Img và đọc cột Size.

Phép tính thứ hai: một ảnh thiếu kích thước làm CLS trượt thế nào

CLS được tính cho mỗi lần nội dung nhảy chỗ bằng tích hai phần: phần màn hình bị ảnh hưởng (impact fraction) nhân với quãng đường nội dung bị đẩy đi (distance fraction), cả hai tính theo tỉ lệ chiều cao màn hình.

Ví dụ: một khối chữ chiếm 60% màn hình. Phía trên nó, một ảnh không khai báo chiều cao tải xong và đẩy khối chữ xuống một đoạn bằng 25% màn hình. Vùng bị ảnh hưởng là vị trí cũ cộng phần mở rộng: 60% + 25% = 85%. Quãng đường bị đẩy: 25%. Điểm của lần nhảy này: 0,85 × 0,25 ≈ 0,21 — gấp đôi ngưỡng tốt 0,1, chỉ từ một ảnh.

Cách sửa rẻ nhất trong toàn bộ bài này: thêm thuộc tính width và height cho mọi thẻ img. Trình duyệt dùng tỉ lệ của hai số này để giữ chỗ trước khi ảnh về, ngay cả khi CSS co ảnh lại theo màn hình. Các thủ phạm CLS phổ biến khác: thanh thông báo cookie hoặc khuyến mãi chèn lên đầu trang sau khi trang đã hiện, khung quảng cáo hoặc video nhúng không có chỗ giữ sẵn, và phông chữ web thay phông dự phòng có kích thước chênh nhiều.

Phép tính thứ ba: INP và những đoạn mã không phải của bạn

INP đo độ trễ của tương tác chậm nhất (gần như vậy) trong suốt thời gian người dùng ở trên trang. Trình duyệt chỉ có một luồng chính để vừa chạy JavaScript vừa vẽ màn hình. Khi một đoạn mã chạy liên tục — mà trình duyệt gọi là tác vụ dài (long task) nếu quá 50 mili giây — thì cú chạm của người dùng phải xếp hàng chờ.

Phép tính: CPU điện thoại tầm trung chậm khoảng 4 lần máy tính để bàn (đúng hệ số mà Lighthouse dùng để giả lập). Một đoạn mã chạy 60 mili giây trên máy tính của lập trình viên — không ai để ý — có thể thành khoảng 240 mili giây trên máy khách, và đã vượt ngưỡng 200 mili giây trước khi tính thời gian vẽ lại màn hình.

Trên website doanh nghiệp, phần lớn mã chạy trên trang thường không do đội làm website viết: khung chat trực tuyến, mã theo dõi quảng cáo của nhiều nền tảng, bản đồ nhúng, công cụ ghi lại phiên truy cập, khung đánh giá của bên thứ ba. Mỗi cái đều nhỏ khi thêm vào, và hiếm khi có ai đếm chúng lại.

Việc nên làm: mở DevTools, tab Network, lọc JS, sắp xếp theo tên miền. Liệt kê mọi tên miền không phải của bạn và hỏi với từng cái: còn ai dùng số liệu của nó không? Mã theo dõi của một chiến dịch quảng cáo đã dừng từ năm ngoái là một tác vụ dài miễn phí cho mọi lượt truy cập. Với những gì cần giữ, phần lớn có thể nạp sau khi trang đã hiện — ví dụ khung chat chỉ nạp khi người dùng bấm vào nút chat.

Sáu bước đo–sửa–đo lại

Thứ tự dưới đây được sắp để mỗi bước dùng kết quả của bước trước, và để việc rẻ được làm trước việc đắt.

Bước 1. Đọc số của người dùng thật, tab điện thoại. Mở pagespeed.web.dev, dán địa chỉ, chọn Mobile, đọc phần trên cùng trước phần điểm số. Ghi lại p75 của LCP, INP, CLS. Nếu trang không đủ dữ liệu, xem mức toàn site. Nếu cả site cũng không có, sang bước 5 trước.

Bước 2. Tìm phần tử LCP. Trong Chrome, mở DevTools (F12), tab Performance. Ở biểu tượng bánh răng, đặt CPU "4x slowdown" và mạng "Slow 4G", rồi bấm nút tải lại và ghi. Trên dòng thời gian có mốc LCP; bấm vào đó để thấy phần tử nào. Mọi việc sửa LCP bắt đầu từ phần tử này.

Bước 3. Đo dung lượng ảnh đó. Dùng lệnh curl -sI ở trên. Ảnh banner cho điện thoại nên dưới khoảng 200 KB; phần lớn ảnh chụp đạt được mức này khi xuất ở định dạng WebP hoặc AVIF với chiều rộng vừa màn hình điện thoại, và dùng thuộc tính srcset để máy tính nhận bản lớn hơn.

Bước 4. Kiểm tra ảnh đầu trang không bị trì hoãn. Ở tab Elements, tìm thẻ img của banner. Nếu có loading="lazy", hãy bỏ đi — thuộc tính này bảo trình duyệt tải ảnh muộn, đúng cho ảnh cuối trang nhưng sai cho ảnh đầu trang. Thêm fetchpriority="high" để trình duyệt ưu tiên ảnh này. Nếu banner là một slider dựng bằng JavaScript, ảnh chỉ bắt đầu tải sau khi mã slider chạy xong — cân nhắc để ảnh đầu tiên là thẻ img thường trong HTML. Cùng lúc, kiểm tra mọi img và iframe đều có width và height.

Bước 5. Tự thu số của người dùng thật. Google phát hành thư viện mã nguồn mở web-vitals để đo đúng ba chỉ số này trên trình duyệt của khách. Đoạn mã tối thiểu:

import {onCLS, onINP, onLCP} from 'web-vitals';

const send = (m) => navigator.sendBeacon('/analytics', JSON.stringify({name: m.name, value: m.value, rating: m.rating, id: m.id}));

onCLS(send); onINP(send); onLCP(send);

Thay /analytics bằng địa chỉ nhận dữ liệu của bạn — hoặc gửi thành sự kiện vào công cụ thống kê đang dùng. navigator.sendBeacon gửi được cả khi khách đang đóng trang, điều cần thiết vì INP và CLS chỉ chốt số khi người dùng rời đi. Sau vài tuần, tính p75 cho từng chỉ số, tách điện thoại và máy tính. Thư viện có sẵn trường rating (good / needs-improvement / poor) theo đúng ngưỡng ở trên, nên không cần tự so ngưỡng.

Bước 6. Sửa một thứ, ghi trước và sau, chờ đủ lâu. Mỗi lần chỉ sửa một nguyên nhân để biết cái nào có tác dụng. Số trên PageSpeed Insights là cửa sổ trượt 28 ngày, nên sau khi sửa, con số sẽ dịch dần trong khoảng bốn tuần chứ không đổi ngay. Số tự thu ở bước 5 cho thấy kết quả sau vài ngày. Đây là lý do việc tối ưu tốc độ là một vòng lặp, không phải một lần sửa.

Quay lại ví dụ minh hoạ ở đầu bài: nếu việc nén ảnh banner và bỏ lazy-load giúp nhóm máy khoẻ nhanh thêm 0,3 giây và nhóm máy yếu nhanh thêm khoảng 1,3 giây (nhóm máy yếu được lợi nhiều hơn vì nút thắt của họ chính là mạng), p75 giảm từ 3,2 xuống 2,2 giây — đạt, và tỉ lệ lượt truy cập chờ quá 2,5 giây giảm từ 38% xuống 19%. Không cần đổi máy chủ, không cần viết lại website.

Còn chuyện thứ hạng tìm kiếm thì sao

Google xác nhận Core Web Vitals là một phần trong các tín hiệu trải nghiệm trang mà hệ thống xếp hạng sử dụng. Nhưng Google cũng nói rõ rằng nội dung phù hợp với câu hỏi của người tìm vẫn được ưu tiên, kể cả khi trải nghiệm trang chưa tốt. Một trang nhanh nhưng không trả lời đúng câu hỏi sẽ không vượt lên chỉ nhờ tốc độ.

Vì vậy lý do chính để sửa không phải là thứ hạng. Lý do chính là người khách ở đầu bài: người đã bấm vào liên kết của bạn — tức là bạn đã trả giá cho lượt bấm đó, bằng quảng cáo hoặc bằng công sức làm nội dung — rồi phải chờ bốn giây, và bấm nhầm vì nút bị đẩy đi.

Kết

Câu hỏi "website có nhanh không" không có một câu trả lời, vì website nhanh hay chậm tuỳ vào ai đang mở nó. Câu hỏi có câu trả lời là: ở phân vị 75 của khách hàng thật, trên điện thoại, ba con số đang là bao nhiêu?

Phần lớn website doanh nghiệp trượt ở câu hỏi đó vì vài nguyên nhân quen thuộc — một ảnh quá nặng, một ảnh bị trì hoãn sai chỗ, vài ảnh thiếu kích thước, vài đoạn mã của bên thứ ba không ai còn dùng. Những thứ này đều sửa được trong vài ngày. Điều thường thiếu là thói quen đo trước khi sửa và đo lại sau khi sửa.

Nếu bạn muốn có người đo website của mình bằng số của người dùng thật, tìm đúng nguyên nhân và sửa theo vòng lặp đo–sửa–đo lại, liên hệ với chúng tôi hoặc xem năng lực Optimization Loop của KonexForge.

Bài viết liên quan

Optimization Loop

Trước khi chạy A/B test, tính một con số — với phần lớn website Việt Nam nó lớn hơn lưu lượng cả năm

Muốn biết thử nghiệm A/B của bạn có kết luận được gì không thì không cần chạy mới biết. Có một phép tính làm trong một phút cho ra số lượt truy cập tối thiểu. Với một website 500 khách mỗi ngày, phát hiện được mức cải thiện 10% cần 322 ngày — và thói quen ngó kết quả mỗi ngày đẩy tỷ lệ báo thắng nhầm từ 4% lên 20%.

Optimization Loop

Thiết kế alert pipeline tránh alert fatigue: từ threshold cứng đến anomaly detection

Hệ thống alert đặt threshold quá nhạy sẽ gửi hàng chục cảnh báo mỗi ngày — team dần bỏ qua, và alert thực sự bị chìm vào noise. Alert đặt quá cao thì phát hiện sự cố khi đã quá muộn. Thiết kế alert pipeline ba tầng: static threshold, dynamic baseline và anomaly detection, kết hợp với routing và escalation policy để cảnh báo đến đúng người vào đúng thời điểm.

Optimization Loop

Model AI trong production suy giảm như thế nào — và cách phát hiện trước khi quá trễ

Sau khi deploy, model AI tiếp tục nhận input và trả kết quả — nhưng thế giới xung quanh nó thay đổi. Data drift và concept drift là hai cơ chế khiến một model từng hoạt động tốt dần mất độ chính xác mà không có lỗi nào được log. Cách phát hiện sớm, thiết kế monitoring pipeline theo ba tầng, và quyết định khi nào retrain thay vì chỉ vá triệu chứng.

Có một bài toán tương tự đang cần giải?

Liên hệ team