I've been working with ionic for a while now, and I decided to make a compilation of useful ionic hacks, tips, tricks or simply useful information from my journey, so I can have a centralized place where I can find easy and fast this useful compilation, and also share it with all the ionic developers, I hope this might be of some help for others.
I divided it into 3 categories (for now), I think this is going to be an on-going process of keeping adding ionic hacks, Every time I find something interesting I'll update this post.
Ionic hacks index
- UI/UX
- Hide Scrollbar when using Chrome
- Configure your Ionic App Config
- Making Text Selectable
- Debugging
- Remote Debug on Android and iOS
- Debugging faster on iOS & Android with -livereload
- Targeting Platforms and Operating Systems
- Target platform from url
- Practical solutions
- ngZone, include into angular cycle digest
- Declare globally window's var for plugins with no wrappers
- @ViewChild only works when the view is loaded
- Use Crosswalk for Android
- Improving Loading Times and performance of your Ionic App
- Using Custom Scripts
- Add cordova-android-support-gradle-release to resolve gradle version conflict issues (Android)
Lets get started
Hide Scrollbar when using Chrome
When debugging your ionic app, using for example ionic serve lab on Chrome, One thing that is really annoying is the visible scrollbar:
Go to app/apps.css to add the following css globally (this will hide all the scrollbars inside your application):
* ::-webkit-scrollbar { display: none; }
Configure your ionic app config
We can modify the general behavior of components through the root configuration of our app. The Config lets you configure your entire app or specific platforms. You can set the tab placement, icon mode, animations, define back button icon, and more. This is one of the most interesting ionic hacks.
@NgModule({ declarations: [ MyApp ], imports: [ BrowserModule, IonicModule.forRoot(MyApp, { backButtonText: 'Go Back', iconMode: 'ios', modalEnter: 'modal-slide-in', modalLeave: 'modal-slide-out', tabsPlacement: 'bottom', pageTransition: 'ios-transition' }, {} )], bootstrap: [IonicApp], entryComponents: [ MyApp ], providers: [] })
You could also configure these values at a component level
<ion-tabs tabsPlacement="top"> <ion-tab tabTitle="Dash" tabIcon="pulse" [root]="tabRoot"></ion-tab> </ion-tabs>
Any value can be added to config, and looked up at a later in any component.
config.set('ios', 'favoriteColor', 'green'); // from any page in your app: config.get('favoriteColor'); // 'green' when iOS
Making Text Selectable
You might have noticed that you can’t select the text inside your ionic app, which is especially challenging if you want to enable the user to be able to select text (to be able to copy/paste for example) inside of your application.
You can apply this css rule to all the application, or just to a specific element container:
body { -webkit-user-select: text; user-select: text; }
Remote Debug on Android and iOS
Android
For this you'll need to have Android Studio installed on your computer
Connect your device to the computer and make sure it is correctly detected, by running adb devices (Android SDK is required).
Build your app and install it on your device by running ionic cordova run android --device command. Once your app is launched on the device, open the Chrome browser on your computer, in a new tab's url bar type: chrome://inspect/#devices, and inspect your device.
iOS
Plug in your device and make sure it is correctly detected by your computer. Build your app and install it on your device by running ionic run ios --device.
Once your app is launched on device, open Safari dev tools (on your computer) by clicking on Develop > Your iPhone > Your app:
Debugging faster on iOS & Android with -livereload
This is very simple, when you run the command to deploy to your device, add parameter -l ionic cordova run android --device -l you can also add parameter -c to display console logs in your command prompt:
--livereload, -l Spin up server to live-reload www files
--consolelogs, -c Print out console logs to terminal
Targeting Platforms and Operating Systems
Some times we need to detect in which platform the code is running, some scenarios are when you are using cordova plugins that are only supported by for example Android and iOS, and you are planning to deploy your app also to Windows app store, and as a PWA. A specific plugin with this characteristics is the admob free plugin.
Here is a list of the platforms supported:
Target platform from url
This is a useful functionality, when you run your application in the browser ionic serve you can use the --lab parameter to open your app into an iframe wrapper that call for specific platform, in that way is easy for you to visually select what platform target you want the ionic application to run.
But what happen when you deploy your application to firebase hosting for example, maybe to demo a prototype for your clients, or in our case to demo our latest starter on the ionic market
In our case wecalled the application with the following parameters: http://< path to your app >?production=true&ionicplatform=android
For Android:
https://www.jomendez.com/ionappfullplus/?production=true&ionicplatform=android
For iOS:
https://www.jomendez.com/ionappfullplus/?production=true&ionicplatform=ios
ngZone, include into angular cycle digest
As the official angular documentation states:
The most common use of this service is to optimize performance when starting a work consisting of one or more asynchronous tasks that don't require UI updates or error handling to be handled by Angular. Such tasks can be kicked off via runOutsideAngular and if needed, these tasks can reenter the Angular zone via run.
In other words, it allows you to either execute code outside angular cycle digest (to improve performance) or, to include code executed asynchronous (outside angular) inside the angular cycle digest.
A practical example is when we created the dialogFlow (chatbot) showcase, since the cordova plugin didn't have the ionic wrapper, it executes the code outside of angular:
this.ngZone.run(() => { console.log(response); let text = this.processCommand(response.result.fulfillment.speech); this.messages.push({ text: text, sender: "api" }); this.content.scrollToBottom(400); });
Declare globally window's var for plugins with no wrappers
This is the same scenario as before, we needed to call the dialogflow plugin's api via window variable window.ApiAIPlugin if try to call ApiAIPlugin from the window variable, Typescript will complaint about ApiAIPlugin not been a property of window
We have 3 solution for this, one is what the title of this category suggest, declare the window variable globally:
import { DatabaseProvider } from "../../../providers/database/database"; declare var window; @IonicPage() @Component({ selector: 'page-dialogflow-chat', templateUrl: 'dialogflow-chat.html', }) export class DialogflowChatPage { //... }
Second is to cast the window variable to "any" type
(<any>window).ApiAIPlugin
And the third one is to call the property using the arry call format:
window["ApiAIPlugin"].requestText
@ViewChild only works when the view is loaded
I remember faced this issue before, but the last time I did was crating the signature-pad showcase where I needed to reference a canvas within the HTML, and call the method clear() as soon as the page is loaded.
Once you declare the @ViewChild() if you try to use the reference on the constructor method you'll get an error:
Uncaught TypeError: Cannot read property 'clear' of null
One potencial solution is to call it when ionViewDidEnter lifecycle event is called:
ionViewDidEnter() { this.signaturePad.clear(); }
Use Crosswalk for Android
Every Android version runs a different WebView (a browser that runs your ionic application). The performance is different across devices, and it can be really bad on the old Android devices. To get a consistent performance and experience with fluidity and responsiveness on every Android device, you can install Crosswalk. It basically embeds the latest Chromium browser into your application, it will add around 20Mb per APK, both ARM and X86.
To install the plugin you can run the following command:
ionic plugin add cordova-plugin-crosswalk-webview
Knowing this was very useful, when created our multi-platform Gamefy (which is a bundle of 5 games in 1), because the performance of the games was poor on android low-end devices, and crosswalk fixed the issue.
Improving Loading Times and performance of your Ionic App
As every developer should know you are first of all responsible for writing good code that performs. It’s not the fault of Ionic (most of the time) if the app loads slowly, but there are few thinks you can do to improve your performance.
Make sure to use lazy load for your page, although when you generate a page from the ionic CLI it generate the page ready for lazy loading, the starters templates doesn't use lazy load.
By doing this, your app won’t load all the pages on startup immediately but rather prolong the loading a bit so the first page will appear a lot faster. This is very important if you are creating PWA, this is one of the key points for PWA.
To learn more about how to use lazy load on an Ionic app, visit here
As mentioned before, another improve is to use ngZone to execute tasks that don't require UI updates or error handling to be handled by Angular to improve performance.
As mentioned in the previous point, install crosswall can be a boost in your performance specially for low-end android devices.
Finally, what can make a huge change for all Ionic apps is building for production. This will remove any debugging plugin, minify, uglify the code, etc. Simply run:
ionic cordova build ios --prod --release
That command will activate Angular’s production mode, and run a full production build so you can get the smallest bundle possible.
It will take a while, especially the first time you run it, but it is worth it.
Using Custom Scripts
You'll notice that in the package.json file of your project there are a property called scripts
"scripts": {
"clean": "ionic-app-scripts clean",
"build": "ionic-app-scripts build",
"lint": "ionic-app-scripts lint",
"ionic:build": "ionic-app-scripts build",
"ionic:serve": "ionic-app-scripts serve",
}
Here you can define your own tasks, for deployment, android app signing, zipalign, etc. So every time you need to sign your apk to deploy to the app store, you can define a task to do that
"scripts": {
"clean": "ionic-app-scripts clean",
"build": "ionic-app-scripts build",
"lint": "ionic-app-scripts lint",
"ionic:build": "ionic-app-scripts build",
"ionic:serve": "ionic-app-scripts serve",
"jarsign": "jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore release-key.jks path\\platforms\\android\\app\\build\\outputs\\apk\\release\\app-release-unsigned.apk jomendez",
"zipalign": "\"C:\\Users\\user\\AppData\\Local\\Android\\sdk\\build-tools\\27.0.3\\zipalign\" -f -v 4 path\\platforms\\android\\app\\build\\outputs\\apk\\release\\app-release-unsigned.apk path\\platforms\\android\\app\\build\\outputs\\apk\\release\\name.apk",
}
Then you just have to run:
npm run jarsign
or
npm run zipalign
Add cordova-android-support-gradle-release to resolve gradle version conflict issues (Android)
In my experience sometimes cordova plugins throw errors regarding packages versions vs environment versions, or the most common for me has been conflict between two or more cordova plugin, the most recent was when I was trying to integrate the barcodescanner plugin on ionAppFullPlus together with the facebook plugin.
I received the following error:
Build fails with error
> java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex
The problem was that the two plugin uses different versions for the supporting libraries
After few hours trying everything I found this plugin for Android (cordova-android-support-gradle-release) that aligns various versions of the Android Support libraries specified by other plugins to a specific version, which fixed the issue.
Installation:
cordova plugin add cordova-android-support-gradle-release
Conclutions
I will try to update this post often with new ionic hacks, I think there is a lot of things that can be done to to improve the performance of ionic applications, or the developer's productivity, etc.