Ionic 開發人員最常犯的 9 個錯誤
已發表: 2022-03-11介紹
Ionic 已經存在兩年了。 它是一套很棒的工具,用於開發基於 AngularJS 的混合應用程序。 目前,Ionic 非常受歡迎,構建了超過一百萬個應用程序,並且由數千名開發人員組成的社區不斷壯大。
自從 Ionic 的第一個版本發布以來,時間已經過去了,Web 技術和最佳實踐已經在許多方面發生了變化。 因此,在開始一個新項目時,很難確定要走哪條路。 在這些情況下,開發人員可能會犯錯誤,這可能會影響其應用程序的質量或團隊的生產力。
通過閱讀以下常見錯誤,您將掌握避免基本問題並使用 Ionic 創建高性能和可擴展應用程序的關鍵。
常見錯誤 #1:忘記啟用原生滾動
Native Scrolling允許 Ionic 監聽支持的 webviews 上的滾動事件。 它使Pull to Refresh 、 List Reordering和Infinite Scroll在沒有 JavaScript 滾動的情況下成為可能,而 JavaScript 滾動是在瀏覽器缺乏適當的滾動事件時創建的。
自 Ionic 1.2(2015 年 12 月)起,Android 上默認啟用原生滾動。 這是一個巨大的性能和用戶體驗改進,因為它確保了異步事件的平滑滾動。
不幸的是,由於 iOS 上缺乏適當的事件,該平台尚未啟用本機滾動。
如果您使用的是 1.2 之前的版本,則可以使用$ionicConfigProvider為 Android 啟用本機滾動:
// Enable Native Scrolling on Android $ionicConfigProvider.platform.android.scrolling.jsScrolling(false); 您還可以使用任何ion-content上的overflow-scroll指令在任何頁面上啟用或禁用本機滾動:
<!-- Disable Native Scrolling on this page only --> <ion-content overflow-scroll=”false”>請注意,很遺憾,collection-repeat 允許您的應用程序顯示大量項目列表,但本機滾動無法覆蓋。
常見錯誤 #2:不使用 Ionic CLI 安裝平台和插件
Ionic CLI 為 Cordova CLI 添加了功能。 平台和插件持久性是 Ionic CLI 添加的一項很棒的功能。
Cordova CLI 的問題在於您安裝的平台和插件僅安裝在您的計算機上。 在團隊工作時,為了避免錯誤,您希望共享相同的環境、平台和插件。 使用 Cordova CLI,使項目在開發人員機器之間保持同步變得更加困難。 是的,您可以提交平台和插件文件夾,但不建議這樣做。
使用 Ionic CLI 安裝平台ionic platform add ios和 plugins ionic plugin add camera時,適當編輯package.json文件。
平台和插件存儲在cordovaPlatforms和cordovaPlugins屬性中:
"cordovaPlugins": [ "[email protected]", "[email protected]", "[email protected]" ], "cordovaPlatforms": [ "android", "ios" ] 現在,其他開發人員在拉取新代碼時很容易保持同步,只需在必要時(添加、刪除或版本更新)運行ionic state restore 。
常見錯誤#3:思維表現開箱即用
Ionic 基於 AngularJS,設備上的性能經常受到質疑。 在這一點上,我想向您保證:只要有一點 AngularJS 背景,您就可以使用 Ionic 創建世界級的應用程序。
完美的例子是使用 Ionic 構建的 Sworkit 應用程序,用戶群超過 900 萬,下載量超過 700 萬,在 Google Play 上平均獲得 4.5 顆星。
如果您想充分利用 AngularJS,那麼在開始您的項目之前,您應該了解以下幾點。
$手錶
觀察者習慣於監聽 AngularJS 中的作用域變化。 $watch基本上有四種類型: $watch (normal) 、 $watch (deep) 、 $watchCollection和$watchGroup 。
它們中的每一個都是不同的,選擇正確的可以在性能方面產生巨大的差異。
$手錶(正常)
使用普通的$watch只會檢查現有的 Object 屬性或 Array 項。 將不會處理諸如添加 Object 屬性或將新項目推送到 Array 等淺層更改。
$scope.$watch('watchExpression', function(newVal, oldVal){ if(newVal){ // watchExpression has changed. } });$watch(深度)
deep $watch負責處理淺層變化和深層變化,例如嵌套對象屬性。 有了這款$watch ,您一定不會錯過任何修改。 但是,使用深度$watch會影響性能。 我建議謹慎使用它。
$scope.$watch('watchExpression', function(newVal, oldVal){ if(newVal){ // watchExpression has changed. } }, true);$watchCollection
$watchCollection可以考慮介於普通$watch和深度$watch之間。 它也適用於比較對象引用,但優點是還可以通過添加 Object 屬性或將新項目推入 Array 來淺層監視對象的屬性。
$scope.$watchCollection('watchExpression', function(newVal, oldVal){ if(newVal){ // watchExpression has changed. } });$watchGroup
在 AngularJS 1.3 中引入的$watchGroup允許同時查看多個表達式。
雖然$watchGroup與普通的$watch相比可能不會提高您的應用程序性能,但它的優勢是在查看多個範圍表達式時更加綜合。
$scope.$watchGroup([ 'watchExpression', 'watchExpression2', 'watchExpression3' ], function(newVals, oldVals) { if (newVals[0]) { // watchExpression has changed. } if (newVals[1]) { // watchExpression2 has changed. } if (newVals[2]) { // watchExpression3 has changed. } });追踪
track by用於避免在使用ng-repeat時進行無用的 DOM 操作。 實際上,如果摘要循環發現您的集合中至少有一個元素發生了變化,那麼ng-repeat將重新渲染所有元素。 DOM 操作總是會對應用程序性能產生影響,所以越少越好。
為避免重新渲染整個集合併僅更新需要更新的元素,請使用帶有唯一標識符的track by 。
<!-- if items have a unique id --> <div ng-repeat="item in items track by item.id"></div> <!-- if not, you can use the $index that ng-repeat adds to every of its items --> <div ng-repeat="user in users track by $index"></div> 只是避免在collection-repeat上使用track by 。
一次性綁定
一次性綁定或::是在 Angular 1.3 中引入的,它對您的應用程序性能產生了真正的影響。
基本上,在表達式上使用一次性綁定::將在填充時將其從$watchers列表中刪除。 這意味著即使數據發生變化,表達式也無法更新。
<p>{{::user.firstName}}</p> 我們的建議是瀏覽您的應用程序的所有視圖並考慮可以更新或不能更新的內容,並相應地使用一次性綁定:: 。 對於消化週期來說,這將是一個巨大的解脫。
請注意,很遺憾,一次性綁定不能在collection-repeat中使用,因為屏幕上顯示的項目列表會隨著滾動而改變。
如果您想了解更多有關 AngularJS 和 Ionic 性能提示和技巧的信息,我建議您閱讀 Ultimate AngularJS 和 Ionic 性能備忘單。
常見錯誤 #4:與View Cache邏輯混淆
默認情況下,單頁應用程序不緩存頁面。 您可能已經使用 AngularJS 應用程序體驗過,當您在頁面之間來回導航時,滾動或用戶輸入不會被保存。
使用 Ionic,默認緩存十頁,這可以在全局或每個平台上進行更改。
// Globally $ionicConfigProvider.views.maxCache(5); // Per platforms $ionicConfigProvider.platform.android.views.maxCache(5); $ionicConfigProvider.platform.ios.views.maxCache(5);這是一個很棒的功能,但有時初學者很難理解如何處理緩存頁面。
問題是當用戶返回到一個緩存頁面時,控制器不會再次被重新實例化,這與 AngularJS 應用程序不同,一切就像你從未離開過那個頁面一樣。
在這些情況下,您應該如何更新頁面上的數據?
介紹控制器生命週期事件
與 AngularJS 相比,Ionic 提供了許多生命週期事件:
$scope.$on('$ionicView.loaded', function(){}); $scope.$on('$ionicView.unloaded', function(){}); $scope.$on('$ionicView.enter', function(){}); $scope.$on('$ionicView.leave', function(){}); $scope.$on('$ionicView.beforeEnter', function(){}); $scope.$on('$ionicView.beforeLeave', function(){}); $scope.$on('$ionicView.afterEnter', function(){}); $scope.$on('$ionicView.afterLeave', function(){});如果您想控制視圖緩存,這些事件是必需的。
例如,第一次加載視圖時觸發$ionicView.loaded事件。 當這個視圖被緩存時,這個事件將不再被觸發,即使用戶回到它。 這通常是您用來啟動變量的事件,就像在 AngularJS 中使用$viewContentLoaded事件一樣。

如果您想在每次進入視圖時獲取數據,無論是否緩存,您可以使用$ionicView.enter事件。
通過在正確的時間使用正確的事件,您可以提高應用程序的可用性。
關於性能,使用緩存視圖只會影響 DOM 的大小。 當一個頁面被緩存時,它的所有觀察者都斷開連接,因此該頁面只是位於頁面上等待再次使用的更多 DOM 元素。
DOM 的大小對於獲得良好的用戶體驗很重要,但是緩存多達 10 個頁面似乎可以正常工作(當然,這取決於您在頁面中加載的內容)。
常見錯誤 #5:不了解 Android 的 Crosswalk
每個 Android 版本都運行不同的 WebView(運行您的應用程序的瀏覽器)。 不同設備的性能不同,在舊的 Android 設備上可能非常糟糕。 要在每台 Android 設備上獲得相同的流暢性和響應性體驗,您可以安裝 Crosswalk。 它基本上將最新的 Chromium 瀏覽器嵌入到您的應用程序中,並且每個 APK 增加了大約 20Mb,包括 ARM 和 X86。
可以使用 Ionic CLI 或 Cordova CLI 簡單地安裝 Crosswalk:
ionic plugin add cordova-plugin-crosswalk-webview常見錯誤 #6:試圖在瀏覽器中運行 Cordova 插件
大多數使用 Ionic 的開發人員都希望他們的應用程序可以在 iOS 和 Android 上運行。 添加平台ionic platform add ios android和一些插件ionic plugin add cordova-plugin-device-orientation cordova-plugin-contacts後,一個菜鳥的錯誤是認為你可以在瀏覽器中測試它們。 好吧,您可以,但前提是您安裝了正確的瀏覽器平台。 請記住,它不適用於所有插件。
Cordova 的插件旨在通過 JavaScript 與本機設備 API 進行交互。 因此,聯繫人插件或設備方向插件只能在設備上運行。
但是,您可以輕鬆地在設備上測試您的代碼,並通過您的計算機對其進行遠程調試。
Android 上的遠程調試
插入您的設備並通過運行adb devices確保您的計算機正確檢測到它(需要 Android SDK)。
通過運行ionic run android構建您的應用程序並將其安裝在您的設備上。 在設備上啟動您的應用後,通過 Chrome 開發工具(在您的計算機上) chrome://inspect/#devices打開控制台,然後檢查您的設備。
iOS 上的遠程調試
插入您的設備並確保它被您的計算機正確檢測到。 通過運行ionic run ios --device構建您的應用並將其安裝在您的設備上。
在設備上啟動您的應用程序後,通過單擊“ Develop > Your iPhone > Your app ”打開 Safari 開發工具(在您的計算機上):
在瀏覽器中運行 Cordova 插件
在瀏覽器中運行 Cordova 插件是您應該了解的高級功能。 從 Ionic 1.2 開始,瀏覽器得到官方支持,開啟了超越 iOS 和 Android 平台的跨平台應用時代。
借助 Cordova 瀏覽器平台、Electron 和唯一的 Web 技術(JavaScript、HTML 和 CSS),我們現在可以為瀏覽器和桌面(Windows、Linux 和 OSX)構建 Ionic 應用程序。
Github 上提供了一個入門工具包。
Cordova 瀏覽器平台
使用瀏覽器平台,您可以為瀏覽器創建 Cordova 應用程序。 這意味著您也可以在瀏覽器上使用 Cordova 的插件。
它可以像安裝 iOS 或 Android 平台一樣安裝:
cordova platform add browser您的應用程序需要在使用前編譯,與 iOS 或 Android 完全相同:
cordova run browser此命令將編譯您的應用程序並打開您的默認瀏覽器。
跨平台插件
網絡、相機和 Facebook 等許多插件同時支持 iOS、Android 和瀏覽器平台 - 都使用相同的 API。
為了說明有一種方法可以使用 ngCordova API 了解您的設備在每個平台(iOS、Android、瀏覽器和桌面)上是在線還是離線:
// listen for Online event $rootScope.$on('$cordovaNetwork:online', (event, connectionType) => { this.isOnline = true; }); // listen for Offline event $rootScope.$on('$cordovaNetwork:offline', (event, connectionType) => { this.isOnline = false; });考慮到這一點,您現在可以想像使用一個代碼庫創建可以在任何地方運行的產品。
常見錯誤 #7:遵循大型應用程序的入門套件架構
使用ionic start myapp命令時,會創建一個具有以下文件夾結構的啟動項目:
www/ js/ app.js controllers/ aaa.js bbb.js ccc.js services/ xxx.js yyy.js zzz.js templates/ aaa.html bbb.html ccc.html這稱為按類型分類的結構,其中 JavaScript、CSS 和 HTML 文件按類型分組。 對於初學者來說似乎很容易,這種架構很快就會失控。 它根本無法擴展。
以下是不使用 Folder-by-Type 結構的一些原因:
- 文件夾中的文件數量可能會很大
- 查找您需要為特定功能修改的所有文件可能會很棘手
- 處理一項功能將導致許多打開的文件夾
- 不能很好地擴展,應用程序增長得越多,工作就越困難
我更推薦使用 Folders-by-Feature 結構,其中 JavaScript、CSS 和 HTML 文件按功能或 AngularJS 模塊分組:
myNewFeature/ index.js (AngularJS module) config.js service.js controller.js index.html style.scss使用 Folders-by-Feature 結構的原因:
- 文件夾中的文件數量限制為少數
- 查找您需要為特定功能修改的所有文件很容易 - 它們位於同一個文件夾中
- 您可以獨立處理功能
- 知道模塊代表什麼很容易 - 文件夾名稱就足夠了
- 輕鬆創建新功能,只需複制/粘貼現有功能
- 擴展性好,您可以根據需要添加任意數量的新功能,而不會讓您的團隊難以工作
請注意,這種架構接近於現在 Angular2/Ionic2 應用程序中默認的 Folders-by-Component 結構。
常見錯誤 #8:將事件綁定到onscroll ,而忘記了requestAnimationFrame
這個單一的陷阱通常是初學者的錯誤,但它可能對性能產生最嚴重的影響。 考慮一下:
<ion-content on-scroll="getScrollPosition()"> // … </ion-content> $scope.getScrollPosition = function () { // heavy processing, like manipulating DOM // or anything that triggers a $digest() // will be called every ~80ms, // and will impact UX }儘管 Ionic 為這些操作提供了節流,但它仍然可能非常慢。 基本上,任何觸發摘要循環的東西都應該被推遲,而不是與重繪一起觸發,這也是滾動的效果。
開發人員一直試圖通過綁定到滾動事件(尤其是動畫)來實現的許多目標也可以使用不同的方法來實現。 看requestAnimationFrame 。
var myElement = document.getElementById('content'); var elemOffsetFromParent = myElement.offsetTop; function onCapturedFrame() { if (window.scrollY >= elemOffsetFromParent) { customTweenFunction(myElement, options); } window.requestAnimationFrame(onCapturedFrame); } onCapturedFrame();上面的代碼是一個非常簡單的例子,檢查用戶是否滾動到元素的頂部。 如果您打算使用該示例,請記住添加特定於供應商的替代方案以實現跨瀏覽器兼容性。 它基本上會以最佳速度運行,具體取決於瀏覽器、60 FPS 或屏幕刷新率。 但它是經過優化的,高性能動畫框架使用了這種簡單的方法。
您可能還想查看element.getBoundingClientRect() ,它提供有關 HTML 節點大小和位置的信息。
常見錯誤 #9:手動設計離子應用程序原型
Ionic 有一個特定的設計,幾乎是一種視覺語言。 特別是對於原型和早期產品,利用可用的組件和样式可以節省大量時間和費用。 它們實際上相當小,並且具有良好的美感。
呈現具有基本功能的線框和模型已成為行業標準。 在移動設備上查看圖片和查看帶有動態組件的實際應用程序是兩種截然不同的茶。 許多設計師和 UX 開發人員使用 Axure 或 Balsamiq 等工具,它們可以快速製作功能最少的線框。
現在,Ionic 的創建者發布了一個專門為 Ionic 開發人員製作的類似工具。 它被稱為離子創造者。 它有一個拖放 Web 界面,並支持幾乎所有核心 Ionic 提供的東西。 它的優點在於它允許將原型導出為多種格式,使用標準的工作 Ionic 代碼,甚至構建應用程序並共享它。 該工具是專有的,但許多選項可以免費使用。
結論
Ionic 以一種沒人能想像的方式徹底改變了混合應用行業。 然而,隨著時間的推移,最佳實踐和工具缺乏演變。 結果,開發人員可能犯的潛在錯誤的數量增加了。
專業的 Ionic 開發人員有一種清晰的方法可以同時向多個平台交付世界級的應用程序。 方法是利用可用的工具,將性能作為重中之重,並遵循最佳實踐。
如果沒有令人驚嘆的 Ionic 社區 Michal Mikolajczyk、Mike Hartington(Ionic Core 團隊)和 Katie Ginder-Vogel(Ionic 營銷與傳播經理)的創造力,這篇文章是不可能完成的。 非常感謝大家。
