Mục lục

Perceived Performance: Hack não người dùng với Optimistic UI

Tăng tốc độ cảm nhận (không phải tốc độ thật) bằng kỹ thuật Skeleton Loading và Optimistic UI như Facebook/Twitter.

Người dùng không quan tâm Server của bạn trả về trong 100ms hay 500ms. Họ chỉ quan tâm: "Bấm nút xong có thấy phản hồi ngay không?".

Hiệu năng cảm nhận (Perceived Performance) quan trọng hơn hiệu năng thực tế (Actual Performance).

1. Skeleton Loading: Nghệ thuật chờ đợi

Tại sao YouTube, Facebook, LinkedIn đều dùng Skeleton (khung xương xám) thay vì Spinner (vòng tròn quay)?

  • Tâm lý học: Skeleton cho thấy cấu trúc nội dung, tạo cảm giác tiến độ (Progress). Spinner tạo cảm giác tắc nghẽn (Block).
  • CLS: Skeleton chiếm sẵn không gian, ngăn chặn layout shift khi nội dung thật hiện ra.

2. Optimistic UI (Giao diện Lạc quan)

Đây là kỹ thuật phân biệt App "thường" và App "xịn" (như Instagram, iMessage).

Nguyên lý: Giao diện cập nhật trạng thái thành công NGAY LẬP TỨC khi người dùng hành động, trước cả khi server phản hồi.

  • Bấm Like -> Tim đỏ ngay lập tức.
  • Gửi tin nhắn -> Tin nhắn hiện lên khung chat ngay lập tức.

Triển khai với React Query (onMutate)

tsx:
// 1. User bấm Send
onMutate: async (newMessage) => {
  // Update Cache UI ngay lập tức (Giả vờ thành công)
  queryClient.setQueryData(['chat'], old => [...old, newMessage]);
  return { previousData }; // Lưu lại để rollback nếu lỗi
},
// 2. Server trả về lỗi?
onError: (err, newMsg, context) => {
  // Hoàn tác UI về cũ
  queryClient.setQueryData(['chat'], context.previousData);
}

Case Study: Nút "Like" Twitter

Khi bạn bấm Like một tweet:

  1. UI chuyển icon tim sang màu đỏ + animation nổ pháo hoa.
  2. Request API gửi đi ngầm (background).
  3. Nếu API chậm 3s? Bạn không hề biết. Bạn đã lướt qua tweet khác rồi. Trải nghiệm là Instant (Tức thì).

3. Streaming SSR (Next.js Suspense)

Đừng bắt người dùng nhìn màn hình trắng xóa chỉ vì một component Reviews dươí chân trang đang load chậm.

Sử dụng Streaming:

  • Gửi HTML Header/Navbar về ngay lập tức (TTFB thấp).
  • Hiển thị nội dung chính.
  • Load chậm phần Reviews sau cùng (bọc trong Suspense).

Tạo cảm giác trang web tải xong rất nhanh, dù thực tế JS vẫn đang chạy.

Kết luận

Hãy tối ưu cho Con người, không phải cho Máy móc. Một ứng dụng phản hồi trong 10ms (Optimistic) nhưng chạy ngầm 1s vẫn tốt hơn một ứng dụng buộc người dùng đợi 0.5s với cái Spinner quay tròn.

Quảng cáo
mdhorizontal