{"id":2463,"date":"2017-04-10T11:43:46","date_gmt":"2017-04-10T09:43:46","guid":{"rendered":"https:\/\/www.angulararchitects.io\/?p=2463"},"modified":"2017-04-10T11:43:46","modified_gmt":"2017-04-10T09:43:46","slug":"optimizing-performance","status":"publish","type":"post","link":"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/","title":{"rendered":"Optimizing Performance"},"content":{"rendered":"<div class=\"article\">\n<p>The new Router for Angular allows for lazy loading of modules. This way, the startup performance of an Angular based SPA can be optimized. At <a href=\"http:\/\/www.angularconnect.com\/\">AngluarConnect 2016 in London<\/a>, the Angluar mastermind <a href=\"https:\/\/vsavkin.com\/\">Victor Savkin<\/a> presented a preloading approach which goes beyond this: It uses free resources after the start of the application to load modules that might be requested via lazy loading later. If the router actually needs those modules later, they are available immediately.  <\/p>\n<p>In this post I'm showing how to use Preloading in an Angular application. The <a href=\"https:\/\/github.com\/manfredsteyer\/preloading-angular-2\">whole sample<\/a> can be found here. It bases upon Angular 2.1.0-beta.0 and the Router 3.1.0-beta.0. Those are the first versions that offer this feature. <\/p>\n<h2>Initial Situation<\/h2>\n<p>The sample below uses an <code>AppModule<\/code>, that imports a <code>FlightModule<\/code> via lazy loading. For this, it references the name of the module and the file that contains it with <code>loadChildren<\/code>:<\/p>\n<pre><code>\/\/ app.routes.ts\n\nimport {Routes, RouterModule} from '@angular\/router';\nimport {HomeComponent} from \".\/modules\/home\/home\/home.component\";\n\nconst ROUTE_CONFIG: Routes = [\n    {\n        path: 'home',\n        component: HomeComponent\n    },\n    {\n        path: 'flight-booking',\n        loadChildren: '.\/modules\/flights\/flight.module#FlightModule'\n    },\n    {\n        path: '**',\n        redirectTo: 'home'\n    }\n];\n\nexport const AppRoutesModule = RouterModule.forRoot(ROUTE_CONFIG);\n<\/code><\/pre>\n<p>Using the routing configuration, the terminal line in this listing creates a configured <code>RouterModule<\/code> which is exported via the variable <code>AppRoutesModule<\/code>. The <code>AppModule<\/code>, that serves as Root-Module, imports it. <\/p>\n<pre><code>\/\/ app.module.ts\n\nimport {NgModule} from \"@angular\/core\";\nimport {AppRoutesModule} from \".\/app.routes\";\n\n[...]\n\n@NgModule({\n    imports: [\n        BrowserModule,\n        HttpModule,\n        FormsModule,\n        AppRoutesModule,\n        [...]\n    ],\n    declarations: [\n        AppComponent\n    ],\n    bootstrap: [\n        AppComponent \n    ]\n})\nexport class AppModule { \n}\n<\/code><\/pre>\n<p>In order to make <a href=\"https:\/\/www.npmjs.com\/package\/angular2-router-loader\"><code>loadChildren<\/code><\/a> play together nicely with <a href=\"https:\/\/webpack.github.io\/\">webpack 2<\/a> the angular2-router-loader is used. It can be obtained with <code>npm<\/code> (<code>npm i angular2-router-loader --save-dev<\/code>) and serves as additional loader for .ts-files in <code>webpack.config.js<\/code>:<\/p>\n<pre><code>[...]\n    module: {\n        loaders: [\n            [...],\n            { test: \/\\.html$\/,  loaders: ['html-loader'] },\n            { test: \/\\.ts$\/, loaders: ['angular2-router-loader?loader=system', 'awesome-typescript-loader'], exclude: \/node_modules\/}\n        ]\n    },\n[...]\n<\/code><\/pre>\n<p>The parameter <code>?loader=system<\/code> asks the loader to load modules requested by lazy loading via <code>System.import<\/code>.<\/p>\n<h2>Preloading<\/h2>\n<p>To activate preloading starting from version 3.1.0 of the router, one has only to give a <code>PreloadingStrategy<\/code> when creating the configured <code>AppRoutesModule<\/code>:<\/p>\n<pre><code>import {Routes, RouterModule, PreloadAllModules} from '@angular\/router';\n\n[...]\n\nexport const AppRoutesModule = RouterModule.forRoot(ROUTE_CONFIG, { preloadingStrategy: PreloadAllModules });\n<\/code><\/pre>\n<p>The <code>PreloadAllModules<\/code> strategy used in this example causes the Angular application to obtain all modules by means of prefetching after the start of the program.<\/p>\n<p>The result of this endeavor can be witnessed in the dev tools window (F12) within the <code>network<\/code> tab. As loading local files is very fast, it is advisable to throttle the speed of the network. the following picture demonstrates for instance the loading behavior with a simulated 3G connection:<\/p>\n<p><a href=\"https:\/\/camo.githubusercontent.com\/2830be22cb2fdd6b13e8a525775a1ceb5480cfcd\/687474703a2f2f692e696d6775722e636f6d2f705a34507779462e706e67\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/camo.githubusercontent.com\/2830be22cb2fdd6b13e8a525775a1ceb5480cfcd\/687474703a2f2f692e696d6775722e636f6d2f705a34507779462e706e67\" alt=\"Loading behavior after activating preloading\" data-canonical-src=\"http:\/\/i.imgur.com\/pZ4PwyF.png\" style=\"max-width:100%;\"><\/a><\/p>\n<p>When loading the page, the corresponding window shows that the bundle <code>0.js<\/code> containing the <code>FlightModule<\/code> is not loaded before the application starts. As this bundle is quite small, one has to look at this very carefully. Hence, the next section describes an experiment that allows to better reproduce this fact.<\/p>\n<h2>Watching preloading with an experiment<\/h2>\n<p>For a better traceability of the fact that preloading doesn't kick in before the start of the application, this section uses a custom <code>PreloadingStrategy<\/code>. This strategy enforces a delay of some seconds, before it begins to load the modules. <\/p>\n<p>Custom preloading can be easily achieved by implementing <code>PreloadingStrategy<\/code>, e.g. as follows:<\/p>\n<pre><code>\/\/ custom-preloading-strategy.ts\n\nimport {PreloadingStrategy, Route} from \"@angular\/router\";\nimport {Observable} from 'rxjs';\n\nexport class CustomPreloadingStrategy implements PreloadingStrategy {\n\n    preload(route: Route, fn: () =&gt; Observable&lt;any&gt;): Observable&lt;any&gt; {\n\n        return Observable.of(true).delay(7000).flatMap(_ =&gt; fn());\n    }\n\n}\n<\/code><\/pre>\n<p>The method <code>preload<\/code> of the <code>PreloadingStrategy<\/code> gets from Angular the route to load as well as a function that cares for the loading itself. Thus, it can decide whether to preload the route in question. The returned <code>Observable<\/code> informs Angular, when <code>preload<\/code> has done its task.<\/p>\n<p>The here considered implementation creates an Observable with the (dummy) value <code>true<\/code> and transmits it with a delay of 7 seconds. After that, <code>flatMap<\/code> triggers the preloading.<\/p>\n<p>To use the <code>CustomPreloadingStrategy<\/code>, the <code>AppRoutesModule<\/code> has to point to it. As the strategy is solely used as a token at this point, Angular needs a provider for it too:<\/p>\n<pre><code>\/\/ app.routes.ts\n\n[...]\n\nexport const AppRoutesModule = RouterModule.forRoot(ROUTE_CONFIG, { preloadingStrategy: CustomPreloadingStrategy });\nexport const APP_ROUTES_MODULE_PROVIDER = [CustomPreloadingStrategy];\n<\/code><\/pre>\n<p>To make the provider available for the application, the <code>AppModule<\/code> has to reference it via its array <code>providers<\/code>. The configured <code>AppRoutesModule<\/code> is still imported:  <\/p>\n<pre><code>\/\/ app.module.ts\nimport {AppRoutesModule, APP_ROUTES_MODULE_PROVIDER} from \".\/app.routes\";\n[...]\n\n@NgModule({\n    imports: [\n        BrowserModule,\n        HttpModule,\n        FormsModule,\n        AppRoutesModule,\n        [...]\n    ],\n    declarations: [\n        AppComponent\n    ],\n    providers: [\n        [...]\n        APP_ROUTES_MODULE_PROVIDER\n    ],\n    bootstrap: [\n        AppComponent \n    ]\n})\nexport class AppModule { \n}\n<\/code><\/pre>\n<p>The <code>Network<\/code> tab within the dev tools now shows very clearly that the application starts to preload the module not before the start of the application:<\/p>\n<p><a href=\"https:\/\/camo.githubusercontent.com\/9d0f83b741012789b610639f8ed038c21c5c7ca8\/687474703a2f2f692e696d6775722e636f6d2f56575a7831436f2e706e67\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/camo.githubusercontent.com\/9d0f83b741012789b610639f8ed038c21c5c7ca8\/687474703a2f2f692e696d6775722e636f6d2f56575a7831436f2e706e67\" alt=\"Loading Behavior with custom preloading strategy\" data-canonical-src=\"http:\/\/i.imgur.com\/VWZx1Co.png\" style=\"max-width:100%;\"><\/a><\/p>\n<h2>Selective preloading with custom preloading strategy<\/h2>\n<p><a href=\"https:\/\/vsavkin.com\/\">Victor Savkin<\/a> also showed at <a href=\"http:\/\/www.angularconnect.com\/\">AngularConnect 2016 in London<\/a> how an Angular application can restrict preloading to specific modules. To mark the routes to preload, he used a custom property <code>preload<\/code>:<\/p>\n<pre><code>\/\/ app.routes.ts\n\nimport {Routes, RouterModule} from '@angular\/router';\nimport {HomeComponent} from \".\/modules\/home\/home\/home.component\";\n\nconst ROUTE_CONFIG: Routes = [\n    {\n        path: 'home',\n        component: HomeComponent\n    },\n    {\n        path: 'flight-booking',\n        loadChildren: '.\/modules\/flights\/flight.module#FlightModule',\n        data: { preload: true }\n    },\n    {\n        path: '**',\n        redirectTo: 'home'\n    }\n];\n\nexport const AppRoutesModule = RouterModule.forRoot(ROUTE_CONFIG, { preloadingStrategy: CustomPreloadingStrategy });\n\nexport const APP_ROUTES_MODULE_PROVIDER = [CustomPreloadingStrategy];\n\n<\/code><\/pre>\n<p>The property <code>data<\/code> is intended for such custom extensions. The <code>PreloadingStrategy<\/code> can now check, whether the passed route has this property and whether it is <em>truthy<\/em>:<\/p>\n<pre><code>\/\/ custom-preloading-strategy.ts\n\nimport {PreloadingStrategy, Route} from \"@angular\/router\";\nimport {Observable} from 'rxjs';\n\nexport class CustomPreloadingStrategy implements PreloadingStrategy {\n\n    preload(route: Route, fn: () =&gt; Observable&lt;any&gt;): Observable&lt;any&gt; {\n        if (route.data['preload']) {\n            return fn();\n        }\n        else {\n            return Observable.of(null);\n        }\n    }\n\n}\n<\/code><\/pre>\n<p>If the route should be preloaded, it is loading the route with the passed function and returns the received Observable. Otherwise, it returns a (dummy) Observable which transports the value <code>null<\/code>.<\/p>\n<p>After that, the registration of the <code>CustomPreloadingStrategy<\/code> takes place as mentioned above. <\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>With Preloading And The New Angular Router [English Version]<\/p>\n","protected":false},"author":9,"featured_media":2997,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2463","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-unkategorisiert"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Optimizing Performance - ANGULARarchitects<\/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:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Optimizing Performance - ANGULARarchitects\" \/>\n<meta property=\"og:description\" content=\"With Preloading And The New Angular Router [English Version]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/\" \/>\n<meta property=\"og:site_name\" content=\"ANGULARarchitects\" \/>\n<meta property=\"article:published_time\" content=\"2017-04-10T09:43:46+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1280\" \/>\n\t<meta property=\"og:image:height\" content=\"853\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Manfred Steyer, GDE\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@daniel\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Manfred Steyer, GDE\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/\"},\"author\":{\"name\":\"Manfred Steyer, GDE\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951\"},\"headline\":\"Optimizing Performance\",\"datePublished\":\"2017-04-10T09:43:46+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/\"},\"wordCount\":646,\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg\",\"articleSection\":[\"Unkategorisiert\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/\",\"name\":\"Optimizing Performance - ANGULARarchitects\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg\",\"datePublished\":\"2017-04-10T09:43:46+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/#primaryimage\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg\",\"width\":1280,\"height\":853},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.angulararchitects.io\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Optimizing Performance\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"name\":\"ANGULARarchitects\",\"description\":\"AngularArchitects.io\",\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\",\"name\":\"ANGULARarchitects\",\"alternateName\":\"SOFTWAREarchitects\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"width\":644,\"height\":216,\"caption\":\"ANGULARarchitects\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/github.com\/angular-architects\",\"https:\/\/www.linkedin.com\/company\/angular-architects\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951\",\"name\":\"Manfred Steyer, GDE\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g\",\"caption\":\"Manfred Steyer, GDE\"},\"sameAs\":[\"https:\/\/x.com\/daniel\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Optimizing Performance - ANGULARarchitects","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:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/","og_locale":"en_US","og_type":"article","og_title":"Optimizing Performance - ANGULARarchitects","og_description":"With Preloading And The New Angular Router [English Version]","og_url":"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/","og_site_name":"ANGULARarchitects","article_published_time":"2017-04-10T09:43:46+00:00","og_image":[{"width":1280,"height":853,"url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg","type":"image\/jpeg"}],"author":"Manfred Steyer, GDE","twitter_card":"summary_large_image","twitter_creator":"@daniel","twitter_misc":{"Written by":"Manfred Steyer, GDE","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/#article","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/"},"author":{"name":"Manfred Steyer, GDE","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951"},"headline":"Optimizing Performance","datePublished":"2017-04-10T09:43:46+00:00","mainEntityOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/"},"wordCount":646,"publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg","articleSection":["Unkategorisiert"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/","url":"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/","name":"Optimizing Performance - ANGULARarchitects","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/#primaryimage"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg","datePublished":"2017-04-10T09:43:46+00:00","breadcrumb":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/#primaryimage","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg","width":1280,"height":853},{"@type":"BreadcrumbList","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/optimizing-performance\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.angulararchitects.io\/en\/"},{"@type":"ListItem","position":2,"name":"Optimizing Performance"}]},{"@type":"WebSite","@id":"https:\/\/www.angulararchitects.io\/en\/#website","url":"https:\/\/www.angulararchitects.io\/en\/","name":"ANGULARarchitects","description":"AngularArchitects.io","publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.angulararchitects.io\/en\/#organization","name":"ANGULARarchitects","alternateName":"SOFTWAREarchitects","url":"https:\/\/www.angulararchitects.io\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","width":644,"height":216,"caption":"ANGULARarchitects"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/github.com\/angular-architects","https:\/\/www.linkedin.com\/company\/angular-architects\/"]},{"@type":"Person","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951","name":"Manfred Steyer, GDE","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g","caption":"Manfred Steyer, GDE"},"sameAs":["https:\/\/x.com\/daniel"]}]}},"_links":{"self":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/2463","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/comments?post=2463"}],"version-history":[{"count":0,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/2463\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media\/2997"}],"wp:attachment":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media?parent=2463"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/categories?post=2463"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/tags?post=2463"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}