🏛️ Vai trò kiểm soát chất lượng của Frontend Architect
- Trong vai trò kiến trúc sư frontend, nhiệm vụ lớn nhất là giám sát sự phát triển của website và hệ thống thiết kế (design system).
- Tuy nhiên, với quy mô lớn:
- Đội ngũ có thể hàng chục người.
- Hàng trăm commit mỗi tuần.
- Hàng ngàn dòng code.
- Không thể kỳ vọng một cá nhân có thể kiểm tra từng dòng code.
- Nhưng mức độ giám sát đó lại cần thiết để đảm bảo hệ thống ổn định.
🐛 Các loại lỗi (regressions) có thể xảy ra khi có code mới
- Lỗi tính toán logic
→ Ví dụ: Sai giá sản phẩm. - Lỗi chức năng quan trọng
→ Ví dụ: Người dùng không thể thanh toán bằng giỏ hàng. - Lỗi giao diện người dùng (UI)
→ Ví dụ: Người dùng vẫn hoàn thành nhiệm vụ, nhưng giao diện gây khó chịu hoặc không đồng nhất. - Lỗi hiệu năng
→ Ví dụ: Website chậm đến mức gần như không thể hoàn tất thanh toán từ một số thiết bị hoặc khu vực địa lý.
🔔 Hậu quả chung:
Tất cả các lỗi trên đều dẫn đến mất doanh thu.
🧪 Giải pháp chung cho các loại lỗi: Testing!
- Kiến trúc sư không thể kiểm soát từng commit.
- Thay vào đó, cần xây dựng hệ thống kiểm thử (testing suites) để đảm bảo chất lượng tự động.
📝 Nguyên tắc lập kế hoạch test coverage
🌟 1. Viết test khi hoặc trước khi viết code.
- Test không chỉ viết sau mà có thể có trước (test-driven development).
🌟 2. Test là một phần sống của codebase.
- Test phải được commit cùng hoặc sát bên repo của hệ thống.
🌟 3. Mọi test phải pass trước khi merge vào nhánh master.
- Không có ngoại lệ: Tất cả các bài test phải chạy thành công trước khi code được hợp nhất.
🌟 4. Nhánh master luôn luôn ở trạng thái ổn định.
- Bất kỳ commit nào làm hỏng:
- Logic tính toán,
- Chức năng kinh doanh cốt lõi,
- Hiển thị UI chính xác,
- Hoặc hiệu năng tổng thể → Đều không được phép merge.
🎯 Trọng tâm của Kiến trúc sư
- Không dành thời gian đọc từng dòng code.
- Có tập trung vào xây dựng hệ thống kiểm thử toàn diện và chất lượng để tự động hóa việc kiểm soát chất lượng.
🧩 Định nghĩa Unit Testing
- Unit testing là quá trình:
- Phân rã ứng dụng thành các chức năng nhỏ nhất.
- Viết các bài kiểm thử tự động, có thể lặp lại, và luôn cho kết quả nhất quán.
- Các bài unit test là nền tảng xây dựng tương lai của codebase.
- ❗ Nếu không có unit tests:
- Một chức năng ít dùng có thể hỏng hàng tháng trời mà không ai phát hiện.
- ✅ Với unit tests:
- Mọi chức năng hệ thống được kiểm tra trước khi code merge vào master (chứ chưa nói tới production).
🧰 Vai trò của Frontend Architect
- Trang bị công cụ giúp developer làm việc hiệu quả hơn.
- Unit testing là một công cụ thiết yếu.
- Dù backend hay frontend, luôn có công cụ testing phù hợp:
PHPUnit
(PHP)NodeUnit
(Node.js)QUnit
(JavaScript)
- Không cần giỏi hết tất cả các framework ➔ Nhưng cần nắm vững các nguyên lý cơ bản để:
- Viết code dễ test.
- Nhanh chóng thích nghi với framework mới.
🛠️ Nguyên lý cơ bản: “Do one thing, and do it well”
🌟 Ví dụ hàm ban đầu:
Tính phí vận chuyển từ địa chỉ khách hàng đến trung tâm phân phối gần nhất.
🌟 Các bước hàm thực hiện:
- Tìm trung tâm phân phối gần nhất.
- Tính khoảng cách giữa hai địa chỉ.
- Tính phí vận chuyển dựa trên khoảng cách.
➡️ Nhận xét:
Một hàm nhưng làm 3 việc khác nhau ➔ Vi phạm nguyên tắc “làm một việc duy nhất và làm thật tốt”.
🔄 Refactor thành các đơn vị nhỏ
- Tách ra 3 hàm riêng:
- lookupNearestCenter(address)
- calculateDistance(address1, address2)
- calculateShippingCost(distance)
- Lợi ích:
- Tái sử dụng được ở nhiều nơi.
- Viết test đơn giản hơn rất nhiều.
- Giảm số lượng chức năng phức tạp trong ứng dụng.
🧪 Test-Driven Development (TDD)
🌟 Trình tự:
- Viết test trước (cho những chức năng chưa tồn tại).
- Các test sẽ fail ban đầu ➔ Đây là mục tiêu đúng.
- Viết code để làm cho các test pass.
🌟 Áp dụng vào ví dụ vận chuyển:
- Viết 3 test cho 3 hàm nhỏ trước.
- Code các hàm cho đến khi tất cả test pass.
🌟 Ưu điểm:
- Có test coverage hoàn chỉnh ngay từ đầu.
- Hạn chế bug tiềm ẩn.
📜 Ví dụ test đơn giản với QUnit
🌟 Hàm tính phí vận chuyển:
function calculateShipping(distance) { let shipping; if (distance < 25) { shipping = 4; } else if (distance < 100) { shipping = 5; } else if (distance < 1000) { shipping = 6; } else { shipping = 7; } return shipping; }
🌟 Test bằng QUnit:
QUnit.test('Calculate Shipping', function(assert) { assert.equal(calculateShipping(24), 4, "24 Miles"); assert.equal(calculateShipping(99), 5, "99 Miles"); assert.equal(calculateShipping(999), 6, "999 Miles"); assert.equal(calculateShipping(1000), 7, "1000 Miles"); });
🧠 Giải thích:
assert.equal(actual, expected, message)
so sánh giá trị thực tế và kỳ vọng.- Nếu khớp ➔ test pass.
- Nếu ai đó sửa nhầm hàm
calculateShipping
, test sẽ fail ngay.
🔎 Các điểm mạnh khác của QUnit
- Hỗ trợ test cả:
- Hàm đồng bộ.
- Hàm bất đồng bộ (asynchronous).
- Có thể test các tương tác giao diện như click chuột, gõ phím.
📈 Bao nhiêu test coverage là đủ?
- Không có quy tắc cứng nhắc.
- Nếu test quá nhiều ➔ Dễ làm chậm quá trình phát triển.
- Nếu test quá ít ➔ Dễ bị lỗi lọt vào production.
🌟 Gợi ý:
- Bắt đầu từ những phần đơn giản nhất.
- Sau đó mở rộng dần ra các phần phức tạp và hay lỗi trong quá khứ.
🛠️ Bắt đầu với project mới
🌟 Quy tắc tại Red Hat:
- Mỗi user story đều phải:
- Có kế hoạch dành thời gian cho viết test.
- Ví dụ: nếu coding mất 8 giờ ➔ Thêm 2 giờ dành cho viết và kiểm tra test coverage.
🌟 Lưu ý:
- Frontend Architect phải:
- Bảo vệ quyền được viết test của developer.
- Thuyết phục khách hàng hoặc quản lý về lợi ích lâu dài của testing.
Performance Testing
🎯 Mục tiêu của Performance Testing
- Bảo vệ người dùng khỏi trải nghiệm tồi tệ do website kém hiệu suất.
- Performance testing:
- Không tìm lỗi hệ thống hoặc lỗi giao diện.
- Nhưng cực kỳ quan trọng vì hiệu suất thấp cũng gây mất người dùng.
🌟 Các chỉ số đo hiệu suất website:
- Page weight (trọng lượng trang).
- Number of requests (số lượng request).
- Time to First Byte (TTFB).
- Load time (thời gian tải).
- Scrolling performance (hiệu suất cuộn trang).
🏗️ Nguyên tắc cốt lõi: Thiết lập Performance Budget
- Performance Budget = Đặt mục tiêu rõ ràng cho các chỉ số hiệu suất ➔ Kiểm tra trước mỗi lần merge hoặc deploy.
- Nếu test fail ➔ Cần:
- Điều chỉnh feature mới, hoặc
- Loại bỏ những thứ nặng nề khác.
🌟 Lưu ý tâm lý:
- Giống như quản lý tài chính: “ít hơn” không hấp dẫn.
- Nhưng chi tiêu theo ngân sách ➔ Không nợ nần, không hối tiếc ➔ Website nhanh + người dùng hài lòng.
📊 Các cách thiết lập Performance Budget
🥇 1. Competitive Baseline
- So sánh với đối thủ:
- Đo thời gian tải, page weight,… của các trang chính.
- Mục tiêu: Nhanh hơn ít nhất 20%.
- Ví dụ: Đối thủ load trang sản phẩm 3s ➔ Trang bạn phải ≤ 2.4s.
- Theo dõi định kỳ, vì đối thủ cũng không ngừng tối ưu.
🥈 2. Averaged Baseline
- So với mặt bằng chung ngành.
- Ví dụ số liệu từ HTTPArchive (tháng 4/2015):
- Page weight trung bình: 2,061 KB.
- Total requests trung bình: 99.
- Mục tiêu cá nhân (giảm 20%):
- Page weight: 1,648 KB.
- Total requests: 79.
📐 Các chỉ số cần theo dõi
🔥 Raw Metrics
🌟 Page Weight
- Website ngày càng nặng hơn:
- 2011: 769 KB ➔ 2015: 2,061 KB (tăng 168%).
- Vì sao cần giảm page weight:
- Tăng tốc độ tải.
- Tiết kiệm chi phí dữ liệu cho người dùng, đặc biệt ở các nước đang phát triển.
- Giải pháp:
- Tối ưu hình ảnh (nén PNG, giảm chất lượng JPEG, dùng
<picture>
+srcset
). - Hạn chế số lượng và kiểu chữ custom fonts.
- Dùng SVG inline thay vì icon fonts nặng.
- Hạn chế dùng JS frameworks, jQuery plugins nếu không cần thiết.
- Dùng minify và gzip để giảm kích thước file CSS/JS.
- Tối ưu hình ảnh (nén PNG, giảm chất lượng JPEG, dùng
🌟 Number of HTTP Requests
- Vấn đề:
- Browser giới hạn số lượng request song song.
- Nhiều file nhỏ ➔ nhiều round trips ➔ tải chậm.
- Giải pháp:
- Combine CSS/JS vào file lớn hơn.
- Combine ảnh vào image sprite.
- Lazy-load assets không cần thiết ngay từ đầu.
- Dùng CDN để chia server ➔ Tăng số lượng request cùng lúc.
🕰️ Timing Metrics
⏳ Time to First Byte (TTFB)
- Thời gian từ lúc gửi request đến khi nhận được byte đầu tiên.
- Không phải chỉ số hiệu suất tổng thể, nhưng nên theo dõi.
🖌️ Time to Start Render
- Thời gian bắt đầu vẽ giao diện cho người dùng.
- Giải pháp:
- Deferred JS/CSS.
- Inline critical CSS.
- Lazy load ảnh dưới viewport.
🏁 Time to Document Complete
- Khi tất cả tài nguyên ban đầu được tải xong.
- Không tính những file lazy-loaded sau.
🧮 Hybrid Metrics
🌟 PageSpeed Score
- Công cụ Google PageSpeed:
- Chấm điểm /100.
- Gợi ý tối ưu: chặn render-blocking JS/CSS, tối ưu hình ảnh, cache, v.v.
🌟 Speed Index
- Đo trung bình thời gian các phần visible của trang được hiển thị.
- Là chỉ số mô phỏng sát nhất với trải nghiệm thực tế người dùng.
🛠️ Các công cụ tự động hóa Performance Testing
🚀 Grunt PageSpeed
- Plugin Grunt để chạy Google PageSpeed tự động trước mỗi merge/build.
🌟 Cài đặt:
npm install grunt-pagespeed --save-dev
🌟 Gruntfile.js:
grunt.loadNpmTasks('grunt-pagespeed'); pagespeed: { options: { nokey: true, url: "http://redhat.com" }, desktop: { options: { strategy: "desktop", threshold: 80 } }, mobile: { options: { strategy: "mobile", threshold: 80 } } }
🚀 Grunt Perfbudget
- Plugin Grunt sử dụng WebPageTest API.
- Test mô phỏng các kết nối và địa điểm khác nhau.
🌟 Cài đặt:
npm install grunt-perfbudget --save-dev
🌟 Gruntfile.js:
grunt.loadNpmTasks('grunt-perfbudget'); perfbudget: { default: { options: { url: 'http://www.redhat.com/en', key: 'YOUR_WEBPAGETEST_API_KEY', budget: { visualComplete: '4000', // ms SpeedIndex: '1500' // ms } } } }
🏆 Kết luận
- Performance Testing + Performance Budget:
- Bảo vệ website khỏi việc tụt hiệu suất ngầm.
- Giúp phát triển feature mới mà không hy sinh trải nghiệm người dùng.
Visual Regression Testing
🎯 Vấn đề thực tế: Vòng lặp lỗi giao diện
- Bạn làm việc rất cẩn thận để hoàn thiện form liên hệ theo đúng thiết kế Photoshop.
- Code đã được ký duyệt, merge an toàn, và bạn chuyển sang task khác.
- Nhưng vài tuần sau, bất ngờ:
- Một ticket mới xuất hiện: “Form có lỗi!”
- Một QA hoặc Designer nào đó so sánh với phiên bản PSD mới và phát hiện khác biệt.
🔔 Lý do có thể:
- Ai đó vô tình sửa class chung mà bạn dùng cho form.
- Thiết kế PSD không đồng bộ (file này khác file kia).
- Decision Maker thay đổi yêu cầu mà không ghi nhận đó là thay đổi, lại ghi là bug.
🕵️ Các nguyên nhân phổ biến
👩💻 Unknowing Developers
- Người khác vô tình sửa class dùng chung, ảnh hưởng đến form cũ của bạn.
🎨 Inconsistent Designs
- Các file PSD không đồng bộ ➔ Mỗi người QA hoặc Designer dùng 1 phiên bản khác nhau để so sánh.
🧠 Waffling Decision Makers
- Quy luật xác suất vô hạn: Càng nhiều tính năng, càng nhiều người duyệt ➔ chắc chắn sẽ có thay đổi.
- Không phân biệt giữa change request và defect ➔ Tốn thời gian vô ích.
🛡️ Giải pháp: Visual Regression Testing
🌟 Visual Regression Testing giúp:
- Chụp ảnh giao diện đã được duyệt (baseline).
- So sánh ảnh với phiên bản mới ➔ Xác định khác biệt pixel.
🌟 Lợi ích:
- Có bằng chứng rõ ràng: nếu baseline không thay đổi, lỗi thuộc về file PSD.
- Phân biệt rõ bug thực sự và change request ngẫu hứng.
📸 Các dạng Visual Regression Testing
🧱 Page-based Diffing
- Ví dụ: Wraith
- Cách hoạt động:
- So sánh toàn bộ trang web giữa 2 môi trường (live vs staging).
- Phù hợp: Khi không kỳ vọng có sự khác biệt.
📦 Component-based Diffing
- Ví dụ: BackstopJS
- Cách hoạt động:
- Chụp và so sánh từng phần tử nhỏ (selectors) thay vì toàn trang.
- Ưu điểm: Tránh false positive khi nội dung khác làm dịch bố cục.
🎯 CSS Unit Testing
- Ví dụ: Quixote
- Cách hoạt động:
- Kiểm tra giá trị CSS (font-size, margin, v.v.) thay vì hình ảnh.
- Ưu điểm: Rất mạnh khi kiểm soát branding, bố cục chuẩn xác.
🖥️ Headless Browser Driven
- Ví dụ: Gemini + PhantomJS
- Cách hoạt động:
- Sử dụng trình duyệt không giao diện để tải và chụp ảnh website.
- Ưu điểm: Nhanh, nhất quán, phù hợp automation.
🖥️ Desktop Browser Driven
- Ví dụ: Gemini + Selenium
- Cách hoạt động:
- Chạy tests trên trình duyệt thật (Chrome, Firefox, v.v.).
- Ưu điểm: Bắt được các lỗi mà chỉ xuất hiện trên trình duyệt cụ thể.
🛠️ Includes Scripting Libraries
- Ví dụ: CasperJS
- Cách hoạt động:
- Tương tác như người dùng: hover, click, fill form rồi chụp ảnh.
- Ưu điểm: Test được các luồng động và dữ liệu thay đổi.
🖼️ GUI-based Comparison & Approval
- Ví dụ: Diffux
- Cách hoạt động:
- Có giao diện web để xem kết quả và duyệt/reject thay đổi hình ảnh.
- Ưu điểm: Cho phép người không kỹ thuật tham gia kiểm tra.
💻 Command-line Comparison & Approval
- Ví dụ: PhantomCSS
- Cách hoạt động:
- Chạy kiểm tra bằng lệnh terminal ➔ Kết quả pass/fail ngay trong terminal.
- Ưu điểm: Tích hợp dễ dàng vào hệ thống CI/CD như Jenkins, Travis CI.
🔥 Kết luận
- Visual Regression Testing:
- Làm giảm đáng kể số lượng lỗi giao diện ngẫu nhiên.
- Bảo vệ thiết kế khỏi những thay đổi không mong muốn.
- Tiết kiệm thời gian và nâng cao uy tín khi đối mặt với QA và stakeholders.
Để lại một bình luận
Bạn phải đăng nhập để gửi bình luận.