{"id":99,"date":"2018-05-07T17:56:05","date_gmt":"2018-05-07T17:56:05","guid":{"rendered":"http:\/\/www.bullcrane.com\/angular\/?p=99"},"modified":"2018-06-25T16:18:57","modified_gmt":"2018-06-25T16:18:57","slug":"flex-layout-performance-solution","status":"publish","type":"post","link":"http:\/\/www.bullcrane.com\/angular\/2018\/05\/07\/flex-layout-performance-solution\/","title":{"rendered":"Flex-layout performance solution"},"content":{"rendered":"<p>In my <a href=\"http:\/\/www.bullcrane.com\/angular\/2018\/05\/01\/flex-layout-performance-problem\/\">previous blog post<\/a>, I described a performance problem with the special responsive features of the Angular flex-layout module.\u00a0 Combined use of fxShow and fxHide was killing my app&#8217;s performance.\u00a0 Example:<\/p>\n<pre>&lt;button mat-button fxHide=\"true\" fxShow.gt-sm=\"true\"<\/pre>\n<p>As I studied the documentation more I learned that the above syntax is overkill.\u00a0 The following is easier and does the same thing:<\/p>\n<pre>&lt;button mat-button fxHide fxShow.gt-sm<\/pre>\n<p>This simplification makes no difference in performance, however.<\/p>\n<p>The <em>.gt-sm<\/em> means &#8220;when greater than small.&#8221;\u00a0 A few HTML tags like this one don&#8217;t hurt, but I might have a few thousand, generated by an ngFor.<\/p>\n<h6>Solution:\u00a0 go imperative &#8211; use flex-layout&#8217;s ObservableMedia<\/h6>\n<p>The &#8220;dot&#8221; modifiers like the <em>.gt-sm<\/em> shown above are known as <em>mediaQuery alias suffixes.\u00a0\u00a0<\/em> While they are one of the main attractions of the flex-layout module&#8217;s\u00a0<em>responsive API, <\/em>I got rid of them all.\u00a0 Eventually I went ahead and removed the <em>static API <\/em>also.<\/p>\n<pre>&lt;button mat-button <del>fxHide<\/del> <del>fxShow.gt-sm\r\n<\/del>                      ^     ^\r\n                      |     |\r\nremove static API ----+     +--- remove responsive API<\/pre>\n<p>I put in flex-layout&#8217;s way of checking mediaQuery changes, the <em>isActive<\/em> method of the <a href=\"https:\/\/github.com\/angular\/flex-layout\/wiki\/ObservableMedia\">ObservableMedia<\/a> service.\u00a0 This is in my main <em>app.component.ts.<\/em>\u00a0 Here are the relevant parts:<\/p>\n<pre>import { ObservableMedia } from '@angular\/flex-layout';\r\n...\r\nconstructor (\r\n public media: ObservableMedia,\r\n...\r\nsizeNum: Object = {'PHONE':1,'TABLET':2,'HD':3}\r\nactiveSize(): number {\r\n if (this.media.<span style=\"color: #ff0000;\">isActive('xs')<\/span>) {return this.sizeNum['PHONE'];}\r\n if (this.media.<span style=\"color: #ff0000;\">isActive('sm')<\/span>) {return this.sizeNum['TABLET'];}\r\n else {return this.sizeNum['HD'];}\r\n }<\/pre>\n<p>Now I can use ngIf in my html:<\/p>\n<pre>&lt;button mat-button *ngIf=\"activeSize()&gt;=sizeNum['HD']\"<\/pre>\n<p>In addition to implementing show\/hide logic, I also was using mediaQuery alias suffixes on ngClass.\u00a0 Now I am doing this instead:<\/p>\n<p>TypeScript<\/p>\n<pre>classList(size:number): string[] {\r\n  if (size&gt;=this.sizeNum['HD'])          {return ['small']}\r\n  else if (size&gt;=this.sizeNum['TABLET']) {return ['tiny']}\r\n  else                                   {return ['nano']}\r\n  }<\/pre>\n<p>HTML<\/p>\n<pre>&lt;img [src]=\"songImgUrl()\"\r\n  class=\"rounded\"\r\n  [ngClass]=\"classList(activeSize())\"<\/pre>\n<h6>Conclusion<\/h6>\n<p>The turning point was removing the responsive API directives.\u00a0 That restored the performance but I had some constructs like this:<\/p>\n<pre>&lt;button mat-button [fxShow]=\"activeSize()&gt;=sizeNum['HD']\"<\/pre>\n<p>This is the same thing as Angular&#8217;s stock <em>ngIf.\u00a0 <\/em>So I decided to switch everything to native Angular DOM directives and use only the <em>ObservableMedia <\/em>from <em>flex-layout.\u00a0 <\/em>I am satisfied with this solution because:<\/p>\n<ul>\n<li>the performance is fully restored<\/li>\n<li>it&#8217;s almost entirely stock Angular<\/li>\n<li>it&#8217;s clear that I am setting up just three breakpoints<\/li>\n<li>it still taps into, rather than duplicates, the Material Design breakpoints<\/li>\n<\/ul>\n<p>[25-Jun-2018 I can do constants better now.  See <a href=\".\/2018\/06\/25\/global-constants\/\">global constants<\/a>.]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my previous blog post, I described a performance problem with the special responsive features of the Angular flex-layout module.\u00a0 Combined use of fxShow and fxHide was killing my app&#8217;s performance.\u00a0 Example: &lt;button mat-button fxHide=&#8221;true&#8221; fxShow.gt-sm=&#8221;true&#8221; As I studied the documentation more I learned that the above syntax is overkill.\u00a0 The following is easier and &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/www.bullcrane.com\/angular\/2018\/05\/07\/flex-layout-performance-solution\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Flex-layout performance solution&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[5],"tags":[],"_links":{"self":[{"href":"http:\/\/www.bullcrane.com\/angular\/wp-json\/wp\/v2\/posts\/99"}],"collection":[{"href":"http:\/\/www.bullcrane.com\/angular\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.bullcrane.com\/angular\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.bullcrane.com\/angular\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.bullcrane.com\/angular\/wp-json\/wp\/v2\/comments?post=99"}],"version-history":[{"count":18,"href":"http:\/\/www.bullcrane.com\/angular\/wp-json\/wp\/v2\/posts\/99\/revisions"}],"predecessor-version":[{"id":305,"href":"http:\/\/www.bullcrane.com\/angular\/wp-json\/wp\/v2\/posts\/99\/revisions\/305"}],"wp:attachment":[{"href":"http:\/\/www.bullcrane.com\/angular\/wp-json\/wp\/v2\/media?parent=99"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.bullcrane.com\/angular\/wp-json\/wp\/v2\/categories?post=99"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.bullcrane.com\/angular\/wp-json\/wp\/v2\/tags?post=99"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}