跳到主要內容

本地快取

既然您已經了解如何從網路伺服器載入資料,您的 Flutter 應用程式應該會感覺更有活力。然而,即使您可以從遠端伺服器載入資料,也不代表您總是應該這樣做。有時,重新渲染先前網路請求收到的資料,而不是重複請求並讓使用者等待再次完成,會更好。這種保留應用程式資料以便在未來再次顯示的技術稱為快取,本頁將介紹如何在您的 Flutter 應用程式中處理此任務。

快取簡介

#

最基本而言,所有快取策略都相當於以下三步驟操作,以虛擬碼表示:

dart
Data? _cachedData;

Future<Data> get data async {
    // Step 1: Check whether your cache already contains the desired data
    if (_cachedData == null) {
        // Step 2: Load the data if the cache was empty
        _cachedData = await _readData();
    }
    // Step 3: Return the value in the cache
    return _cachedData!;
}

有很多有趣的方法可以變化此策略,包括快取的位置、您預先寫入值到快取(或「預熱」快取)的程度等等。

常見快取術語

#

快取有其自身的術語,其中一些術語定義和說明如下。

快取命中
當快取中已包含所需的資訊,且不需要從真實來源載入時,會說應用程式發生了快取命中。
快取未命中
當快取為空,且所需資料從真實來源載入,然後儲存到快取以供未來讀取時,會說應用程式發生了快取未命中。

快取資料的風險

#

當真實來源內的資料已變更,導致應用程式有呈現過時舊資訊的風險時,會說應用程式具有過時快取

所有快取策略都有保留過時資料的風險。不幸的是,驗證快取新鮮度的動作,通常需要與完整載入相關資料一樣長的時間才能完成。這表示大多數應用程式傾向於只有在信任資料在執行期間是新鮮且未經驗證時,才能從快取資料中獲益。

為了處理這個問題,大多數快取系統都會對任何單一快取資料設定時間限制。超過此時間限制後,在載入新資料之前,原應為快取命中的情況會被視為快取未命中。

電腦科學家之間流行的笑話是「電腦科學中最困難的兩件事是快取失效、命名事物以及差一錯誤。」 😄

儘管有這些風險,世界上幾乎每個應用程式都大量使用資料快取。本頁的其餘部分將探討在您的 Flutter 應用程式中快取資料的多種方法,但請注意,所有這些方法都可以針對您的情況進行調整或組合。

在本地記憶體中快取資料

#

最簡單且效能最高的快取策略是記憶體內快取。此策略的缺點在於,由於快取僅保留在系統記憶體中,因此除了最初快取的階段之外,不會保留任何資料。(當然,這個「缺點」也具有自動解決大多數過時快取問題的優點!)

由於它們的簡單性,記憶體內快取非常類似上述虛擬碼。也就是說,最好使用經過驗證的設計原則,例如儲存庫模式,來組織程式碼,並防止類似上述的快取檢查出現在您的程式碼庫中。

想像一個 UserRepository 類別,其也負責在記憶體中快取使用者,以避免重複的網路請求。它的實作可能如下所示:

dart
class UserRepository {
  UserRepository(this.api);
  
  final Api api;
  final Map<int, User?> _userCache = {};

  Future<User?> loadUser(int id) async {
    if (!_userCache.containsKey(id)) {
      final response = await api.get(id);
      if (response.statusCode == 200) {
        _userCache[id] = User.fromJson(response.body);
      } else {
        _userCache[id] = null;
      }
    }
    return _userCache[id];
  }
}

UserRepository 遵循多個經過驗證的設計原則,包括:

最棒的是,無論在單一階段中,使用者造訪您的 Flutter 應用程式中載入特定使用者的頁面多少次,UserRepository 類別都只會透過網路載入該資料一次

但是,您的使用者最終可能會對每次重新啟動應用程式時都必須等待資料載入感到厭煩。為此,您應該從以下提供的永久快取策略中選擇一種。

永久快取

#

在記憶體中快取資料永遠無法讓您珍貴的快取在使用者單一階段後繼續存在。為了在應用程式全新啟動時享受快取命中的效能優勢,您需要將資料快取在裝置硬碟上的某個位置。

使用 shared_preferences 快取資料

#

shared_preferences 是一個 Flutter 外掛程式,在 Flutter 的所有六個目標平台上封裝了特定於平台的鍵值儲存。儘管這些底層平台的鍵值儲存是為小型資料大小而設計的,但它們仍然適用於大多數應用程式的快取策略。如需完整指南,請參閱我們有關使用鍵值儲存的其他資源。

使用檔案系統快取資料

#

如果您的 Flutter 應用程式超出適用於 shared_preferences 的低輸送量情境,您可能可以準備探索使用裝置的檔案系統快取資料。如需更詳盡的指南,請參閱我們關於檔案系統快取的其他資源。

使用裝置端資料庫快取資料

#

本機資料快取的最終挑戰是任何使用適當資料庫來讀取和寫入資料的策略。存在多種版本,包括關聯式和非關聯式資料庫。所有方法都比簡單檔案提供顯著的效能提升,尤其是對於大型資料集。如需更詳盡的指南,請參閱以下資源:

快取圖片

#

快取影像與快取一般資料類似,但具有一體適用的解決方案。要指示您的 Flutter 應用程式使用檔案系統來儲存影像,請使用cached_network_image 套件

狀態還原

#

除了應用程式資料之外,您可能還想要保存使用者階段的其他方面,例如其導覽堆疊、捲動位置,甚至是填寫表單的部分進度。這種模式稱為「狀態還原」,並且內建於 Flutter 中。

狀態還原的工作方式是指示 Flutter 架構將資料從其元素樹同步到 Flutter 引擎,然後 Flutter 引擎會將其快取在特定於平台的儲存中以供未來階段使用。若要在 Flutter 上為 Android 和 iOS 啟用狀態還原,請參閱以下文件:

意見回饋

#

由於本網站的此部分仍在發展中,我們歡迎您的意見回饋