{"id":28702,"date":"2019-04-24T22:13:00","date_gmt":"2019-04-24T20:13:00","guid":{"rendered":"https:\/\/blexin.com\/?p=28702"},"modified":"2021-01-13T09:40:37","modified_gmt":"2021-01-13T08:40:37","slug":"angular-performance-improvements","status":"publish","type":"post","link":"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/","title":{"rendered":"Angular Performance Improvements"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"608\" data-attachment-id=\"28703\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/attachment\/ccc34bfb-ebde-488d-873c-6195df9b513b\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ccc34bfb-ebde-488d-873c-6195df9b513b.png?fit=1024%2C608&amp;ssl=1\" data-orig-size=\"1024,608\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"ccc34bfb-ebde-488d-873c-6195df9b513b\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ccc34bfb-ebde-488d-873c-6195df9b513b.png?fit=1024%2C608&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ccc34bfb-ebde-488d-873c-6195df9b513b.png?resize=1024%2C608&#038;ssl=1\" alt=\"\" class=\"wp-image-28703\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/ccc34bfb-ebde-488d-873c-6195df9b513b.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/ccc34bfb-ebde-488d-873c-6195df9b513b-980x582.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/ccc34bfb-ebde-488d-873c-6195df9b513b-480x285.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Una delle caratteristiche pi\u00f9 interessanti delle librerie di front end \u00e8 la capacit\u00e0 di tenere in binding l&#8217;interfaccia utente con le propriet\u00e0 contenenti i dati da visualizzare. Anche Angular offre questa caratteristica, utilizzando un meccanismo che viene chiamato Change Detection, grazie al quale &#8220;capisce&#8221; quando aggiornare l&#8217;interfaccia a fronte di un cambiamento di stato dell&#8217;applicazione.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Trovate molti articoli in rete che spiegano come funziona nel dettaglio questo meccanismo e come sfrutta zone.js per capire quando intervenire per aggiornare la UI, ma vorrei provare, con un esempio semplice, a evidenziare come questo meccanismo pu\u00f2 impattare sulle performance della nostra applicazione se non facciamo attenzione.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Partiamo da un semplice componente, in cui inseriamo una casella di testo in binding bidirezionale con una propriet\u00e0 del componente stesso. Quando digitiamo in questa casella un testo e premiamo invio, vogliamo pushare la stringa digitata all&#8217;interno di una semplice lista non ordinata, insieme a un numero tra 1 e 10 generato casualmente. Se vogliamo vedere a occhio nudo l&#8217;impatto che pu\u00f2 avere la change detection sulla user experience, dobbiamo per\u00f2 forzare un po&#8217; la mano.\u00a0Quindi, quando visualizzeremo l&#8217;elemento della lista, non ci limiteremo a stampare semplicemente il valore numerico, ma invocheremo un metodo, direttamente dall&#8217;espressione di binding, che calcoler\u00e0 dal valore originale, moltiplicato per 4, il corrispondente numero di Fibonacci:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nimport { Component } from &#039;@angular\/core&#039;;\n\u00a0\n@Component({\n\u00a0\u00a0selector: &#039;app-sample-list&#039;,\n\u00a0\u00a0templateUrl: &#039;.\/sample-list.component.html&#039;\n})\nexport class SampleListComponent {\n\u00a0\n\u00a0\u00a0text: string;\n\u00a0\u00a0items: {label: string, value: number}&#x5B;] = &#x5B;];\n\u00a0\n\u00a0\u00a0addTextToList() {\n\u00a0\u00a0\u00a0\u00a0const randomValue =\u00a0 Math.floor(Math.random() * 10) + 1;\n\u00a0\u00a0\u00a0\u00a0this.items.push({ label: this.text, value: randomValue });\n\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0generateValue(value: number) {\n\u00a0\u00a0\u00a0\u00a0console.log(&#039;value &#039; + value + &#039; generated&#039;);\n\u00a0\u00a0\u00a0\u00a0return this.fibonacci(value * 4);\n\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0private fibonacci(num: number): number {\n\u00a0\u00a0\u00a0\u00a0if (num === 1 || num === 2) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 1;\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0return this.fibonacci(num - 1) + this.fibonacci(num - 2);\n\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Reminiscenze del corso di informatica vi ricorderanno che calcolare un valore della sequenza di Fibonacci ha una complessit\u00e0 computazionale che cresce esponenzialmente al crescere del valore stesso. Ovviamente, questa implementazione \u00e8 solo un esempio, ma ci serve per esasperare il problema. Notate che nel codice non ho chiamato direttamente l&#8217;algoritmo, ma ho invocato un metodo che prima stampa in console una stringa e poi esegue il calcolo. Questo ci permette di vedere dalla console quante volte il metodo viene chiamato mentre interagiamo con l&#8217;interfaccia:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"372\" data-attachment-id=\"28706\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/attachment\/image1-5\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image1.gif?fit=640%2C372&amp;ssl=1\" data-orig-size=\"640,372\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image1\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image1.gif?fit=640%2C372&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image1.gif?resize=640%2C372&#038;ssl=1\" alt=\"\" class=\"wp-image-28706\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Come potete vedere dall&#8217;immagine, ogni volta che modificate il testo, la change detection richiama il metodo di calcolo per ogni elemento nella lista. Se provate a inserire un po&#8217; di elementi, vi accorgerete dopo un po&#8217; che la responsivit\u00e0 dell&#8217;applicazione si riduce visibilmente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Come possiamo intervenire per migliorare la situazione? Un primo approccio \u00e8 quello di riorganizzare il nostro componente esternalizzando la casella di testo, in modo che la lista da visualizzare venga passata in input al componente e non elaborata contestualmente. Nel nostro esempio, spostiamo in app-component il testo e la gestione della lista:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;input type=&quot;text&quot; &#x5B;(ngModel)]=&quot;text&quot; (keydown.enter)=&quot;addTextToList()&quot;&gt;\n&lt;app-sample-list &#x5B;items]=&quot;items&quot;&gt;&lt;\/app-sample-list&gt;\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nimport { Component } from &#039;@angular\/core&#039;;\n\u00a0\n@Component({\n\u00a0\u00a0selector: &#039;app-root&#039;,\n\u00a0\u00a0templateUrl: &#039;.\/app.component.html&#039;\n})\nexport class AppComponent {\n\u00a0\u00a0text: string;\n\u00a0\u00a0items: {label: string, value: number}&#x5B;] = &#x5B;];\n\u00a0\n\u00a0\u00a0addTextToList() {\n\u00a0\u00a0\u00a0\u00a0const randomValue =\u00a0 Math.floor(Math.random() * 10) + 1;\n\u00a0\u00a0\u00a0\u00a0this.items.push({ label: this.text, value: randomValue });\n\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Lasceremo nel componente lista solo la parte di calcolo della sequenza di Fibonacci. La change detection in Angular si propaga dal componente in cui stiamo interagendo a tutti i suoi figli, quindi, spostando la casella di testo nel componente padre, non risolviamo il problema. Possiamo per\u00f2 disabilitare la change detection nel componente lista, in modo che il valore non venga ricalcolato ogni volta. Potete fare questa cosa impostando la change detection strategy del componente nel suo decoratore. I valore possibili sono Default, il comportamente predefinito, e OnPush, con cui possiamo dire ad Angular che saremo noi a indicare quando eseguire il ciclo di aggiornamento dell&#8217;interfaccia. La cosa interessante \u00e8 che l&#8217;interruzione della change detection non si applica ai parametri di Input, quindi se il valore in Input cambia, l&#8217;interfaccia sar\u00e0 aggiornata:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nimport { Component, Input, ChangeDetectionStrategy } from &#039;@angular\/core&#039;;\n\u00a0\n@Component({\n\u00a0\u00a0selector: &#039;app-sample-list&#039;,\n\u00a0\u00a0templateUrl: &#039;.\/sample-list.component.html&#039;,\n\u00a0\u00a0changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SampleListComponent {\n\u00a0\n\u00a0\u00a0@Input()\n\u00a0\u00a0items: {label: string, value: number}&#x5B;] = &#x5B;];\n\u00a0\n\u00a0\u00a0generateValue(value: number) {\n\u00a0\u00a0\u00a0\u00a0console.log(&#039;value &#039; + value + &#039; generated&#039;);\n\u00a0\u00a0\u00a0\u00a0return this.fibonacci(value * 4);\n\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0private fibonacci(num: number): number {\n\u00a0\u00a0\u00a0\u00a0if (num === 1 || num === 2) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 1;\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0return this.fibonacci(num - 1) + this.fibonacci(num - 2);\n\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Eseguendo per\u00f2 questo codice l&#8217;applicazione smette di funzionare. Questo accade perch\u00e9\u00a0stiamo fornendo in input un array che cresce ad ogni inserimento, ma il riferimento all&#8217;array non cambia, quindi Angular non si accorge del cambiamento. Questo \u00e8 il momento in cui l&#8217;immutabilit\u00e0 ci risolve il problema. Come primo approccio, proviamo a ricreare l&#8217;array ogni volta che aggiungiamo un valore:\u00a0il modo pi\u00f9 stupido \u00e8 convertire l&#8217;array in una stringa e poi ritrasformarlo in un array:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\naddTextToList() {\n\u00a0\u00a0const randomValue =\u00a0 Math.floor(Math.random() * 10) + 1;\n\u00a0\u00a0this.items.push({ label: this.text, value: randomValue });\n\u00a0\u00a0this.items = JSON.parse(JSON.stringify(this.items));\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Brutto ma efficace. In questo modo potete vedere che la modifica al testo nella casella non scatena il ricalcolo dei valori della lista:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"372\" data-attachment-id=\"28710\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/attachment\/image2-1-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image2-1.gif?fit=640%2C372&amp;ssl=1\" data-orig-size=\"640,372\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image2-1\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image2-1.gif?fit=640%2C372&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image2-1.gif?resize=640%2C372&#038;ssl=1\" alt=\"\" class=\"wp-image-28710\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Questo approccio per\u00f2 ha il problema che l&#8217;operazione di ricreazione della lista ad ogni inserimento, oltre a essere scomodo, \u00e8 anche poco efficiente, sia in termini di tempo che di occupazione di memoria. Per risolvere questo ulteriore problema, possiamo utilizzare immutable.js (<a rel=\"noreferrer noopener\" href=\"https:\/\/immutable-js.github.io\/immutable-js\/\" target=\"_blank\">https:\/\/immutable-js.github.io\/immutable-js\/<\/a>), che fornisce tutti gli strumenti necessari a lavorare con oggetti immutabili ottimizzando le risorse. Potete facilmente installarlo con il solito\u00a0<strong>npm i immutable<\/strong>. A questo punto, possiamo utilizzare le liste immutabili invece del semplice array, che forniscono il metodo unshift per l&#8217;aggiunta di un nuovo elemento, il quale restituisce la nuova istanza dell&#8217;array.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nimport { Component } from &#039;@angular\/core&#039;;\nimport { List } from &#039;immutable&#039;;\n\u00a0\n@Component({\n\u00a0\u00a0selector: &#039;app-root&#039;,\n\u00a0\u00a0templateUrl: &#039;.\/app.component.html&#039;\n})\nexport class AppComponent {\n\u00a0\u00a0text: string;\n\u00a0\u00a0items = List&lt;{label: string, value: number}&gt;();\n\u00a0\n\u00a0\u00a0addTextToList() {\n\u00a0\u00a0\u00a0\u00a0const randomValue =\u00a0 Math.floor(Math.random() * 10) + 1;\n\u00a0\u00a0\u00a0\u00a0this.items = this.items.unshift({ label: this.text, value: randomValue });\n\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Questa libreria ottimizza le risorse creando una struttura dati in cui gli elementi gi\u00e0 presenti non vengono persi, ma riutilizzati nel nuovo array.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sfruttiamo adesso una caratteristica poco conosciuta delle Pipe di Angular. Creiamo una Pipe per calcolare la sequenza di Fibonacci invece di invocare il metodo del componente:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nimport { Pipe, PipeTransform } from &#039;@angular\/core&#039;;\n\u00a0\n@Pipe({\n\u00a0\u00a0name: &#039;fibonacci&#039;,\n\u00a0\u00a0pure: true\n})\nexport class FibonacciPipe implements PipeTransform {\n\u00a0\u00a0transform(value: any, ...args: any&#x5B;]): any {\n\u00a0\u00a0\u00a0\u00a0console.log(&#039;value &#039; + value + &#039; generated&#039;);\n\u00a0\u00a0\u00a0\u00a0return this.fibonacci(value * 4);\n\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0private fibonacci(num: number): number {\n\u00a0\u00a0\u00a0\u00a0if (num === 1 || num === 2) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 1;\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0return this.fibonacci(num - 1) + this.fibonacci(num - 2);\n\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Nel codice, ho esplicitato il valore di default del parametro\u00a0<strong>pure<\/strong>\u00a0della Pipe, che \u00e8 true. Questo significa che, se anche non esplicitamente detto come in questo caso, le Pipe sono trattate come funzioni pure, cio\u00e8 il risultato della loro elaborazione cambia solo se cambiano i parametri. Una Pipe pura in Angular non viene richiamata se i parametri non cambiano, dato che il risultato non cambier\u00e0. Questo ottimizza tantissimo il nostro codice, perch\u00e8 invocheremo la Pipe solo sui nuovi valori inseriti:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"372\" data-attachment-id=\"28713\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/attachment\/image3-5\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image3.gif?fit=640%2C372&amp;ssl=1\" data-orig-size=\"640,372\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image3\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image3.gif?fit=640%2C372&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image3.gif?resize=640%2C372&#038;ssl=1\" alt=\"\" class=\"wp-image-28713\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Se impostate il parametro\u00a0<strong>pure<\/strong>\u00a0a false, vedrete invece che Angular invocher\u00e0 ogni volta la Pipe. Anche lasciando la Pipe pura per\u00f2, non possiamo evitare che il valore venga calcolato per una nuova riga, nonostante i parametri possano coincidere con una riga differente. Se ci pensate, il valore n-simo della sequenza di Fibonacci \u00e8 sempre lo stesso, quindi, una volta calcolato, potremmo riutilizzarlo in tutti i casi in cui ci viene richiesto lo stesso valore. Angular non ha uno strumento integrato per questa funzionalit\u00e0, che non \u00e8 altro che una strategia di caching dei valori. Possiamo per\u00f2 installare una libreria che sa fare questa cosa, con il comando\u00a0<strong>npm i memo-decorator<\/strong>. La Pipe diventa la seguente:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nimport { Pipe, PipeTransform } from &#039;@angular\/core&#039;;\nimport memo from &#039;memo-decorator&#039;;\n\u00a0\n@Pipe({\n\u00a0\u00a0name: &#039;fibonacci&#039;\n})\nexport class FibonacciPipe implements PipeTransform {\n\u00a0\n\u00a0\u00a0@memo()\n\u00a0\u00a0transform(value: any, ...args: any&#x5B;]): any {\n\u00a0\u00a0\u00a0\u00a0console.log(&#039;value &#039; + value + &#039; generated&#039;);\n\u00a0\u00a0\u00a0\u00a0return this.fibonacci(value * 4);\n\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0private fibonacci(num: number): number {\n\u00a0\u00a0\u00a0\u00a0if (num === 1 || num === 2) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 1;\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0return this.fibonacci(num - 1) + this.fibonacci(num - 2);\n\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Aggiungendo il decoratore\u00a0<strong>memo<\/strong>\u00a0al metodo transform, andremo a salvare il risultato dell&#8217;elaborazione a parit\u00e0 di parametri, in modo da saltarne l&#8217;esecuzione per valori gi\u00e0 precedentemente calcolati:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"372\" data-attachment-id=\"28715\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/attachment\/image4-4\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image4.gif?fit=640%2C372&amp;ssl=1\" data-orig-size=\"640,372\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image4\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image4.gif?fit=640%2C372&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image4.gif?resize=640%2C372&#038;ssl=1\" alt=\"\" class=\"wp-image-28715\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Spero vi sia utile. Trovate il codice qui:<br><a href=\"https:\/\/github.com\/apomic80\/angular-performance-improvements\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/apomic80\/angular-performance-improvements<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Happy Coding!<\/p>\n\n\n\n\n","protected":false},"excerpt":{"rendered":"<p>Come migliorare le performance delle nostre applicazioni Angular usando le Pipe e disabilitando la Change Detection dove non serve.<\/p>\n","protected":false},"author":196716248,"featured_media":28703,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"","_et_gb_content_width":"","_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","_crdt_document":"","inline_featured_image":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"jetpack_post_was_ever_published":false},"categories":[688637374],"tags":[688637387],"class_list":["post-28702","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-angular"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Angular Performance Improvements - Blexin<\/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:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Angular Performance Improvements - Blexin\" \/>\n<meta property=\"og:description\" content=\"Come migliorare le performance delle nostre applicazioni Angular usando le Pipe e disabilitando la Change Detection dove non serve.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/\" \/>\n<meta property=\"og:site_name\" content=\"Blexin\" \/>\n<meta property=\"article:published_time\" content=\"2019-04-24T20:13:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-01-13T08:40:37+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ccc34bfb-ebde-488d-873c-6195df9b513b.png?fit=1024%2C608&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"608\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Michele Aponte\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Scritto da\" \/>\n\t<meta name=\"twitter:data1\" content=\"Michele Aponte\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minuti\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/angular-performance-improvements\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/angular-performance-improvements\\\/\"},\"author\":{\"name\":\"Michele Aponte\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#\\\/schema\\\/person\\\/cdc5540c3b6edcacd8d760669e797005\"},\"headline\":\"Angular Performance Improvements\",\"datePublished\":\"2019-04-24T20:13:00+00:00\",\"dateModified\":\"2021-01-13T08:40:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/angular-performance-improvements\\\/\"},\"wordCount\":1026,\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/angular-performance-improvements\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/ccc34bfb-ebde-488d-873c-6195df9b513b.png?fit=1024%2C608&ssl=1\",\"keywords\":[\"Angular\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"it-IT\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/angular-performance-improvements\\\/\",\"url\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/angular-performance-improvements\\\/\",\"name\":\"Angular Performance Improvements - Blexin\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/angular-performance-improvements\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/angular-performance-improvements\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/ccc34bfb-ebde-488d-873c-6195df9b513b.png?fit=1024%2C608&ssl=1\",\"datePublished\":\"2019-04-24T20:13:00+00:00\",\"dateModified\":\"2021-01-13T08:40:37+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#\\\/schema\\\/person\\\/cdc5540c3b6edcacd8d760669e797005\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/angular-performance-improvements\\\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/angular-performance-improvements\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/angular-performance-improvements\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/ccc34bfb-ebde-488d-873c-6195df9b513b.png?fit=1024%2C608&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/ccc34bfb-ebde-488d-873c-6195df9b513b.png?fit=1024%2C608&ssl=1\",\"width\":1024,\"height\":608},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/angular-performance-improvements\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/blexin.com\\\/it\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Angular Performance Improvements\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#website\",\"url\":\"https:\\\/\\\/blexin.com\\\/it\\\/\",\"name\":\"Blexin\",\"description\":\"Con noi \u00e8 semplice\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/blexin.com\\\/it\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"it-IT\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#\\\/schema\\\/person\\\/cdc5540c3b6edcacd8d760669e797005\",\"name\":\"Michele Aponte\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g\",\"caption\":\"Michele Aponte\"},\"url\":\"https:\\\/\\\/blexin.com\\\/it\\\/author\\\/michele-aponteblexin-com\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Angular Performance Improvements - Blexin","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:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/","og_locale":"it_IT","og_type":"article","og_title":"Angular Performance Improvements - Blexin","og_description":"Come migliorare le performance delle nostre applicazioni Angular usando le Pipe e disabilitando la Change Detection dove non serve.","og_url":"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/","og_site_name":"Blexin","article_published_time":"2019-04-24T20:13:00+00:00","article_modified_time":"2021-01-13T08:40:37+00:00","og_image":[{"width":1024,"height":608,"url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ccc34bfb-ebde-488d-873c-6195df9b513b.png?fit=1024%2C608&ssl=1","type":"image\/png"}],"author":"Michele Aponte","twitter_card":"summary_large_image","twitter_misc":{"Scritto da":"Michele Aponte","Tempo di lettura stimato":"7 minuti"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/#article","isPartOf":{"@id":"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/"},"author":{"name":"Michele Aponte","@id":"https:\/\/blexin.com\/it\/#\/schema\/person\/cdc5540c3b6edcacd8d760669e797005"},"headline":"Angular Performance Improvements","datePublished":"2019-04-24T20:13:00+00:00","dateModified":"2021-01-13T08:40:37+00:00","mainEntityOfPage":{"@id":"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/"},"wordCount":1026,"image":{"@id":"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ccc34bfb-ebde-488d-873c-6195df9b513b.png?fit=1024%2C608&ssl=1","keywords":["Angular"],"articleSection":["Blog"],"inLanguage":"it-IT"},{"@type":"WebPage","@id":"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/","url":"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/","name":"Angular Performance Improvements - Blexin","isPartOf":{"@id":"https:\/\/blexin.com\/it\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/#primaryimage"},"image":{"@id":"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ccc34bfb-ebde-488d-873c-6195df9b513b.png?fit=1024%2C608&ssl=1","datePublished":"2019-04-24T20:13:00+00:00","dateModified":"2021-01-13T08:40:37+00:00","author":{"@id":"https:\/\/blexin.com\/it\/#\/schema\/person\/cdc5540c3b6edcacd8d760669e797005"},"breadcrumb":{"@id":"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/"]}]},{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/#primaryimage","url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ccc34bfb-ebde-488d-873c-6195df9b513b.png?fit=1024%2C608&ssl=1","contentUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ccc34bfb-ebde-488d-873c-6195df9b513b.png?fit=1024%2C608&ssl=1","width":1024,"height":608},{"@type":"BreadcrumbList","@id":"https:\/\/blexin.com\/it\/blog\/angular-performance-improvements\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blexin.com\/it\/"},{"@type":"ListItem","position":2,"name":"Angular Performance Improvements"}]},{"@type":"WebSite","@id":"https:\/\/blexin.com\/it\/#website","url":"https:\/\/blexin.com\/it\/","name":"Blexin","description":"Con noi \u00e8 semplice","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blexin.com\/it\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"it-IT"},{"@type":"Person","@id":"https:\/\/blexin.com\/it\/#\/schema\/person\/cdc5540c3b6edcacd8d760669e797005","name":"Michele Aponte","image":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/secure.gravatar.com\/avatar\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g","caption":"Michele Aponte"},"url":"https:\/\/blexin.com\/it\/author\/michele-aponteblexin-com\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ccc34bfb-ebde-488d-873c-6195df9b513b.png?fit=1024%2C608&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/pcyUBx-7sW","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts\/28702","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/users\/196716248"}],"replies":[{"embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/comments?post=28702"}],"version-history":[{"count":6,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts\/28702\/revisions"}],"predecessor-version":[{"id":28718,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts\/28702\/revisions\/28718"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/media\/28703"}],"wp:attachment":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/media?parent=28702"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/categories?post=28702"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/tags?post=28702"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}