iT邦幫忙

2024 iThome 鐵人賽

0

Flutter 無疑的是一個高效率的跨平台解決方案。桌面、行動裝置的應用程式都可以使用它建置創新的軟體服務。在這個時間點,如果您剛要學習應用程式開發或者有跨平台的需求,Flutter 確實是值得推薦的方案之一。

隨著我們逐漸熟悉 Flutter ,學習最佳實踐有助於後續我們專案的實作。

程式碼

清晰整潔的程式碼結構可以讓我們的專案維持一致性、增加可維護性,也可以避免冗余的重複甚至增加程式的複雜度。

命名是第一件常常被小看的問題,一些常見的建議:

  • 類別、Enum、使用 PascalCase 命名
  • 變數、參數、方法、屬性使用 camelCase 風格命名
  • 檔名使用 snake_case 風格

變數和函數名應該描述性強,能清楚表達其用途。避免過短的名稱(如單個字母),除非在非常簡短的作用域內。使用工具或 IDE 的格式化功能來保持一致性。註解應該用來解釋為什麼以某種方式撰寫該程式碼,而不是重述程式碼執行的內容。移除任何未使用的程式碼。

這個部分跟大多數語言或框架並沒有太多的不同。

目錄結構

為您的專案設計一個合適的目錄結構也是一個重要步驟。它非常直觀的影響到可維護性和協作。雖然 Flutter 並沒有強制性的規範,但我們借鑒社群流行的結構不止可以學習大家共識的好方法,在協作時也比較容易了解。社群主流的方式概略有 2 種:

  1. 依照類型分類:這是最常見的方式。目錄和檔案根據功能或類型進行分類,例如所有「頁面畫面」都放在 screens 目錄下,資料模型在 models 等。

    lib/
    ├── screens/
    ├── widgets/
    ├── services/
    ├── view_models/
    └── ...
    
  2. 依照功能分類:這種方式適合大型項目,目錄根據功能進行組織。每個功能都有自己的目錄

    lib/
    ├── feature_1/
    │   ├── screens/
    │   ├── widgets/
    │   ├── models/
    │   ├── services/
    │   └── view_models/
    ├── feature_2/
    │   ├── screens/
    │   ├── widgets/
    │   ├── models/
    │   ├── services/
    │   └── view_models/
    └── ...
    

    對於那些希望採用「依照功能」組織的開發者,社群甚至還有指令工具 - feature_folder_cli

模組化

另外,對於那些可能要跨專案重複使用的程式碼,可以擷取函式庫並發佈到 pub.dev。若您覺得多一層這樣的處理開發不太方便也可以:

lib/
└── packages/
    ├── my_pkg/
    │   ├── lib/
    │   └── pubspec.yaml

有效運用組件 Widget

Flutter 應用程式開發的重要原則之一,就是要懂得靈活運用 Flutter 組件。這些組件是用來建構使用者介面、功能和外觀的關鍵。要開發出一個效能優異的應用,熟悉如何運用這些組件是非常重要的。「有效運用」指的是:

  • 挑選適合的組件來實現特定功能。
  • 正確地組合和堆疊組件。
  • 避免不必要的重新渲染(這點在 React Native 也是相同的)。
  • 善用 Flutter 提供的效能優化,例如 const 建構子。
  • 正確使用 StatelessWidget 和 StatefulWidget,以及合理管理狀態。

另外還有一些實作上的建議:

  • 組件適當的分拆,單一責任。
  • 處理長內容列表時,使用 ListView.builder
  • 盡可能使用 Stateless 組件
  • 使用 key ,對於不會被重新渲染或重新排序的組件使用 Key(UniqueKey().toString()),對於可能重建的組件使用ValueKey(items[index].id),

狀態管理

狀態管理的選擇和使用也能協助我們減少 Bug 、提升效能。我們前面已經介紹過了目前主流的套件。

一般來說,簡單的應用程式選擇 Provider 這樣簡單的技術;而比較大型複雜的應用則應該選擇 Redux、BLoC、Riverpod 等等當然這完全取決於個人。

Riverpod 的發展迅速,對於新的專案,特別是中大型專案,Riverpod 確實是一個好的選擇,但相比於一些更成熟的解決方案,其生態系和社群支持可能還不夠廣泛。

除了套件的選擇,通用的狀態管理最佳實踐如將「狀態」儲存在最低需要使用的階層,避免效能和傳遞問題。

效能

優化應用程式效能是開發過程中重要的環節,一些建議如:

  • 選擇輕量級的動畫,避免過度大量自定義動畫。
  • Pre-caching 一些頻繁存取的指令。針對圖片可以評估使用 cached_network_image 除了網路讀取的圖片。
  • 使用 Lazy Loading 延遲下載,例如一些還不需要在畫面呈現的圖片可以延後載入。
  • 網頁的話使用 Code Splitting。
  • 使用 Dart Observatory 分析效能
  • 使用 RepaintBoundary 處理經常會重新渲染的組件
  • 使用 ValueNotifier 和 ValueListenableBuilder ;對於簡單的狀態管理,可以使用 ValueNotifier 和 ValueListenableBuilder 避免不必要的重新渲染。
  • 使用適當大小的圖片,考慮使用 WebP 格式。對於 Android,可以使用 R8 編譯器來自動壓縮 PNG 文件。
  • 使用 FutureBuilder 和 StreamBuilder 可以幫助我們更有效地處理非同步操作。
  • 對於非常耗時的操作,可以使用 Isolates 在後台線程中執行。

測試和除錯

如果可以,儘早開始測試。Flutter 提供了完整的測試工具包含我們之前介紹的單元測試等等,其他還有 Mockito、flame_test、或 Flutter Deive 都可以協助進行測試。

對於端對端測試或許您可以選擇 Appium - 跨平台 E2E 自動化測試工具除了平台支援 iOS、Android、Windows、macOS、網頁、React Native、tvOS 等等,撰寫語言支援 Java、Python、JavaScript、C#、Ruby

其他小技巧

  • Flutter 3.24 引入了新的 Flutter GPU 若您有進階 3D 圖像處理可以嘗試。

  • 儘量使用 Widget 而不是方法 Method。使用 Widget 可以獲得完整生命週期的好處,避免不必要的重新構建。

  • 盡可能使用 const 關鍵字

  • 使用 if 替代三元表示式

    Column(
      children: [
        Text("平台"),
        if (Platform.isAndroid) Text("安卓"),
        if (Platform.isIOS) Text("蘋果"),
      ]
    );
    
  • 使用展開運算子,當資料已經儲存在另一個集合時:

    // 建議
    var x = [1, 2, 3];
    var y = [4, 5, ...x];
    
    // 避免
    var x = [1, 2, 3];
    var y = [4, 5, 6];
    x.addAll(y);
    
  • 使用級聯運算子 .. ,若要對一個物件進行一系列操作:

    var path = Path()
      ..lineTo(0, size.height)
      ..lineTo(size.width, size.height)
      ..lineTo(size.width, 0)
      ..close();
    
  • 優先使用 is ,而不是 as。如果無法強制轉換,則 as 會發生例外。

    // 建議
    if (item is User) {}
    
    // 避免
    (item as User).name = 'Andy';
    
  • 考慮優先使用 SizedBox 替代 Container 組件

  • 使用 Null 安全運算子:???.,避免過長的 null 檢查。

    // 建議
    z = x ?? y;
    
    // 避免
    z = x == null ? y : x;
    

    總結

這裡單純儘量羅列一些建議,當然其中有些描述可能還需要進一步深入學習其知識。無論如何,這篇文章希望能讓我們在開發的時儘量優化我們的應用程式。


上一篇
Flutter 藍芽通訊使用 flutter_blue_plus
下一篇
Rive - 動畫解決方案新選擇
系列文
Flutter 開發實戰 - 30 天逃離新手村33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言