規劃效能
使用者會期望其應用程式保持回應性,並可自在地使用,而不會耗盡電池。 在技術上來說,效能是非功能的需求,但是將效能視為功能可協助您滿足使用者的期望。 指定目標和測量是主要因素。 決定您的效能關鍵案例是什麼;定義良好效能代表什麼意義。 然後在整個專案週期中及早並經常進行測量,以確保您能夠達成目標。
指定目標
使用者體驗是定義良好效能的基本方式。 應用程式的啟動時間可能影響使用者對其效能的看法。 使用者可能會認為啟動時間少於一秒的應用程式是效能出色,5 秒內是效能良好,超過 5 秒則是效能不佳。
其他指標對使用者體驗的影響較不明顯,例如記憶體。 應用程式在暫停或非使用中時遭終止的可能性會隨使用中應用程式使用的記憶體量增加而提高。 一般規則是,高記憶體使用量會降低系統上所有應用程式的體驗,因此合理作法是設定記憶體消耗目標。 考慮使用者所感受到的應用程式的粗略大小:小、中或大。 對效能的期望與這種感知相互關聯。 例如,您可能希望一個不使用大量媒體的小型應用程式耗用少於 100 MB 的記憶體。
最好設定初始目標,然後再加以修改,而不是設定完目標就好。 您的應用程式效能目標應該是特定且可測量的,而且應該分成三個類別:使用者或應用程式完成工作所需的時間 (時間);應用程式為了回應使用者互動而重新繪製本身的速率和持續性 (流暢性);以及應用程式如何節省系統資源,包括電池電力 (效率)。
Time
想想使用者在應用程式中完成工作所需經過時間的可接受範圍 (互動類別)。 針對每個互動類別,指派標籤、感知的使用者情感,以及理想和最大持續時間。 以下是一些建議。
Interaction 類別標籤 | 使用者感知 | 理想 | 最大值 | 範例 |
---|---|---|---|---|
快速 | 可感受到的最小延遲 | 100 毫秒 | 200 毫秒 | 顯示應用程式列;按下按鈕 (第一個回應) |
一般 | 迅速,但不是飛快 | 300 毫秒 | 500 毫秒 | 調整大小;語意式縮放 |
回應性 | 不快,但感覺有回應 | 500 毫秒 | 1 秒 | 瀏覽至不同的頁面;從暫停狀態繼續應用程式 |
啟動 | 競爭體驗 | 1 秒 | 3 秒 | 第一次啟動應用程式,或先終止應用程式之後再啟動 |
連續 | 不再感覺有回應 | 500 毫秒 | 5 秒鐘 | 從網際網路下載檔案 |
停滯 | 長;使用者可能切換離開 | 500 毫秒 | 10 秒 | 從市集安裝多個應用程式 |
您現在可以將互動類別指派給應用程式的效能案例。 您可以將應用程式的時間點參考、部分使用者體驗,以及互動類別指派給每個案例。 以下是一些美食應用程式範例的建議。
案例 | 時間點 | 使用者體驗 | Interaction 類別 |
---|---|---|---|
瀏覽至食譜頁面 | 第一個回應 | 頁面轉換動畫已啟動 | 快速 (100 - 200 毫秒) |
回應性 | 載入成分清單;沒有影像 | 有回應 (500 毫秒 - 1 秒) | |
可見完成 | 載入所有內容;顯示影像 | 連續 (500 毫秒 - 5 秒) | |
搜尋食譜 | 第一個回應 | 按下 [重新整理] 按鈕 | 快速 (100 - 200 毫秒) |
可見完成 | 顯示當地食譜標題清單 | 一般 (300 - 500 毫秒) |
如果您要顯示即時內容,則也應考慮內容新鮮度目標。 目標是要每隔幾秒鐘重新整理內容嗎? 或者,每隔幾分鐘、每隔幾小時,甚至每天重新整理一次內容算是可接受的使用者體驗嗎?
指定目標之後,您現在可以更清楚地測試、分析和最佳化您的應用程式。
流動性
您的應用程式專屬的可測量流動性目標可能包括:
- 沒有螢幕重繪停止和啟動 (故障)。
- 動畫每秒轉譯 60 個畫面 (FPS)。
- 當使用者瀏覽/捲動時,應用程式每秒會顯示 3-6 頁的內容。
效率
您的應用程式專屬的可測量效率目標可能包括:
- 針對應用程式的程序,CPU 百分比位於或低於 N,且記憶體使用量 (MB) 一直位於或低於 M。
- 當應用程式處於非使用中狀態時,您的應用程式程序的 N 和 M 為零。
- 您的應用程式可以靠電池電源使用 X 個小時;當應用程式處於非使用中狀態時,裝置會保留 Y 個小時的電量。
設計應用程式的效能
您現在可以使用效能目標來影響應用程式的設計。 使用美食應用程式範例,在使用者瀏覽至食譜頁面之後,您可以選擇增量更新項目,先轉譯食譜的名稱,延遲顯示成分,再更進一步延遲顯示影像。 這樣可以在移動瀏覽/捲動時保持回應能力和流暢的 UI,並在互動減慢到允許 UI 執行緒跟上的速度後進行完全精確度轉譯。 以下是需要考慮的一些其他層面。
UI
- 最佳化您的 XAML 標記,將應用程式 UI 的每個頁面 (特別是初始頁面) 的剖析和載入時間與記憶體效率最大化。 簡而言之,延遲載入 UI 和程式碼,直到需要為止。
- 針對 ListView 和 GridView,請讓所有項目為相同大小,並盡可能使用 ListView 和 GridView 最佳化技術。
- 以標記形式宣告 UI,架構可以在區塊中載入並重複使用,而不是在程式碼中以命令方式建構。
- 延遲建立 UI 元素直到使用者需要時。 請參閱 x:Load 屬性。
- 偏好主題轉換和動畫至分鏡腳本的動畫。 如需詳細資訊,請參閱動畫概觀。 請記住,分鏡腳本動畫需要持續更新畫面,並讓 CPU 和圖形管線保持使用中。 若要保留電力,如果使用者未與應用程式互動,則不會執行動畫。
- 您應該使用 getThumbnailAsync 方法,以適合您呈現其檢視的大小載入您載入的影像。
CPU、記憶體與電源
- 排程低優先順序的工作,以在較低優先順序的執行緒和/或核心上執行。 請參閱非同步程式設計、Dispatcher 屬性,以及 CoreDispatcher 類別。
- 藉由在暫停時釋放昂貴的資源 (例如媒體),將應用程式的記憶體使用量降到最低。
- 將程式碼的工作集最小化。
- 盡可能取消註冊事件處理常式和取值 UI 元素,以避免記憶體流失。
- 為了電力,請節約處理資料輪詢、查詢感應器,或在閒置時排程 CPU 上工作的頻率。
資料存取
- 盡可能預先擷取內容。 如需自動預先擷取,請參閱 ContentPrefetcher 類別。 如需手動預先擷取,請參閱 Windows.ApplicationModel.Background 命名空間和 MaintenanceTrigger 類別。
- 盡可能快取存取成本高昂的內容。 請參閱 localFolder 和 LocalSettings 屬性。
- 針對快取遺漏,請儘快顯示預留位置 UI,以表示應用程式仍在載入內容。 以不妨礙使用者的方式,從預留位置轉換為即時內容。 例如,當應用程式載入即時內容時,請勿變更使用者手指或滑鼠指標下的內容位置。
應用程式啟動及繼續
- 延遲應用程式的啟動顯示畫面,除非必要,否則不要擴充應用程式的啟動顯示畫面。 如需詳細資訊,請參閱建立快速流暢的應用程式啟動體驗和顯示啟動顯示畫面以取得更多時間。
- 停用在啟動顯示畫面關閉後立即發生的動畫,因為這些動畫只會造成應用程式啟動時間延遲的感知。
調適型 UI 與方向
- 使用 VisualStateManager 類別。
- 僅立即完成必要的工作,延遲密集的應用程式工作 — 您的應用程式有 200 到 800 毫秒的時間完成工作,使用者才會看到應用程式 UI 處於裁切狀態。
有了與效能相關的設計,您就可以開始撰寫應用程式程式碼。
效能檢測
當您撰寫程式碼時,新增程式碼,以在應用程式執行時在特定點記錄訊息和事件。 稍後,當您測試應用程式時,您可以使用 Windows Performance Recorder 和 Windows Performance Analyzer 等分析工具 (這兩者都包含在 Windows Performance Toolkit 中) 來建立和檢視應用程式效能的相關報告。 在此報告中,您可以尋找這些訊息和事件,協助您更輕鬆地分析報表的結果。
通用 Windows 平台 (UWP) 提供記錄 API,由 Windows 事件追蹤 (ETW) 支援,同時提供豐富的事件記錄和追蹤解決方案。 屬於 Windows.Foundation.Diagnostics 命名空間的 API 包括 FileLoggingSession、LoggingActivity、LoggingChannel,和 LoggingSession 類別。
若要在應用程式執行時在特定時間點記錄報告中的訊息,請建立 LoggingChannel 物件,然後呼叫物件的 LogMessage 方法,如下所示。
// using Windows.Foundation.Diagnostics;
// ...
LoggingChannel myLoggingChannel = new LoggingChannel("MyLoggingChannel");
myLoggingChannel.LogMessage(LoggingLevel.Information, "Here' s my logged message.");
// ...
若要將應用程式執行期間內一段時間的啟動和停止事件記錄到報告中,請建立 LoggingActivity 物件,然後呼叫物件的 LoggingActivity 建構函式,如下所示。
// using Windows.Foundation.Diagnostics;
// ...
LoggingActivity myLoggingActivity;
// myLoggingChannel is defined and initialized in the previous code example.
using (myLoggingActivity = new LoggingActivity("MyLoggingActivity"), myLoggingChannel))
{ // After this logging activity starts, a start event is logged.
// Add code here to do something of interest.
} // After this logging activity ends, an end event is logged.
// ...
另請參閱記錄範例。
透過檢測您的應用程式,您可以測試及測量應用程式的效能。
測試及測量效能目標
效能計劃的一部分是定義開發過程中測量效能的點。 這會根據您在原型設計、開發或部署期間測量的方式,提供不同的用途。 在原型設計的初期階段測量效能可能非常有價值,因此我們建議您在程式碼執行有意義的工作時立即測量。 早期測量可讓您了解應用程式中的重要成本出處,為設計決策提供資訊。 這會使應用程式具有高效能且可擴充。 晚期變更設計的成本通常比早期變更要高。 在產品週期後期測量效能,可能會導致最後一刻的駭客攻擊和效能不佳等問題。
請使用這些技術和工具來測試您的應用程式堆疊針對原始效能目標的表現。
- 針對各種不同的硬體組態進行測試,包括多合一電腦和桌上型電腦、筆記型電腦、Ultrabook,以及平板電腦與其他行動裝置。
- 針對各種不同的螢幕大小進行測試。 雖然較寬的螢幕大小可以顯示更多內容,但導入所有這些額外內容可能會對效能造成負面影響。
- 盡可能減少測試變數。
- 關閉測試裝置上的背景應用程式。 若要這樣做,請在 Windows 中,從 [開始] 功能表選取 [設定]>[個人化]>[鎖定畫面]。 選取每個使用中的應用程式,然後選取 [無]。
- 先在發行組態中建構應用程式,將其編譯為機器碼,之後再將應用程式部署至測試裝置。
- 為了確保自動維護不會影響測試裝置的效能,請手動觸發維護,並等候維護完成。 在 Windows 中,在 [開始] 功能表中搜尋 [安全性和維護]。 在 [維護] 區域中,於 [自動維護]下,選取 [啟動維護],並等候狀態結束 [維護進行中]。
- 多次執行應用程式,以協助消除隨機測試變數,並協助確保一致的測量。
- 測試降低電源的可用性。 使用者裝置的電力可能比您的開發電腦少得多。 Windows 設計時已將行動裝置等低功率裝置納入考量。 在平台上執行的應用程式應確保其在這些裝置上執行良好。 作為啟發,可期待低功率裝置的執行速度約為桌上型電腦速度的四分之一,並據此設定您的目標。
- 使用 Microsoft Visual Studio 和 Windows Performance Analyzer 等工具的組合來測量應用程式效能。 Visual Studio 的設計目的是要提供以應用程式為主的分析,例如原始程式碼連結。 Windows Performance Analyzer 的設計目的是提供以系統為中心的分析,例如提供系統資訊、觸控操作事件的相關資訊,以及磁碟輸入/輸出 (I/O) 和圖形處理器 (GPU) 成本的相關資訊。 這兩個工具都提供追蹤擷取和匯出,而且可以重新開啟共用和事後檢討追蹤。
- 將應用程式提交到市集進行認證之前,請務必將與效能相關的測試案例加入您的測試計劃中,如 Windows 應用程式認證套件測試的<效能測試>一節,以及 UWP 應用程式測試案例 \(英文\) 的<效能和穩定性>一節中所述。
如需詳細資訊,請參閱這些資源和分析工具。
- Windows Performance Analyzer
- Windows 效能工具組
- 使用 Visual Studio 診斷工具分析效能 \(部分機器翻譯\)
- //build/ session XAML 效能
- //build/ session Visual Studio 2015 中新的 XAML 工具
效能測試結果的回應
分析效能測試結果之後,請判斷是否需要任何變更,例如:
- 應該變更任何應用程式設計決策,或最佳化您的程式碼嗎?
- 應該在程式碼中新增、移除或變更任何檢測嗎?
- 應該修改任何效能目標嗎?
如果需要任何變更,請進行變更,然後返回檢測或測試並重複。
最佳化
只最佳化應用程式中的效能關鍵程式碼路徑:花費最多時間的程式碼路徑。 程式碼剖析會告訴您是哪些路徑。 通常,需要在建立遵循良好設計作法的軟體,以及撰寫以最高最佳化方式執行的程式碼之間取捨。 針對不需要顧慮效能的領域,通常最好將開發人員生產力和良好的軟體設計排為優先。