Thiết kế ứng dụng ưu tiên ngoại tuyến (offline-first): ý tưởng và cách làm

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Mạng di động có thể chập chờn trong thang máy, tàu điện hay vùng sóng yếu. Ứng dụng tốt vẫn dùng được trong những lúc đó. Offline-first là cách thiết kế coi dữ liệu trên máy là nguồn chính, còn mạng chỉ là phương tiện đồng bộ khi có thể.

Offline-first nghĩa là gì?

Thay vì gọi máy chủ mỗi lần cần dữ liệu và báo lỗi khi mất mạng, ứng dụng đọc và ghi vào cơ sở dữ liệu cục bộ trước. Một cơ chế nền đồng bộ thay đổi với máy chủ khi có kết nối. Giao diện luôn phản hồi nhanh vì không phải chờ mạng.

Kiến trúc cơ bản

  1. Nguồn dữ liệu cục bộ: cơ sở dữ liệu như SQLite, Room, Core Data hoặc Isar.
  2. Nguồn dữ liệu từ xa: API của máy chủ.
  3. Repository: lớp trung gian quyết định đọc từ đâu, ghi vào đâu, khi nào đồng bộ.
  4. Giao diện: chỉ quan sát dữ liệu cục bộ, tự cập nhật khi dữ liệu đổi.

Nguyên tắc nền tảng là có một nguồn sự thật duy nhất trên máy; giao diện không đọc trực tiếp từ mạng.

Luồng đọc dữ liệu

// Ý tưởng bằng Kotlin: đọc từ cục bộ, làm mới ngầm từ mạng
class ArticleRepository(
    private val dao: ArticleDao,
    private val api: ArticleApi
) {
    fun observeArticles(): Flow<List<Article>> = dao.observeAll()

    suspend fun refresh() {
        try {
            val remote = api.getArticles()
            dao.replaceAll(remote)
        } catch (e: IOException) {
            // mất mạng: giữ nguyên dữ liệu cũ, có thể báo nhẹ nhàng
        }
    }
}

Giao diện hiển thị ngay dữ liệu đã lưu, đồng thời gọi refresh. Khi có dữ liệu mới, cơ sở dữ liệu thay đổi và giao diện tự cập nhật.

Luồng ghi dữ liệu

Khi người dùng tạo hoặc sửa nội dung lúc mất mạng, ứng dụng lưu vào máy và đánh dấu bản ghi là chưa đồng bộ, hoặc đưa thao tác vào hàng đợi. Khi có mạng, một công việc nền gửi các thay đổi lên máy chủ. Trên Android có thể dùng WorkManager, trên iOS dùng tác vụ nền phù hợp, hoặc cơ chế tương đương của framework bạn chọn.

Giải quyết xung đột

Hai thiết bị sửa cùng một bản ghi khi ngoại tuyến sẽ gây xung đột. Một số chiến lược:

  • Bản ghi cuối thắng (last write wins): đơn giản, dùng thời điểm sửa; có thể mất dữ liệu.
  • Hợp nhất theo trường: gộp thay đổi ở các trường khác nhau.
  • Hỏi người dùng: khi nội dung quan trọng.
  • Dùng số phiên bản: máy chủ từ chối bản cũ và yêu cầu đồng bộ lại.

Chọn chiến lược tùy mức quan trọng của dữ liệu. Ghi chú cá nhân có thể dùng cách đơn giản, còn tài liệu cộng tác cần cách tinh vi hơn.

Thiết kế trải nghiệm người dùng

  1. Cho biết trạng thái kết nối và trạng thái đồng bộ một cách nhẹ nhàng, ví dụ biểu tượng chờ đồng bộ.
  2. Không chặn thao tác chỉ vì mất mạng nếu có thể lưu tạm.
  3. Hiển thị thời điểm cập nhật dữ liệu lần cuối khi nội dung có thể cũ.
  4. Báo rõ những chức năng thật sự cần mạng, như thanh toán.

Phát hiện kết nối

Có thể lắng nghe trạng thái mạng của thiết bị, nhưng đừng tin tuyệt đối: thiết bị có thể báo có Wi-Fi mà thực tế không ra được Internet. Cách đáng tin hơn là thử gọi thật và xử lý lỗi, kết hợp thử lại với thời gian chờ tăng dần.

Khi nào không cần offline-first?

Ứng dụng chủ yếu dựa trên dữ liệu thời gian thực như giao dịch chứng khoán, chat trực tiếp hay trò chơi nhiều người chơi vẫn cần mạng. Bạn vẫn nên xử lý lỗi mạng đàng hoàng, nhưng đầu tư vào đồng bộ phức tạp có thể không cần thiết.

Kết luận

Offline-first làm ứng dụng nhanh hơn, ổn định hơn và đáng tin hơn. Bắt đầu bằng việc lưu bộ nhớ đệm để xem được dữ liệu cũ khi mất mạng, sau đó nâng dần lên đồng bộ hai chiều khi sản phẩm cần.

Bắt đầu nhỏ: bộ nhớ đệm trước, đồng bộ sau

Bạn không cần dựng hệ thống đồng bộ phức tạp ngay. Bước đầu hiệu quả là lưu kết quả lần tải cuối vào máy và hiển thị ngay khi mở ứng dụng, đồng thời làm mới ngầm. Người dùng thấy nội dung tức thì và vẫn xem được khi mất mạng. Khi cần cho phép chỉnh sửa ngoại tuyến, hãy thêm hàng đợi thao tác và cờ trạng thái đồng bộ cho từng bản ghi. Mỗi bước nâng cấp đều mang lại lợi ích riêng nên có thể làm dần theo nhu cầu sản phẩm.

Nếu muốn thực hành kiến trúc ứng dụng có đồng bộ dữ liệu, bạn có thể xem các khóa học tại codebem.com.

author_photo
Nguyễn Đình Cường

0 comment