Các phương pháp hay nhất để duy trì trạng thái ứng dụng bằng IndexedDB

Tìm hiểu các phương pháp hay nhất để đồng bộ hoá trạng thái ứng dụng giữa IndexedDB và các thư viện quản lý trạng thái phổ biến.

Khi người dùng tải một trang web hoặc ứng dụng lần đầu tiên, thường có một lượng lớn công việc liên quan đến việc xây dựng trạng thái ứng dụng ban đầu dùng để hiển thị giao diện người dùng. Ví dụ: đôi khi, ứng dụng cần xác thực người dùng ở phía máy khách, sau đó thực hiện một số yêu cầu API trước khi có tất cả dữ liệu cần thiết để hiển thị trên trang.

Việc lưu trữ trạng thái ứng dụng trong IndexedDB có thể là một cách hiệu quả để tăng tốc thời gian tải cho các lượt truy cập lặp lại. Sau đó, ứng dụng có thể đồng bộ hoá với bất kỳ dịch vụ API nào ở chế độ nền và cập nhật từng phần dữ liệu mới cho giao diện người dùng, sử dụng chiến lược đã lỗi thời trong khi xác thực lại.

Tuy nhiên, khi sử dụng IndexedDB, có nhiều điều quan trọng cần xem xét có thể không rõ ràng ngay lập tức với các nhà phát triển mới sử dụng API. Tài liệu này trả lời các câu hỏi thường gặp và thảo luận một số điều quan trọng nhất cần lưu ý khi duy trì trạng thái của ứng dụng trong IndexedDB.

Giúp ứng dụng của bạn dễ dự đoán

Rất nhiều sự phức tạp xung quanh IndexedDB xuất phát từ thực tế là có rất nhiều yếu tố mà bạn (nhà phát triển) không kiểm soát được. Phần này tìm hiểu nhiều vấn đề mà bạn phải lưu ý khi làm việc với IndexedDB.

Có thể không ghi được vào bộ nhớ

Lỗi khi ghi vào IndexedDB có thể xảy ra vì nhiều lý do và trong một số trường hợp, những lý do này nằm ngoài tầm kiểm soát với tư cách là nhà phát triển. Ví dụ: một số trình duyệt không cho phép ghi vào IndexedDB khi ở chế độ duyệt web riêng tư. Ngoài ra, cũng có khả năng người dùng đang sử dụng một thiết bị gần hết dung lượng ổ đĩa và trình duyệt sẽ hạn chế bạn lưu trữ bất kỳ nội dung nào.

Do đó, điều quan trọng là bạn phải luôn triển khai tính năng xử lý lỗi thích hợp trong mã IndexedDB. Điều này cũng có nghĩa là bạn nên giữ trạng thái của ứng dụng trong bộ nhớ (ngoài việc lưu trữ) để giao diện người dùng không bị hỏng khi chạy ở chế độ duyệt web riêng tư hoặc khi không có dung lượng lưu trữ (ngay cả khi một số tính năng khác của ứng dụng cần có bộ nhớ sẽ không hoạt động).

Dữ liệu được lưu trữ có thể đã bị người dùng sửa đổi hoặc xoá

Không giống như các cơ sở dữ liệu phía máy chủ là nơi bạn có thể hạn chế quyền truy cập trái phép, các tiện ích của trình duyệt và công cụ cho nhà phát triển có thể truy cập vào cơ sở dữ liệu phía máy khách. Ngoài ra, người dùng có thể xoá các cơ sở dữ liệu này.

Mặc dù người dùng có thể không sửa đổi dữ liệu được lưu trữ trên máy, nhưng việc xoá dữ liệu đó là khá phổ biến. Điều quan trọng là ứng dụng của bạn phải có thể xử lý cả hai trường hợp này mà không gặp lỗi.

Dữ liệu được lưu trữ có thể đã lỗi thời

Tương tự như phần trước, ngay cả khi người dùng chưa tự sửa đổi dữ liệu, thì cũng có thể dữ liệu họ có trong bộ nhớ được ghi bởi một phiên bản mã cũ hơn, có thể là một phiên bản có lỗi.

IndexedDB tích hợp sẵn tính năng hỗ trợ cho các phiên bản giản đồ và nâng cấp bằng phương thức IDBOpenDBRequest.onupgradeneeded(); tuy nhiên, bạn vẫn cần viết mã nâng cấp theo cách để có thể xử lý người dùng đến từ phiên bản trước (bao gồm cả phiên bản có lỗi).

Phương pháp kiểm thử đơn vị có thể rất hữu ích trong trường hợp này, vì thường bạn không thể kiểm thử thủ công tất cả các trường hợp và đường dẫn nâng cấp có thể có.

Duy trì hiệu suất của ứng dụng

Một trong những tính năng chính của IndexedDB là API không đồng bộ, nhưng đừng để điều đó đánh lừa bạn nghĩ rằng mình không cần lo lắng về hiệu suất khi sử dụng API này. Trong một số trường hợp, việc sử dụng không đúng cách vẫn có thể chặn luồng chính, từ đó dẫn đến phản hồi.

Theo nguyên tắc chung, các hoạt động đọc và ghi vào IndexedDB không được lớn hơn mức cần thiết đối với dữ liệu đang được truy cập.

Mặc dù IndexedDB cho phép lưu trữ các đối tượng lớn, lồng nhau dưới dạng một bản ghi duy nhất (và việc này được thừa nhận là khá thuận tiện từ góc độ nhà phát triển), nhưng bạn nên tránh thực hiện phương pháp này. Lý do là vì khi IndexedDB lưu trữ một đối tượng, trước tiên, đối tượng đó phải tạo một bản sao có cấu trúc của đối tượng đó và quá trình sao chép có cấu trúc diễn ra trên luồng chính. Đối tượng càng lớn thì thời gian chặn càng lâu.

Điều này gây ra một số thách thức khi lập kế hoạch cách duy trì trạng thái ứng dụng vào IndexedDB, vì hầu hết các thư viện quản lý trạng thái phổ biến (như Redux) hoạt động bằng cách quản lý toàn bộ cây trạng thái của bạn dưới dạng một đối tượng JavaScript duy nhất.

Mặc dù việc quản lý trạng thái theo cách này có nhiều lợi ích. Tuy nhiên, mặc dù việc lưu trữ toàn bộ cây trạng thái dưới dạng một bản ghi duy nhất trong IndexedDB có thể lại hấp dẫn và thuận tiện, nhưng việc thực hiện việc này sau mỗi thay đổi (ngay cả khi được điều tiết/bị trả về) sẽ dẫn đến việc chặn không cần thiết đối với luồng chính, điều này sẽ làm tăng khả năng lỗi ghi và trong một số trường hợp, điều này thậm chí sẽ khiến thẻ trình duyệt gặp sự cố hoặc bị trả về.

Thay vì lưu trữ toàn bộ cây trạng thái trong một bản ghi, bạn nên chia cây trạng thái thành các bản ghi riêng lẻ và chỉ cập nhật các bản ghi thực sự thay đổi.

Giống như hầu hết các phương pháp hay nhất, đây không phải là quy tắc tất cả hoặc không. Trong trường hợp không thể chia nhỏ một đối tượng trạng thái và chỉ ghi tập hợp thay đổi tối thiểu, bạn vẫn nên chia nhỏ dữ liệu thành các cây con và chỉ ghi các cây con đó thay vì luôn ghi toàn bộ cây trạng thái. Một chút cải tiến vẫn tốt hơn là không có cải tiến.

Cuối cùng, bạn phải luôn đo lường mức tác động đến hiệu suất của mã bạn viết. Mặc dù đúng là việc ghi nhỏ vào IndexedDB sẽ hoạt động tốt hơn ghi lớn, nhưng điều này chỉ quan trọng nếu việc ghi vào IndexedDB mà ứng dụng của bạn đang thực hiện thực sự dẫn đến các tác vụ dài chặn luồng chính và làm giảm trải nghiệm người dùng. Bạn cần đo lường để hiểu rõ mục tiêu tối ưu hoá của mình.

Kết luận

Các nhà phát triển có thể sử dụng các cơ chế lưu trữ ứng dụng như IndexedDB để cải thiện trải nghiệm người dùng của ứng dụng bằng cách không chỉ duy trì trạng thái qua các phiên mà còn giảm thời gian tải trạng thái ban đầu trong các lượt truy cập lặp lại.

Mặc dù việc sử dụng IndexedDB đúng cách có thể cải thiện đáng kể trải nghiệm người dùng, nhưng việc sử dụng không đúng cách hoặc không xử lý được các trường hợp lỗi có thể dẫn đến ứng dụng bị hỏng và người dùng không hài lòng.

Vì bộ nhớ của ứng dụng liên quan đến nhiều yếu tố nằm ngoài tầm kiểm soát của bạn, nên điều quan trọng là mã của bạn phải được kiểm thử kỹ và xử lý lỗi đúng cách, ngay cả những lỗi mà ban đầu có vẻ như không xảy ra.