0
0
Lập trình
NM

Tối ưu hóa trải nghiệm người dùng trong React với Render lạc quan

Đăng vào 7 tháng trước

• 6 phút đọc

Tối ưu hóa trải nghiệm người dùng trong React với Render lạc quan

Giới thiệu

Trong phát triển ứng dụng web, một trong những thách thức lớn nhất là đảm bảo rằng người dùng không cảm thấy bị chậm trễ khi tương tác với giao diện. Nhiều ứng dụng hiện nay yêu cầu người dùng chờ đợi phản hồi từ máy chủ trước khi cập nhật giao diện, điều này có thể dẫn đến cảm giác chậm chạp và không mượt mà. Bài viết này sẽ khám phá cách sử dụng React để tạo ra trải nghiệm người dùng mượt mà hơn thông qua việc sử dụng phương pháp Render lạc quan và các kỹ thuật tối ưu hóa khác.

Vấn đề

Nhiều giao diện người dùng hiện nay phải chờ đợi phản hồi từ máy chủ trước khi có thể hiển thị những thay đổi, khiến cho người dùng thường xuyên phải nhìn vào những biểu tượng chờ (spinners) và cảm thấy ứng dụng đang bị lag, ngay cả với những hành động chắc chắn như thích (likes), chuyển đổi (toggles), hoặc bình luận (comments). Việc render mọi cập nhật như là khẩn cấp sẽ chặn các tương tác trên các cây DOM lớn hoặc trên các thiết bị chậm, tạo ra cảm giác giật lag (visible jank).

Giải pháp

Sử dụng Render lạc quan

Để cải thiện trải nghiệm này, chúng ta có thể sử dụng hook useOptimistic của React để render một trạng thái dự đoán ngay lập tức (ví dụ: hiển thị một thông báo “Đang gửi…”) trong khi hành động bất đồng bộ đang chạy ở nền. Để đảm bảo rằng việc cập nhật không khẩn cấp vẫn giữ được phản hồi, hãy bọc việc commit cuối cùng trong startTransition để không chặn các tương tác ưu tiên cao hơn.

Mã mẫu

javascript Copy
import { useState, useOptimistic, startTransition, useRef } from 'react';

// Hành động mô phỏng gửi đến máy chủ
async function sendMessageToServer(text) {
  await new Promise((r) => setTimeout(r, 800));
  return { id: crypto.randomUUID(), text };
}

export default function Chat() {
  const formRef = useRef(null);
  const [messages, setMessages] = useState([]);

  // Kết hợp tin nhắn lạc quan ở trên cùng trong khi đang chờ
  const [optimisticMessages, addOptimisticMessage] = useOptimistic(
    messages,
    (current, optimistic) => [
      { ...optimistic, pending: true },
      ...current,
    ]
  );

  async function onSubmit(formData) {
    const text = String(formData.get('text') || '').trim();
    if (!text) return;

    const tempId = `temp-${Date.now()}`;

    // 1) Hiển thị ngay lập tức
    addOptimisticMessage({ id: tempId, text });
    formRef.current?.reset();

    try {
      // 2) Cập nhật trong một transition
      startTransition(async () => {
        const saved = await sendMessageToServer(text);
        setMessages((prev) => [
          { id: saved.id, text: saved.text },
          ...prev.filter(m => m.id !== tempId),
        ]);
      });
    } catch {
      // 3) Khôi phục khi có lỗi
      startTransition(() => {
        setMessages((prev) => prev.filter(m => m.id !== tempId));
      });
      // Tùy chọn kích hoạt một thông báo hoặc trạng thái lỗi ở đây
    }
  }

  return (
    <div>
      <form ref={formRef} action={(fd) => onSubmit(fd)}>
        <input name="text" placeholder="Viết một tin nhắn..." />
        <button type="submit">Gửi</button>
      </form>

      <ul>
        {optimisticMessages.map((m) => (
          <li key={m.id}>
            {m.text} {m.pending ? <em style={{ color: '#888' }}> (Đang gửi...)</em> : null}
          </li>
        ))}
      </ul>
    </div>
  );
}

Khi nào nên sử dụng

  • Các hành động có tỉ lệ thành công cao và có thể đảo ngược: tin nhắn, thích, chuyển đổi, sắp xếp lại, bình luận.
  • Tránh sử dụng cho các thao tác phá hủy hoặc có rủi ro cao trừ khi có sự xác nhận và hoàn tác rõ ràng.

Những điều cần lưu ý

  • startTransition được sử dụng để ưu tiên; useTransition cung cấp isPending nếu một chỉ báo đang chờ là cần thiết.
  • Sau một cuộc gọi với await, hãy bọc các lệnh setState tiếp theo trong startTransition để giữ cho nó không khẩn cấp.
  • Giữ các input được kiểm soát bên ngoài transitions và đảm bảo rằng các hành động từ máy chủ là idempotent hoặc không bị lặp lại để đảm bảo việc thử lại an toàn.

Mẹo hiệu suất

  • Giảm thiểu số lượng render: Sử dụng memoization hoặc các kỹ thuật tối ưu hóa khác để giảm thiểu số lần render không cần thiết.
  • Sử dụng lazy loading: Chỉ tải các thành phần và dữ liệu khi cần thiết để cải thiện thời gian tải ban đầu của ứng dụng.
  • Tránh rendering quá nhiều: Đảm bảo rằng bạn không render quá nhiều thành phần trong một lần để tránh giật lag.

Các trường hợp thực tế

Ví dụ 1: Gửi tin nhắn trong ứng dụng chat

Trong một ứng dụng chat, việc sử dụng Render lạc quan để hiển thị tin nhắn ngay lập tức giúp người dùng cảm thấy rằng họ đang giao tiếp hiệu quả và không phải chờ đợi. Điều này không chỉ cải thiện trải nghiệm người dùng mà còn tăng cường khả năng giữ chân người dùng.

Ví dụ 2: Thích và bình luận

Sử dụng Render lạc quan cho các hành động như thích và bình luận cũng có thể giúp cải thiện sự tương tác của người dùng. Khi người dùng nhấn nút thích, nếu ứng dụng có thể hiển thị ngay lập tức rằng họ đã thích bài viết mà không phải chờ phản hồi từ máy chủ, người dùng sẽ cảm thấy thoải mái hơn khi sử dụng ứng dụng.

Kết luận

Việc tối ưu hóa trải nghiệm người dùng trong ứng dụng React không chỉ giúp tăng cường sự hài lòng của người dùng mà còn làm tăng tính tương tác và giữ chân người dùng. Bằng cách sử dụng Render lạc quan và các kỹ thuật quản lý trạng thái hiệu quả, bạn có thể tạo ra một giao diện người dùng mượt mà và cảm giác như tức thì mà không làm giảm độ chính xác của dữ liệu. Hãy thử áp dụng những chiến lược này vào ứng dụng của bạn ngay hôm nay để xem sự khác biệt!

Câu hỏi thường gặp (FAQ)

1. Render lạc quan là gì?

Render lạc quan là một kỹ thuật hiển thị trạng thái dự đoán ngay lập tức khi người dùng thực hiện hành động, thay vì chờ đợi phản hồi từ máy chủ.

2. Khi nào nên sử dụng startTransition?

startTransition nên được sử dụng khi bạn muốn ưu tiên các cập nhật trạng thái không khẩn cấp mà không làm chậm các tương tác ưu tiên cao hơn.

3. Có những lưu ý gì khi sử dụng Render lạc quan?

Bạn cần đảm bảo rằng các hành động từ máy chủ là idempotent và khôi phục trạng thái một cách an toàn trong trường hợp có lỗi.

4. Làm thế nào để tối ưu hóa hiệu suất trong React?

Sử dụng memoization, lazy loading và giảm số lượng render không cần thiết là những cách hiệu quả để tối ưu hóa hiệu suất trong React.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào