Thiết kế kiểm thử hiệu năng website với Lighthouse và k6
Một con số hiệu năng chỉ có ý nghĩa khi biết nó được đo ở đâu, bằng kịch bản nào và so với mốc nào.
🧭 Mô hình tổng thể
Source commit -> Astro static build
| |
v +-> Lighthouse -> lab report
Deploy Pages
|
(Manual trigger) -> k6 load test -> HTTP report
Mỗi source deploy tạo một artifact tĩnh. Lighthouse kiểm tra artifact tự động trước khi publish; sau khi deploy thành công, maintainer kích hoạt k6 thủ công qua workflow_dispatch để gọi các URL production theo profile đã định. Kết quả được chuẩn hóa thành dữ liệu nhỏ để hai trang report render sẵn, kể cả khi trình duyệt tắt JavaScript.
🔍 Hai phép đo, hai câu hỏi
Lighthouse: browser lab / từng route
-> LCP, FCP, TBT, CLS, score
-> ghi route, thời điểm, máy, mạng, phiên bản
!= trải nghiệm mọi người dùng; không đo INP
k6: VU -> GET route công khai -> nghỉ
-> p95, lỗi, throughput, request, dropped iteration
- LCP: thời điểm nội dung lớn nhất hiển thị.
- FCP: thời điểm nội dung đầu tiên hiển thị.
- TBT: tổng thời gian luồng chính bị chặn.
- CLS: mức dịch chuyển bố cục bất ngờ.
- INP: độ trễ phản hồi tương tác của trang.
- VU: người dùng ảo chạy kịch bản k6.
- HTTP: giao thức dùng để gửi request web.
⚡ Lighthouse trước khi deploy
Build preview -> Lighthouse: 3 route, mobile profile
| -> metric + score + build/index/size
v
So baseline cùng profile và route -> report delta
Content tăng -> theo dõi build, index, trang bị ảnh hưởng
- Route: địa chỉ/trang được kiểm thử.
- Mobile profile: cấu hình mô phỏng thiết bị và mạng di động.
- Baseline: snapshot trước dùng làm mốc so sánh.
- Delta: chênh lệch giữa kết quả hiện tại và baseline.
- Metric / score: số đo riêng lẻ / điểm tổng hợp.
- Build / index: thời gian dựng site / dữ liệu tìm kiếm Pagefind.
dist: thư mục chứa site tĩnh sau khi build.
Chỉ so sánh khi route và profile tương thích; delta là tín hiệu theo dõi, không thay quality threshold CI. Site tĩnh dựng HTML lúc build; content tăng có thể ảnh hưởng thời gian build, index hoặc kích thước trang liên quan. Astro: on-demand rendering và prerendering
👥 k6 theo yêu cầu thủ công (Manual Dispatch)
Deploy tự động (.github/workflows/deploy.yml)
-> Push main -> Build -> Publish Pages (Dừng, không chạy k6)
Load test thủ công (.github/workflows/load-test.yml)
-> Actions UI / gh CLI -> Run workflow -> k6 run -> Bot push snapshot
1. Cách chuyển từ Auto sang Manual
Bước 1: Xóa job load-test tự động khỏi pipeline deploy .github/workflows/deploy.yml:
# Trong deploy.yml: Chỉ giữ lại job build-and-deploy
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- run: npm run build:with-lighthouse
- uses: peaceiris/actions-gh-pages@v4
Bước 2: Tạo workflow độc lập .github/workflows/load-test.yml với trigger workflow_dispatch
name: Manual K6 Performance Load Test
on:
workflow_dispatch:
inputs:
target_url:
description: 'Target site URL'
required: false
default: 'https://pkduong.github.io'
jobs:
load-test:
runs-on: ubuntu-latest
environment: load-test
steps:
- uses: actions/checkout@v4
- uses: grafana/setup-k6-action@v1
- name: Run production K6
env:
TARGET_URL: ${{ inputs.target_url || 'https://pkduong.github.io' }}
K6_WEB_DASHBOARD: 'true'
K6_WEB_DASHBOARD_EXPORT: '.tmp/load-test/report.html'
run: |
mkdir -p .tmp/load-test
k6 run --out web-dashboard=export=.tmp/load-test/report.html tests/load/pages-read-only.k6.js
2. Tip thực chiến
- Triệt tiêu commit rác (
chore(perf)): Nếu chạy k6 tự động sau mỗi deploy, bot k6 sẽ tạo commit snapshot rác liên tục trênmain, làm nhiễu Git log. - Tiết kiệm tài nguyên CI: Kịch bản k6
ramping-vusngốn 7–10 phút runner. Tách sang manual giúp chỉ đo khi thật sự cần nghiệm thu release lớn. - Tip chạy kiểm thử cục bộ (Local Command):
TARGET_URL="https://pkduong.github.io" K6_WEB_DASHBOARD=true k6 run --out web-dashboard=export=.tmp/load-test/report.html tests/load/pages-read-only.k6.js - Tip kích hoạt qua GitHub CLI (
gh):gh workflow run load-test.yml -f target_url="https://pkduong.github.io"
📈 So sánh sự khác biệt Delta:
Snapshot mới
-> đối chiếu điều kiện đo với baseline
-> không khớp: đánh dấu không tương thích
-> khớp: tính delta và hiển thị thông tin
-> lọc kết quả k6 thành JSON snapshot
-> App chỉ stage đường dẫn được phép
-> bot commit -> build report; bỏ k6 ở lượt publish này
Lighthouse cần cùng phiên bản công cụ, mobile profile và tập route; k6 cần cùng target, profile, route mix, phiên bản major và runner. Snapshot là kết quả đã lưu của một lần đo; route mix là tỷ trọng các route trong kịch bản; runner là môi trường chạy test.
Với k6, delta của error rate (tỷ lệ request lỗi) và check rate (tỷ lệ điều kiện kiểm tra đạt) dùng điểm phần trăm. p95 là ngưỡng mà 95% request không chậm hơn; throughput là lượng request xử lý theo thời gian. Hai chỉ số này hiển thị cả chênh lệch tuyệt đối lẫn tương đối.
Một lần đo chậm hơn chỉ là tín hiệu vì CDN, mạng hoặc runner cũng có thể ảnh hưởng; hai report không chặn deploy hay rollback. Stage là chọn file vào commit: GitHub App chỉ cài trên source repository và workflow chỉ stage JSON snapshot ở đường dẫn cho phép. Commit của bot vẫn build report tĩnh, nhưng lượt publish đó được nhận diện để không chạy k6 lặp lại.
🔗 Các báo cáo chính thức và bằng chứng kiểm thử
Hệ thống đã triển khai độc lập hai tầng báo cáo: trang snapshot tổng hợp có delta/lịch sử chạy, cùng liên kết trực tiếp tới file HTML báo cáo chi tiết nguyên bản của từng công cụ phục vụ bằng chứng nghiệm thu:
- Báo cáo kiểm thử tải (K6):
- Trang tổng quan & so sánh baseline:
https://pkduong.github.io/load-test/ - Báo cáo K6 Web Dashboard chi tiết (HTML có biểu đồ):
https://pkduong.github.io/load-test/k6/index.html
- Trang tổng quan & so sánh baseline:
- Báo cáo phòng lab (Lighthouse):
- Trang tổng quan & Core Web Vitals:
https://pkduong.github.io/lighthouse/ - Báo cáo Lighthouse Audit chi tiết (HTML gốc):
https://pkduong.github.io/lighthouse/perf-test/index.html
- Trang tổng quan & Core Web Vitals:
Tất cả các báo cáo trên được sinh tự động trong pipeline CI/CD GitHub Actions và deploy trực tiếp lên GitHub Pages tĩnh.
📚 Kết luận
┌─────────── HỆ THỐNG ĐO HIỆU NĂNG ──────────┐
│ 1. LAB (CI Tự động) -> Lighthouse │
│ • Đo: LCP, TBT, CLS (route đơn lẻ) │
│ │
│ 2. LOAD (Manual Trigger) -> k6 Engine │
│ • Đo: p95, throughput (tải CDN) │
└─────────────────────┬─────────────────────┘
▼
[ Đối chiếu Delta chuẩn mốc ]
Cùng route + Cùng profile
Một hệ thống đo hiệu năng hiệu quả không nằm ở việc chạy dồn dập công cụ sau mỗi lần deploy, mà ở việc tách biệt đúng tầng trách nhiệm:
- Chặn sớm ở cửa ngõ (Lighthouse): Tự động kiểm tra trải nghiệm tải trang trên từng route tĩnh ngay lúc build để phát hiện sớm suy thoái về CSS/JS hay kích thước trang.
- Kiểm tra sức bền khi cần (k6 manual dispatch): Giữ pipeline deploy gọn nhẹ, chỉ kích hoạt tải đồng thời lên CDN khi cần nghiệm thu thực tế, loại bỏ hoàn toàn commit snapshot rác.
- Giá trị nằm ở Delta: Mọi con số chỉ có ý nghĩa khi so sánh chênh lệch (delta) trên cùng một hệ quy chiếu và điều kiện đo tương thích.
🧾 Tóm tắt bỏ túi (Take away)
| Điểm chính | Hành động |
|---|---|
| Lighthouse đo browser lab | So LCP/TBT/CLS giữa các build có cùng profile và route. |
| k6 kích hoạt thủ công (Manual) | Chạy workflow_dispatch khi cần; đọc p95, lỗi và throughput. |
| Delta cần baseline tương thích | Kiểm tra commit, thời điểm, route và điều kiện đo. |