Ionic 개발자가 저지르는 가장 흔한 9가지 실수
게시 됨: 2022-03-11소개
Ionic은 이제 2년이 되었습니다. AngularJS를 기반으로 하는 하이브리드 애플리케이션을 개발하기 위한 훌륭한 도구 세트입니다. Ionic은 현재 백만 개 이상의 애플리케이션이 구축되고 수천 명의 개발자 커뮤니티가 성장하면서 매우 인기가 있습니다.
Ionic의 첫 번째 릴리스 이후 시간이 흘렀고 웹 기술과 모범 사례는 다양한 방식으로 발전했습니다. 따라서 새로운 프로젝트를 시작할 때 어떤 경로를 따라야 할지 결정하기 어렵습니다. 이러한 조건에서 개발자는 응용 프로그램 품질이나 팀 생산성에 잠재적으로 영향을 미치는 실수를 할 수 있습니다.
다음의 일반적인 실수를 읽으면 근본적인 문제를 피하고 Ionic을 사용하여 성능이 뛰어나고 확장 가능한 응용 프로그램을 만드는 열쇠를 갖게 될 것입니다.
일반적인 실수 #1: 네이티브 스크롤링 활성화를 잊음
네이티브 스크롤링 을 통해 Ionic은 지원되는 웹뷰에서 스크롤링 이벤트를 수신할 수 있습니다. 브라우저에 적절한 스크롤 이벤트가 없었을 때 생성된 JavaScript 스크롤 없이도 Pull to Refresh , List Reordering 및 Infinite Scroll 이 가능합니다.
기본 스크롤은 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”>
불행히도 애플리케이션이 방대한 항목 목록을 표시할 수 있도록 하는 컬렉션 반복은 기본 스크롤로 처리할 수 없습니다.
일반적인 실수 #2: Ionic CLI를 사용하여 플랫폼 및 플러그인을 설치하지 않음
Ionic CLI는 Cordova CLI에 기능을 추가합니다. 플랫폼 및 플러그인 지속성은 Ionic CLI가 추가하는 훌륭한 기능입니다.
Cordova CLI의 문제는 설치하는 플랫폼과 플러그인이 컴퓨터에만 설치된다는 것입니다. 팀에서 작업할 때 버그를 피하기 위해 동일한 환경, 플랫폼 및 플러그인을 공유하고 싶습니다. Cordova CLI를 사용하면 개발자 시스템 간에 프로젝트를 동기화 상태로 유지하기가 더 어렵습니다. 예, 플랫폼 및 플러그인 폴더를 커밋할 수 있지만 권장하지 않습니다.
Ionic CLI를 사용하여 플랫폼 ionic platform add ios
및 플러그인 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 앱으로 9백만 이상의 사용자 기반, 7백만 이상의 다운로드 및 Google Play에서 평균 4.5개의 별을 보유하고 있습니다.
AngularJS를 최대한 활용하려면 프로젝트를 시작하기 전에 배워야 할 몇 가지 사항이 있습니다.
$시계
감시자는 AngularJS의 범위 변경을 수신하는 데 사용됩니다. $watch
에는 기본적으로 $watch (normal)
, $watch (deep)
, $watchCollection
및 $watchGroup
의 네 가지 유형이 있습니다.
그것들은 모두 다르며 올바른 것을 선택하면 성능 면에서 큰 차이를 만들 수 있습니다.
$watch(일반)
일반 $watch
를 사용하면 기존 개체 속성이나 배열 항목만 확인합니다. Object 속성을 추가하거나 새 항목을 Array에 푸시하는 것과 같은 얕은 변경은 처리되지 않습니다.
$scope.$watch('watchExpression', function(newVal, oldVal){ if(newVal){ // watchExpression has changed. } });
$watch(깊이)
deep $watch
는 Nested Object 속성과 같은 얕은 변경과 깊은 변경을 처리합니다. 이 $watch
를 사용하면 수정 사항을 놓치지 않을 것입니다. 그러나 deep $watch
를 사용하면 성능에 영향을 미칩니다. 주의해서 사용하는 것이 좋습니다.
$scope.$watch('watchExpression', function(newVal, oldVal){ if(newVal){ // watchExpression has changed. } }, true);
$watchCollection
$watchCollection
은 일반 $watch
와 deep $watch
사이에서 고려될 수 있습니다. 또한 개체 참조를 비교하는 데도 작동하지만 개체 속성을 추가하거나 새 항목을 배열에 푸시하여 개체의 속성을 얕은 관찰할 수 있다는 이점이 있습니다.
$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을 사용하면 기본적으로 10개의 페이지가 캐시되며 이는 전역적으로 또는 플랫폼별로 변경할 수 있습니다.
// 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용 횡단 보도에 대해 알지 못함
모든 Android 버전은 다른 WebView(애플리케이션을 실행하는 브라우저)를 실행합니다. 성능은 기기마다 다르며 오래된 Android 기기에서는 정말 나쁠 수 있습니다. 모든 Android 기기에서 동일한 유동성과 반응성을 경험하기 위해 Crosswalk를 설치할 수 있습니다. 기본적으로 최신 Chromium 브라우저를 애플리케이션에 포함하며 ARM과 X86 모두 APK당 약 20Mb를 추가합니다.
Crosswalk는 Ionic CLI 또는 Cordova CLI를 사용하여 간단히 설치할 수 있습니다.
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 및 유일한 웹 기술(JavaScript, HTML 및 CSS)을 사용하여 이제 브라우저 및 데스크탑(Windows, Linux 및 OSX)용 Ionic 애플리케이션을 구축할 수 있습니다.
Github에서 스타터 키트를 사용할 수 있습니다.
Cordova 브라우저 플랫폼
브라우저 플랫폼을 사용하여 브라우저용 Cordova 애플리케이션을 작성할 수 있습니다. 이는 브라우저에서도 Cordova의 플러그인을 사용할 수 있음을 의미합니다.
iOS 또는 Android 플랫폼을 설치하는 것과 동일한 방식으로 설치할 수 있습니다.
cordova platform add browser
iOS 또는 Android에서와 똑같이 사용하기 전에 애플리케이션을 컴파일해야 합니다.
cordova run browser
이 명령은 앱을 컴파일하고 기본 브라우저를 엽니다.
크로스 플랫폼 플러그인
네트워크, 카메라 및 Facebook과 같은 많은 플러그인이 동일한 API로 iOS, Android 및 브라우저 플랫폼을 동시에 지원합니다.
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
이를 Folder-by-Type 구조라고 하며 JavaScript, CSS 및 HTML 파일을 유형별로 그룹화합니다. 초보자에게는 쉬워 보일 수 있지만 이러한 종류의 아키텍처는 꽤 빨리 손에서 벗어날 수 있습니다. 단순히 확장되지 않습니다.
다음은 Folder-by-Type 구조를 사용하지 않는 몇 가지 이유입니다.
- 폴더의 파일 수가 방대해질 수 있습니다.
- 특정 기능에 대해 수정해야 하는 모든 파일을 찾는 것은 까다로울 수 있습니다.
- 기능에 대한 작업은 많은 열린 폴더로 이어집니다.
- 확장성이 좋지 않을수록 앱이 커질수록 작업이 더 어려워집니다.
JavaScript, CSS 및 HTML 파일이 기능 또는 AngularJS 모듈별로 그룹화되는 Folders-by-Feature 구조를 사용하는 것이 좋습니다.
myNewFeature/ index.js (AngularJS module) config.js service.js controller.js index.html style.scss
기능별 폴더 구조를 사용하는 이유:
- 폴더의 파일 수는 몇 개로 제한됩니다.
- 특정 기능에 대해 수정해야 하는 모든 파일을 쉽게 찾을 수 있습니다. 동일한 폴더에 있습니다.
- 기능에 대해 독립적으로 작업할 수 있습니다.
- 모듈이 무엇을 나타내는지 아는 것은 쉽습니다. 폴더 이름이면 충분합니다.
- 새로운 기능을 쉽게 생성하고 기존 기능을 복사/붙여넣기만 하면 됩니다.
- 확장이 잘 되므로 팀에서 작업을 어렵게 만들지 않고 원하는 만큼 새로운 기능을 추가할 수 있습니다.
이 아키텍처는 현재 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();
위의 코드는 사용자가 요소의 맨 위로 스크롤했는지 확인하는 매우 간단한 예입니다. 예제를 사용하려는 경우 브라우저 간 호환성을 위해 공급업체별 대안을 추가해야 합니다. 기본적으로 브라우저에 따라 최적의 속도로 60FPS 또는 화면 재생 빈도로 실행됩니다. 하지만 최적화되어 있고 고성능 애니메이션 프레임워크는 이 간단한 방법을 활용합니다.
HTML 노드의 크기와 위치에 대한 정보를 제공하는 element.getBoundingClientRect()
를 살펴볼 수도 있습니다.
일반적인 실수 #9: 수동으로 Ionic 애플리케이션 프로토타이핑
Ionic에는 거의 시각적 언어인 특정 디자인이 있습니다. 특히 프로토타입 및 초기 단계 제품의 경우 사용 가능한 구성 요소 및 스타일을 활용하여 많은 시간과 비용을 절약할 수 있습니다. 그것들은 실제로 다소 미미하고 좋은 미학을 가지고 있습니다.
기본 기능을 갖춘 와이어프레임 및 모형을 제공하는 것이 업계 표준이 되었습니다. 모바일 장치에서 사진을 보는 것과 동적 구성 요소가 있는 실제 앱을 보는 것은 매우 다른 두 잔의 차입니다. 많은 디자이너와 UX 개발자는 Axure 또는 Balsamiq와 같은 도구를 사용하여 최소한의 기능으로 와이어프레임을 빠르게 만들 수 있습니다.
이제 Ionic의 제작자는 Ionic 개발자 전용으로 만들어진 유사한 도구를 출시했습니다. 아이오닉 크리에이터라고 합니다. 드래그 앤 드롭 웹 인터페이스가 있으며 핵심 Ionic이 제공하는 거의 모든 것을 지원합니다. 이것의 좋은 점은 프로토타입을 표준 작동하는 Ionic 코드를 사용하여 여러 형식으로 내보내고 응용 프로그램을 빌드하고 공유할 수 있다는 것입니다. 이 도구는 독점적이지만 많은 옵션을 무료로 사용할 수 있습니다.
결론
Ionic은 누구도 상상할 수 없는 방식으로 하이브리드 애플리케이션 산업에 혁명을 일으켰습니다. 그러나 시간이 지남에 따라 모범 사례와 도구는 발전하지 못했습니다. 결과적으로 개발자가 범할 수 있는 잠재적인 실수의 수가 증가했습니다.
전문 Ionic 개발자는 세계적인 수준의 애플리케이션을 여러 플랫폼에 동시에 제공할 수 있는 명확한 방법을 가지고 있습니다. 방법은 사용 가능한 도구를 활용하고 성능을 최우선 순위로 유지하며 모범 사례를 따르는 것입니다.
이 게시물은 놀라운 Ionic 커뮤니티, Michal Mikolajczyk, Mike Hartington(Ionic Core 팀) 및 Katie Ginder-Vogel(마케팅 및 커뮤니케이션 관리자, Ionic)이 없었다면 불가능했을 것입니다. 모두 대단히 감사합니다.