{"id":2918,"date":"2019-07-10T13:06:35","date_gmt":"2019-07-10T13:06:35","guid":{"rendered":"https:\/\/ionicframework.com\/blog\/?p=2918"},"modified":"2019-07-10T13:06:35","modified_gmt":"2019-07-10T13:06:35","slug":"guest-post-ionic-angular-performance-tuning","status":"publish","type":"post","link":"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning","title":{"rendered":"Guest Post: Ionic Angular Performance Tuning"},"content":{"rendered":"<blockquote><p>\n  This post was written by community member Masahiko Sakakibara. He is a Web Native App Developer (using JavaScript and PHP) and organizer of the Ionic Japan User Group. Recently, he&#8217;s started to use Capacitor and is currently developing plugins for <code>Facebook Login<\/code> and <code>Admob<\/code>. Follow him on Twitter <a href=\"https:\/\/twitter.com\/@rdlabo\">@rdlabo<\/a>.\n<\/p><\/blockquote>\n<p>Ionic 4 provides excellent performance out-of-the-box. Even so, I\u2019m a fan of pushing the limits of my web applications. In this post, I\u2019ll be covering some recent experiments I conducted that look at how to improve the performance of Angular within an Ionic 4 app. These hypotheses included:<\/p>\n<ul>\n<li>Using Eager Loading (Instead of Lazy Loading)<\/li>\n<li>Preloading Ionic Components<\/li>\n<li>Prefetching JavaScript files using a Service Worker<\/li>\n<\/ul>\n<p><!--more--><\/p>\n<blockquote><p>\n  Note: I spoke about Ionic Angular performance tips at the <a href=\"https:\/\/ionic-jp.connpass.com\/event\/133896\/\">July 7th Ionic Meetup<\/a> in Japan.\n<\/p><\/blockquote>\n<h2>Measurement Methods<\/h2>\n<h3>Ionic App Template<\/h3>\n<p>I used the Ionic 4 Starter Template with <code>@ionic\/angular<\/code> version 4.5.0.<\/p>\n<h3>Server Environment<\/h3>\n<p>All test apps were hosted on <a href=\"https:\/\/www.netlify.com\/\">Netlify<\/a>, a fully-featured free hosting service using subdomains. Asset optimization was set to <code>Disable<\/code> and the HTTP\/2 Server Push capability was not used.<\/p>\n<h3>Monitoring<\/h3>\n<p>We used <code>Catchpoint<\/code> with the help of <a href=\"https:\/\/spelldata.co.jp\">Spelldata Inc<\/a>. I configured the instrumentation node to be in San Francisco, near the Netlify server. More details <a href=\"https:\/\/qiita.com\/rdlabo\/private\/d7b4bcbc0886f0175926\">here<\/a>.<\/p>\n<h3>Simple Measurement<\/h3>\n<p>For the purposes of this article, I used the Audits feature from <a href=\"https:\/\/developers.google.com\/web\/tools\/lighthouse\/\">Lighthouse<\/a>, running within Google Chrome, then used the time and rendered results from <code>trace<\/code> to <code>Performance<\/code>. This section of Lighthouse&#8217;s report is useful to examine the startup of your app. It can highlight, for example, rendering issues and highlight why they are happening.<\/p>\n<h2>Hypothesis #1: Use Eager Loading Modules (Instead of Lazy Loading)<\/h2>\n<p>By default, Angular\u2019s <code>NgModules<\/code> are eagerly loaded, which means that as soon as the app loads, so do all of the <code>NgModules<\/code>, whether or not they are immediately necessary. For large apps with lots of routes, <a href=\"https:\/\/angular.io\/guide\/lazy-loading-ngmodules\">lazy loading<\/a> (<a href=\"https:\/\/angular.jp\/guide\/lazy-loading-ngmodules\">in Japanese<\/a>) is recommended, which loads each <code>NgModule<\/code> only when they are needed. This reduces the initial bundle size and is useful for speeding up large applications.<\/p>\n<p>However, my theory was that this design pattern may actually increase the initial app render time since in effect multiple JavaScript files are loaded over time.<\/p>\n<h3>Result: Verified<\/h3>\n<p>Within the Ionic tabs starter template, the initial display of <code>Tabs<\/code> loads two modules:<\/p>\n<pre><code>`app.module.ts` =&gt; `tabs.module.ts` =&gt; `tab1.module.ts`\n<\/code><\/pre>\n<p>I consolidated all this into <code>app.module.ts<\/code> and <a href=\"https:\/\/github.com\/ionic-jp\/tabs-compare\/blob\/no-module-lazy\/src\/app\/app-routing.module.ts#L9-L17\">removed <code>tabs.module.ts<\/code> and <code>tab1.module.ts<\/code><\/a>.<\/p>\n<table>\n<thead>\n<tr>\n<th align=\"left\">Design Pattern<\/th>\n<th align=\"left\">Mdn DNS<\/th>\n<th align=\"left\">Mdn Start Rendering<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td align=\"left\">Default<\/td>\n<td align=\"left\">7.00<\/td>\n<td align=\"left\">697.00<\/td>\n<\/tr>\n<tr>\n<td align=\"left\">Eager Loading<\/td>\n<td align=\"left\">7.00<\/td>\n<td align=\"left\">683.50 (-13.5)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Here we can see a slight difference in the render start time. Also, in the speed index, eager loading was faster than Default in the 99th percentile:<\/p>\n<p><a href=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/eager-loading.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"488\" data-src=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/eager-loading.png\" alt=\"\" class=\"aligncenter size-full wp-image-2919 lazyload\" data-srcset=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/eager-loading.png 1000w, https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/eager-loading-300x146.png 300w, https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/eager-loading-768x375.png 768w\" data-sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" style=\"--smush-placeholder-width: 1000px; --smush-placeholder-aspect-ratio: 1000\/488;\" \/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"488\" src=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/eager-loading.png\" alt=\"\" class=\"aligncenter size-full wp-image-2919\" srcset=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/eager-loading.png 1000w, https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/eager-loading-300x146.png 300w, https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/eager-loading-768x375.png 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/noscript><\/a><\/p>\n<h3>Verifying Page Transitions<\/h3>\n<p>Changing the destination page to eager loading reduces the latency of the page transition. However, as mentioned at the beginning, not doing lazy loading will increase the bundle size and may slow down the initial display. Therefore, you must set <code>preloadingStrategy<\/code> to <code>PreloadAllModules<\/code> and have completed Load <a href=\"https:\/\/github.com\/ionic-jp\/blank-preload\/blob\/preload\/src\/app\/app-routing.module.ts#L12\">before the transition<\/a>:<\/p>\n<pre><code>\/\/ app-routing.module.ts\n@NgModule({\n  imports: [\n    RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })\n  ],\n  exports: [RouterModule]\n})\n<\/code><\/pre>\n<p>However, <code>PreloadAllModules<\/code> does not allow you to select a Module to be preloaded, so if you have a lot of Modules, you can definitely reduce the latency of page transitions by specifying a Module that is preloaded.<\/p>\n<p>See <a href=\"https:\/\/medium.com\/@david.dalbusco\/preloading-modules-in-ionic-v4-1839c34384fb\">Preloading Modules in Ionic v4<\/a> for more details.<\/p>\n<h2>Hypothesis #2: Preload Ionic Components<\/h2>\n<p>It takes a bit of time to load Ionic components when the HTML file and\/or template is parsed.<\/p>\n<p>Can we decrease the time it takes to parse Ionic Components by preloading them? I tested this by configuring the DOM to use <code>display: none<\/code>:<\/p>\n<pre><code class=\"language-html\">  &lt;section style=&quot;display: none;&quot;&gt;\n    &lt;ion-tabs&gt;&lt;ion-tab-bar&gt;&lt;ion-tab-button&gt;&lt;\/ion-tab-button&gt;&lt;\/ion-tab-bar&gt;&lt;\/ion-tabs&gt;\n    &lt;ion-header&gt;&lt;ion-toolbar&gt;&lt;ion-title&gt;&lt;\/ion-title&gt;&lt;\/ion-toolbar&gt;&lt;\/ion-header&gt;\n    &lt;ion-content&gt;&lt;\/ion-content&gt;\n    &lt;ion-card&gt;&lt;ion-card-header&gt;&lt;\/ion-card-header&gt;&lt;ion-card-content&gt;&lt;\/ion-card-content&gt;\n    &lt;\/ion-card&gt;\n    &lt;ion-list&gt;&lt;ion-list-header&gt;&lt;ion-item&gt;&lt;\/ion-item&gt;&lt;\/ion-list-header&gt;&lt;\/ion-list&gt;\n    &lt;ion-label&gt;&lt;\/ion-label&gt;\n  &lt;\/section&gt;\n<\/code><\/pre>\n<h3>Result: Verified<\/h3>\n<p>For measurement purposes, Default is compared to <code>eager loading &amp; PreLoad<\/code>, but you can see that it is faster than with eager loading only:<\/p>\n<table>\n<thead>\n<tr>\n<th align=\"left\">Pattern<\/th>\n<th align=\"left\">Mdn DNS<\/th>\n<th align=\"left\">Mdn Start Rendering<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td align=\"left\">Default<\/td>\n<td align=\"left\">7.00<\/td>\n<td align=\"left\">697.00<\/td>\n<\/tr>\n<tr>\n<td align=\"left\">Eager Loading<\/td>\n<td align=\"left\">7.00<\/td>\n<td align=\"left\">683.50 (-13.5)<\/td>\n<\/tr>\n<tr>\n<td align=\"left\">Eager Loading &amp; PreLoad<\/td>\n<td align=\"left\">7.00<\/td>\n<td align=\"left\">637.50 (-59.5)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>You can see a difference in the render start time. Also, in the speed index, eager loading &amp; PreLoad was faster than Default or eager loading in the 99th percentile.<\/p>\n<p><a href=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/verify-eager-load.png\"><img loading=\"lazy\" decoding=\"async\" width=\"987\" height=\"472\" data-src=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/verify-eager-load.png\" alt=\"\" class=\"aligncenter size-full wp-image-2920 lazyload\" data-srcset=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/verify-eager-load.png 987w, https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/verify-eager-load-300x143.png 300w, https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/verify-eager-load-768x367.png 768w\" data-sizes=\"auto, (max-width: 987px) 100vw, 987px\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" style=\"--smush-placeholder-width: 987px; --smush-placeholder-aspect-ratio: 987\/472;\" \/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"987\" height=\"472\" src=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/verify-eager-load.png\" alt=\"\" class=\"aligncenter size-full wp-image-2920\" srcset=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/verify-eager-load.png 987w, https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/verify-eager-load-300x143.png 300w, https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/verify-eager-load-768x367.png 768w\" sizes=\"auto, (max-width: 987px) 100vw, 987px\" \/><\/noscript><\/a><\/p>\n<h3>Verifying Page Transitions<\/h3>\n<p>However, during the loading of Ionic Components, the <code>ion-router-outlet<\/code> blocks transitions, so writing directly to the <code>home.html<\/code> template will slow down the display of  <code>\/home<\/code>. Therefore, we need to <a href=\"https:\/\/github.com\/ionic-jp\/blank-preload\/blob\/preload\/src\/app\/home\/home.page.ts#L12-L21\">prepare the DOM asynchronously<\/a>:<\/p>\n<pre><code class=\"language-html\">  \/\/ home.page.ts\n  ionViewDidEnter() {\n    const preloadArea: HTMLElement = document.getElementById(&#039;preload&#039;);\n    preloadArea.appendChild(document.createElement(&#039;ion-card&#039;));\n    preloadArea.appendChild(document.createElement(&#039;ion-card-header&#039;));\n    preloadArea.appendChild(document.createElement(&#039;ion-card-subtitle&#039;));\n    preloadArea.appendChild(document.createElement(&#039;ion-card-title&#039;));\n    preloadArea.appendChild(document.createElement(&#039;ion-card-content&#039;));\n    preloadArea.appendChild(document.createElement(&#039;ion-back-button&#039;));\n  }\n<\/code><\/pre>\n<p>The code above is not preloaded, while the GIF below is (the transition animation has been disabled for clarity):<\/p>\n<p><a href=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/blank-default.gif\"><img loading=\"lazy\" decoding=\"async\" width=\"1318\" height=\"892\" data-src=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/blank-default.gif\" alt=\"\" class=\"aligncenter size-full wp-image-2921 lazyload\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" style=\"--smush-placeholder-width: 1318px; --smush-placeholder-aspect-ratio: 1318\/892;\" \/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"1318\" height=\"892\" src=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/blank-default.gif\" alt=\"\" class=\"aligncenter size-full wp-image-2921\" \/><\/noscript><\/a><\/p>\n<p>See the demo here: <a href=\"https:\/\/blank-default.netlify.com\">https:\/\/blank-default.netlify.com<\/a><\/p>\n<p><a href=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/blank-preload.gif\"><img loading=\"lazy\" decoding=\"async\" width=\"1318\" height=\"892\" data-src=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/blank-preload.gif\" alt=\"\" class=\"aligncenter size-full wp-image-2922 lazyload\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" style=\"--smush-placeholder-width: 1318px; --smush-placeholder-aspect-ratio: 1318\/892;\" \/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"1318\" height=\"892\" src=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/blank-preload.gif\" alt=\"\" class=\"aligncenter size-full wp-image-2922\" \/><\/noscript><\/a><\/p>\n<p>See the demo here: <a href=\"https:\/\/blank-preload.netlify.com\">https:\/\/blank-preload.netlify.com<\/a><\/p>\n<p>In the GIF animation above, after you click the button, we have to wait for two JavaScript files to load, whereas below, you&#8217;ve already loaded them, so you&#8217;ll see the next page immediately after clicking the \u201cnext\u201d button. You can also notice that the back button displays instantly when the transition is not delayed.<\/p>\n<h2>Hypothesis #3: Prefetch JavaScript files using a Service Worker<\/h2>\n<p>My theory is that prefetching JavaScript files using Angular\u2019s PWA library (<code>@ angular\/pwa<\/code>) may improve performance. This configuration looks like:<\/p>\n<pre><code class=\"language-json\">  \/\/ ng-sw.config.json\n  &quot;assetGroups&quot;: [\n    {\n      &quot;name&quot;: &quot;app&quot;,\n      &quot;installMode&quot;: &quot;prefetch&quot;,\n      &quot;resources&quot;: {\n        &quot;files&quot;: [\n          &quot;\/favicon.ico&quot;,\n          &quot;\/index.html&quot;,\n          &quot;\/*.css&quot;,\n          &quot;\/*.js&quot;\n        ]\n      }\n    ...\n<\/code><\/pre>\n<h3>Result: No Effect<\/h3>\n<p><a href=\"https:\/\/github.com\/ionic-jp\/tabs-compare\/blob\/total\/src\/ngsw-config.json#L10-L12\">Prefetching JavaScript<\/a> using a Service Worker is executed after the <code>First Meaningful Paint<\/code>. Therefore, enabling Service Workers does not affect the initial display.<\/p>\n<h3>Verify Page Transitions<\/h3>\n<p>There may be an effect. However, about 22000 milliseconds are required for loading to complete in a 30 Mbps downstream environment. So if a user is using an app for a long time, you can expect prefetch to speed things up.<\/p>\n<p><a href=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/blank-sw.gif\"><img loading=\"lazy\" decoding=\"async\" width=\"1322\" height=\"896\" data-src=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/blank-sw.gif\" alt=\"\" class=\"aligncenter size-full wp-image-2923 lazyload\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" style=\"--smush-placeholder-width: 1322px; --smush-placeholder-aspect-ratio: 1322\/896;\" \/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"1322\" height=\"896\" src=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/blank-sw.gif\" alt=\"\" class=\"aligncenter size-full wp-image-2923\" \/><\/noscript><\/a><\/p>\n<p>(Demo code: <a href=\"https:\/\/blank-sw.netlify.com\">https:\/\/blank-sw.netlify.com<\/a>)<\/p>\n<p>Precaching assets can take a long time if there are a lot of assets. So it\u2019s best to instead cache these assets after they are done loading<\/p>\n<h2>Bonus (Unverified) Hypothesis: Preloading Ionicons<\/h2>\n<p>For this test, I tried preloading Ionicons by requesting them before they were needed. This way the file loads faster because it\u2019s already in memory, versus requesting it over the network.<\/p>\n<p><code>ionIcon<\/code> calls the appropriate SVG file and displays it, after rendering the Web Components (see <a href=\"https:\/\/github.com\/ionic-team\/ionicons\/blob\/master\/src\/components\/icon\/icon.tsx#L122-L123\">reference code<\/a>).<\/p>\n<p>My theory is that calling out an SVG file for use prior to render may help speed up.<\/p>\n<p><a href=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/preload-ionicons.png\"><img loading=\"lazy\" decoding=\"async\" width=\"984\" height=\"344\" data-src=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/preload-ionicons.png\" alt=\"\" class=\"aligncenter size-full wp-image-2924 lazyload\" data-srcset=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/preload-ionicons.png 984w, https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/preload-ionicons-300x105.png 300w, https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/preload-ionicons-768x268.png 768w\" data-sizes=\"auto, (max-width: 984px) 100vw, 984px\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" style=\"--smush-placeholder-width: 984px; --smush-placeholder-aspect-ratio: 984\/344;\" \/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"984\" height=\"344\" src=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/preload-ionicons.png\" alt=\"\" class=\"aligncenter size-full wp-image-2924\" srcset=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/preload-ionicons.png 984w, https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/preload-ionicons-300x105.png 300w, https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/preload-ionicons-768x268.png 768w\" sizes=\"auto, (max-width: 984px) 100vw, 984px\" \/><\/noscript><\/a><br \/>\n(The icon does not appear and is not Visually Loaded)<\/p>\n<p>However, once I tried preloading them using <code>display: none<\/code> for all the <code>ionIcons<\/code>, but I realized there were no performance improvements.<\/p>\n<p>Demo: <a href=\"https:\/\/tabs-bad-lazy.netlify.com\">https:\/\/tabs-bad-lazy.netlify.com<\/a><\/p>\n<p>A different approach is needed to complete the call to the SVG file as if a block is occurring, and <code>rel=&quot;preload&quot;<\/code> is a good choice. There are some issues such as how to judge iOS\/Android performance, so it has not been verified yet. This is probably the same as <code>ionImg<\/code>.<\/p>\n<h2>Summary<\/h2>\n<p>Reviewing the above experiments, we\u2019ve learned a bunch of tips for improving your <code>Ionic Angular<\/code> apps.<\/p>\n<p><strong>On Improving Initial Display:<\/strong> Use eager loading over lazy loading and server worker prefetching doesn\u2019t have any effect.<\/p>\n<p><strong>On Improving Page Transitions:<\/strong> Preload Angular modules and service worker prefetching may speed up the transitions.<\/p>\n<h2>Improving Your Ionic Angular Apps<\/h2>\n<p>There are many approaches to performance tuning Angular apps. If you\u2019re focused solely on the front-end engineering aspect of app building, then reducing time-to-render is the most important area to focus on.<\/p>\n<p>I would like to encourage you to develop and test your own hypotheses while developing your own <code>Ionic Angular<\/code> apps. Even if the difference in the results is small, they may be worth it depending on your performance requirements.<\/p>\n<p>The <a href=\"https:\/\/spelldata.co.jp\/catchpoint\/\">Catchpoint<\/a> used in cooperation with <a href=\"https:\/\/spelldata.co.jp\">Spelldata Inc.<\/a> is an excellent tool to measure SPA and PWA performance correctly, so I recommend using it when you run your own performance tests.<\/p>\n<p>See you later!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post was written by community member Masahiko Sakakibara. He is a Web Native App Developer (using JavaScript and PHP) and organizer of the Ionic Japan User Group. Recently, he&#8217;s started to use Capacitor and is currently developing plugins for Facebook Login and Admob. Follow him on Twitter @rdlabo. Ionic 4 provides excellent performance out-of-the-box. [&hellip;]<\/p>\n","protected":false},"author":70,"featured_media":2933,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"publish_to_discourse":"","publish_post_category":"","wpdc_auto_publish_overridden":"","wpdc_topic_tags":"","wpdc_pin_topic":"","wpdc_pin_until":"","discourse_post_id":"","discourse_permalink":"","wpdc_publishing_response":"","wpdc_publishing_error":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[121],"tags":[60,79],"class_list":["post-2918","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-engineering","tag-angular","tag-performance"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v23.0 (Yoast SEO v23.0) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Guest Post: Ionic Angular Performance Tuning - Ionic Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Guest Post: Ionic Angular Performance Tuning\" \/>\n<meta property=\"og:description\" content=\"This post was written by community member Masahiko Sakakibara. He is a Web Native App Developer (using JavaScript and PHP) and organizer of the Ionic Japan User Group. Recently, he&#8217;s started to use Capacitor and is currently developing plugins for Facebook Login and Admob. Follow him on Twitter @rdlabo. Ionic 4 provides excellent performance out-of-the-box. [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning\" \/>\n<meta property=\"og:site_name\" content=\"Ionic Blog\" \/>\n<meta property=\"article:published_time\" content=\"2019-07-10T13:06:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/ionic-angular-performance-tuning.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1600\" \/>\n\t<meta property=\"og:image:height\" content=\"880\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Masahiko Sakakibara\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ionicframework\" \/>\n<meta name=\"twitter:site\" content=\"@ionicframework\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Masahiko Sakakibara\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#article\",\"isPartOf\":{\"@id\":\"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning\"},\"author\":{\"name\":\"Masahiko Sakakibara\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/2d3653d94fc25f53608288b6ac6ec15c\"},\"headline\":\"Guest Post: Ionic Angular Performance Tuning\",\"datePublished\":\"2019-07-10T13:06:35+00:00\",\"dateModified\":\"2019-07-10T13:06:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning\"},\"wordCount\":1190,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/ionic.io\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#primaryimage\"},\"thumbnailUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/ionic-angular-performance-tuning.png\",\"keywords\":[\"Angular\",\"performance\"],\"articleSection\":[\"Engineering\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning\",\"url\":\"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning\",\"name\":\"Guest Post: Ionic Angular Performance Tuning - Ionic Blog\",\"isPartOf\":{\"@id\":\"https:\/\/ionic.io\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#primaryimage\"},\"image\":{\"@id\":\"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#primaryimage\"},\"thumbnailUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/ionic-angular-performance-tuning.png\",\"datePublished\":\"2019-07-10T13:06:35+00:00\",\"dateModified\":\"2019-07-10T13:06:35+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#primaryimage\",\"url\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/ionic-angular-performance-tuning.png\",\"contentUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/ionic-angular-performance-tuning.png\",\"width\":1600,\"height\":880},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/ionic.io\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Guest Post: Ionic Angular Performance Tuning\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/ionic.io\/blog\/#website\",\"url\":\"https:\/\/ionic.io\/blog\/\",\"name\":\"ionic.io\/blog\",\"description\":\"Build amazing native and progressive web apps with the web\",\"publisher\":{\"@id\":\"https:\/\/ionic.io\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/ionic.io\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/ionic.io\/blog\/#organization\",\"name\":\"Ionic\",\"url\":\"https:\/\/ionic.io\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png\",\"contentUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png\",\"width\":1920,\"height\":854,\"caption\":\"Ionic\"},\"image\":{\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/ionicframework\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/2d3653d94fc25f53608288b6ac6ec15c\",\"name\":\"Masahiko Sakakibara\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a0987cde03196349491ad66e060c17e1f71b66f567597c8b3593dc9b2961e04b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a0987cde03196349491ad66e060c17e1f71b66f567597c8b3593dc9b2961e04b?s=96&d=mm&r=g\",\"caption\":\"Masahiko Sakakibara\"},\"url\":\"https:\/\/ionic.io\/blog\/author\/rdlabo\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Guest Post: Ionic Angular Performance Tuning - Ionic Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning","og_locale":"en_US","og_type":"article","og_title":"Guest Post: Ionic Angular Performance Tuning","og_description":"This post was written by community member Masahiko Sakakibara. He is a Web Native App Developer (using JavaScript and PHP) and organizer of the Ionic Japan User Group. Recently, he&#8217;s started to use Capacitor and is currently developing plugins for Facebook Login and Admob. Follow him on Twitter @rdlabo. Ionic 4 provides excellent performance out-of-the-box. [&hellip;]","og_url":"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning","og_site_name":"Ionic Blog","article_published_time":"2019-07-10T13:06:35+00:00","og_image":[{"width":1600,"height":880,"url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/ionic-angular-performance-tuning.png","type":"image\/png"}],"author":"Masahiko Sakakibara","twitter_card":"summary_large_image","twitter_creator":"@ionicframework","twitter_site":"@ionicframework","twitter_misc":{"Written by":"Masahiko Sakakibara","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#article","isPartOf":{"@id":"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning"},"author":{"name":"Masahiko Sakakibara","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/2d3653d94fc25f53608288b6ac6ec15c"},"headline":"Guest Post: Ionic Angular Performance Tuning","datePublished":"2019-07-10T13:06:35+00:00","dateModified":"2019-07-10T13:06:35+00:00","mainEntityOfPage":{"@id":"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning"},"wordCount":1190,"commentCount":0,"publisher":{"@id":"https:\/\/ionic.io\/blog\/#organization"},"image":{"@id":"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#primaryimage"},"thumbnailUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/ionic-angular-performance-tuning.png","keywords":["Angular","performance"],"articleSection":["Engineering"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#respond"]}]},{"@type":"WebPage","@id":"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning","url":"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning","name":"Guest Post: Ionic Angular Performance Tuning - Ionic Blog","isPartOf":{"@id":"https:\/\/ionic.io\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#primaryimage"},"image":{"@id":"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#primaryimage"},"thumbnailUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/ionic-angular-performance-tuning.png","datePublished":"2019-07-10T13:06:35+00:00","dateModified":"2019-07-10T13:06:35+00:00","breadcrumb":{"@id":"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#primaryimage","url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/ionic-angular-performance-tuning.png","contentUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/ionic-angular-performance-tuning.png","width":1600,"height":880},{"@type":"BreadcrumbList","@id":"https:\/\/ionic.io\/blog\/guest-post-ionic-angular-performance-tuning#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/ionic.io\/blog"},{"@type":"ListItem","position":2,"name":"Guest Post: Ionic Angular Performance Tuning"}]},{"@type":"WebSite","@id":"https:\/\/ionic.io\/blog\/#website","url":"https:\/\/ionic.io\/blog\/","name":"ionic.io\/blog","description":"Build amazing native and progressive web apps with the web","publisher":{"@id":"https:\/\/ionic.io\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ionic.io\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/ionic.io\/blog\/#organization","name":"Ionic","url":"https:\/\/ionic.io\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png","contentUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png","width":1920,"height":854,"caption":"Ionic"},"image":{"@id":"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/ionicframework"]},{"@type":"Person","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/2d3653d94fc25f53608288b6ac6ec15c","name":"Masahiko Sakakibara","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/a0987cde03196349491ad66e060c17e1f71b66f567597c8b3593dc9b2961e04b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a0987cde03196349491ad66e060c17e1f71b66f567597c8b3593dc9b2961e04b?s=96&d=mm&r=g","caption":"Masahiko Sakakibara"},"url":"https:\/\/ionic.io\/blog\/author\/rdlabo"}]}},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2019\/07\/ionic-angular-performance-tuning.png","_links":{"self":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts\/2918","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/users\/70"}],"replies":[{"embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/comments?post=2918"}],"version-history":[{"count":0,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts\/2918\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/media\/2933"}],"wp:attachment":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/media?parent=2918"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/categories?post=2918"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/tags?post=2918"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}