Ứng dụng bóng đá của tôi đã hoạt động hoàn hảo cho đến khi ngày thi đấu bắt đầu

Việc xây dựng một ứng dụng bóng đá ban đầu có vẻ rất dễ dàng.

Tôi dự định sẽ lấy dữ liệu các trận đấu, hiển thị các đội, hiển thị tỉ số và làm mới sau mỗi vài giây. Mọi thứ đều hoạt động tốt trong quá trình thử nghiệm. Tôi chỉ sử dụng hai tab và một vài trận đấu mẫu. Mọi thứ trông đều ổn.

Thế rồi, ngày thi đấu bận rộn đầu tiên cũng đến.

Hàng trăm người dùng cùng lúc mở ứng dụng. Các yêu cầu (requests) bị chồng chéo lên nhau. Một số tỉ số có vẻ như bị nhảy ngược lại. Ứng dụng đã tải cùng một dữ liệu một cách riêng biệt cho từng khách truy cập.

Tôi nhận ra rằng một ứng dụng thực tế (live app) không chỉ đơn thuần là một trang web kết nối với một API. Nó là một hệ thống đồng bộ hóa dữ liệu.

Dưới đây là những sai lầm tôi đã mắc phải và cách tôi khắc phục chúng:

  • Tránh việc chỉ sử dụng polling ở phía client (client-side only polling) Phiên bản đầu tiên của tôi khiến mọi trình duyệt đều gửi yêu cầu lấy dữ liệu sau mỗi năm giây. 1 người dùng = 12 yêu cầu mỗi phút. 1.000 người dùng = 12.000 yêu cầu mỗi phút. Hầu hết các yêu cầu đều hỏi cùng một dữ liệu chính xác như nhau.

  • Sử dụng các yêu cầu ở phía server (server-side requests) Tôi đã chuyển các lệnh gọi API sang phía server. Điều này giúp bạn kiểm soát được: • Thông tin xác thực API (API credentials) • Bộ nhớ đệm (Caching) • Giới hạn tốc độ (Rate limiting) • Xử lý lỗi (Error handling) • Định dạng phản hồi (Response formatting)

Đừng bao giờ sử dụng các khóa (keys) trong mã nguồn phía client. Việc này rất không an toàn và sẽ rất tốn kém nếu ai đó đánh cắp được khóa của bạn.

  • Tạo một lớp ánh xạ (mapping layer) Tôi đã ngừng việc truyền dữ liệu API thô trực tiếp vào các component của mình. Nếu nhà cung cấp thay đổi tên một trường dữ liệu, giao diện (UI) của tôi sẽ bị lỗi. Giờ đây, tôi ánh xạ dữ liệu từ nhà cung cấp sang định dạng nội bộ của riêng mình trước. Điều này giúp giao diện của tôi luôn ổn định.

  • Sử dụng Server Components để tăng tốc độ Thay vì hiển thị màn hình chờ (loading screen), tôi tải các trận đấu ban đầu ngay trên server. Người dùng có thể thấy nội dung ngay lập tức.

  • Triển khai polling thông minh Ứng dụng không nên làm mới nếu không có trận đấu nào đang diễn ra. Tôi đã thêm một bước kiểm tra để dừng polling khi các trận đấu kết thúc. Điều này giúp tiết kiệm một lượng lớn tài nguyên máy chủ.

  • Khắc phục tình trạng tranh chấp (race conditions) Đôi khi Yêu cầu B trả về trước Yêu cầu A. Điều này khiến tỉ số có vẻ như đang chạy ngược lại. Tôi sử dụng AbortController để hủy các yêu cầu cũ trước khi bắt đầu các yêu cầu mới.

  • Xử lý lỗi một cách mượt mà Nếu việc làm mới thất bại, đừng hiển thị một màn hình trống. Hãy giữ cho dữ liệu thành công gần nhất vẫn hiển thị. Một tỉ số cũ hơn 15 giây vẫn tốt hơn là không có tỉ số nào.

Một bản demo chỉ cần hiển thị dữ liệu. Một sản phẩm thực tế phải quản lý được bộ nhớ đệm, bảo mật và trạng thái (state).

Bạn đã từng xây dựng một ứng dụng thực tế chưa? Điều gì đã bị lỗi khi người dùng thật bắt đầu truy cập?

Nguồn: https://dev.to/mihailove123/my-football-app-worked-perfectly-until-matchday-started-3i59