Angular Performance Optimization

14 Angular Performance Optimization Techniques and Tips to follow

The response time of a highly scalable mobile and desktop web application plays a vital role in holding visitors, who can be potential customers. Reports suggest that if a sophisticated application solution  does not load in up to 3 seconds, the user tends to drift away to the competitors’ choice available. And this can probably be a loss to your business.

Isn’t it?

Therefore, it becomes imperative to optimize the performance of your customer-facing mobile and web application across devices. AngularJS is a common ingredient that many strategic technology partners swear by when working on the front-end developments and single page performant applications.

The Complete Angular Performance Guide For 2021: ways to speed up AngularJS apps
 

Angular, a widely used JavaScript framework, is well suited to build business applications that are responsive and offer an intuitive experience to users. However, sometimes developers end up doing things that lead to low-performing applications. In order to improve the performance of your Angular-based business applications, optimization is important. 

Angular performance optimization techniques are the best way to find the performance bottlenecks in your Angular application and speed up the performance so that the Angular app loads faster every time. Mentioned below are some of the tips and tricks that the organizations must follow to optimize the performance of Angular applications. You can implement these AngularJS performance optimization tricks at all levels including code, build, and server-level. 

Let’s delve deeper into the Angular Performance Guide For 2021:

1. Angular Command Line Interface (CLI)

Angular CLI is a tool that uses bundling and limited tree-shaking to reduce the fragmentation of Angular code to zero. It offers various options while generating the build for the production environment. A regular update of Angular CLI allows access to the advanced methods of fixing bugs and updates of security features.

2. Tree-shaking

Tree-shaking supports the creation of smaller build sizes by eliminating unused codes. It is enabled by default in case you are using Angular CLI.

3. JIT (Just-in-Time) Compilation

JIT supports the compilation of one file at a time using a different set of libraries. The compilation of applications in JIT takes place within the browser and during the runtime. 

4. AOT (Ahead-of-Time) Compilation

AOT is one more way of compiling applications, but it is different from JIT. In AOT, the compiler runs once at the build time using any set of libraries. This process to compile applications was introduced in Angular 4.X but was enforced after Angular 5.X. In Angular 5.X and Angular 6.X, AOT compilation is automatic and there is no need for the use of —aot flag.

5. Prod Flag

meta flag --prod automatically calls --aot in case of Angular 5.X and 6.X. Here, it is to be noted that Angular 2 and Angular 4 uses a meta flag --prod to make small-size builds. However, we can also use --aot meta flag to reduce the build size.

6. UglifyJS and Build Optimizer Flag 

The meta flag --prod uses UglifyJS (a JavaScript compressor) for limited dead code elimination. UglifyJS is the process where a smaller build size is created using code transformations. It removes white spaces, comments, and more to optimize Angular. 

7. Build Optimizer and Vendor-Chunk 

The two meta flags --build-optimizer and --vendor-chunk optimize the Angular build. When using Angular CLI, you have to make sure that the “Build Optimizer” flag is specified as it will disable the vendor chunk and will reduce the size of the application. It is to be noted that the meta flag -vendor-chunk is set to false by default, but it can be changed by using --vendor-chunk=true.

8. Package.json

The file called package.json has all the dependencies that are needed to run the project. It can be run using simple commands like ‘npm run build’, ‘npm run test,’ and more. These commands can work in series and are mentioned in the scripts tag. The scripts section of the package.json file also includes custom scripts that can run once the build is made. It should be noted that the package.json file is automatically created when a new Angular project is started.

After Angular CLI has completed the build process, we get four JS files. These JS files can be reduced in size and concatenated into one single JS file. Since Angular works on component approach, we can call these files asynchronously, but by default in index.html, these files are called synchronously. This increases the initial page load time of an Angular application, which results in reduced page speed, gtmetrix, and yslow score. To improve this score, these Javascript files need to be called in an asynchronous mode.

9. Third-Party Tools 

Third-party tools such as GRUNT and GULP can be used to call the javascript files asynchronously to make the build files small and improve the Angular app performance. By calling the four JS files in an asynchronous mode, the page speed score can be increased by at least 70%. But to achieve a better score and improve the performance, improvement of the CSS delivery is necessary. CSS delivery can be improved by using media option in the link tag, as in the following: 

<link type="text/css" href="cssForMobile.css" rel="stylesheet" media=”(max-width: 600px)” >

The above-mentioned CSS file will only load for screen sizes with a maximum width of 600p and screen width higher than 600px.

Using type=”text/css” you can improve the CSS content delivery.

Here is a sample Gruntfile.js that can be used to make builds smaller and call JS files asynchronously.

module.exports = function(grunt) {
 grunt.initConfig({
   pkg: grunt.file.readJSON('package.json'),
   uglify: {
     dist: {
       files: {
         'dist/inline.bundle.js': ['dist/inline.*.bundle.js'],
         'dist/main.bundle.js': ['dist/main.*.bundle.js'],

         'dist/polyfills.bundle.js': ['dist/polyfills.*.bundle.js'],

         'dist/scripts.bundle.js': ['dist/scripts.*.bundle.js']
       }
     }
   },
   'string-replace': {
     dist: {
       files: [{
         expand: true,
         cwd: 'dist/',
         src: 'index.html',
         dest: 'dist/'
       }],
       options: {
         replacements: [{
           pattern: /<script type=/g,
           replacement: '<script async type='
         },{
           pattern: /inline.*.bundle.js/g,
           replacement: 'inline.bundle.js'
         },{
           pattern: /polyfills.*.bundle.js/g,
           replacement: 'polyfills.bundle.js'
         },{
           pattern: /scripts.*.bundle.js/g,
           replacement: 'scripts.bundle.js'
         },{
           pattern: /main.*.bundle.js/g,
           replacement: 'main.bundle.js'
         },
         {
           pattern: /<link/g,
           replacement: '<link type="text/css"'
         },
       ]
       }
      
     }
   },
   prettify: {
     options: {
       indent: 2,
       indent_char: ' ',
       wrap_line_length: 78,
       brace_style: 'expand'
     },
     one: {
       src: 'dist/index.html',
       dest: 'dist/index.html'
     }
   },
   htmlmin: {                                     
     dist: {                                      
       options: {                                 
         removeComments: true,
         collapseWhitespace: true
       },
       files: {                                   
         'dist/index.html': 'dist/index.html'
       }
     }
   }
 });
 grunt.loadNpmTasks('grunt-contrib-uglify-es');
 grunt.loadNpmTasks('grunt-string-replace');
 grunt.loadNpmTasks('grunt-prettify');
 grunt.loadNpmTasks('grunt-contrib-htmlmin');
 grunt.registerTask('build', ['uglify', 'prettify', 'string-replace', 'htmlmin']);
};

Although these tasks can be performed using “grunt build” command, this command can also be included in the package.json file so that Gruntfile is executed automatically and the best build is obtained by just using one command. 

Following is a sample for script tag in the package.json file:

"build": "run-s build:client, build:grunt",
   "build:client": "ng build --prod --build-optimizer",
   "build:grunt": "grunt build",

Use these commands in the script tag of package.json file and Grunt will allow it to work automatically.

10. htaccess file

After the build process, the improvement of content delivery of all the related resources is necessary. This can be managed on server level using .htaccess file. In .htaccess file, the following modules need to be provided to increase page speed, gtmetrix score, and yslow score:

  • Mod_expires
  • Mod_headers
  • Mod_deflate
  • Mod_gzip

The .htaccess file must be placed in the document root folder for the Apache to read it. Please note that .htaccess file is only used by Apache. If nginx is being used then there is a separate conf file that works on the same principle.

Apps made using Angular 2, 4, 5, 6 and 8 can be deployed using an Apache server, but if Universal Angular is being used then a Node server needs to be used. PM2 is a tool that manages various node servers. It works simultaneously with the Apache, and hence, .htaccess can be applied for universal Angular applications too.

Optimizing the project performance is an uphill battle. However, knowing where to begin when performance issues are identified is an intimidating task.

11. TrackBy and ngFor Directives

As we all know, the AngularJS framework is backed by a library called Zone.js that happens to trigger change detection every time a DOM event occurs. The *ngFor directive holds greater potential for performance optimization of the Angular app when used correctly with the TrackBy feature. In the AngularJS 8 ecosystem, the TrackBy option is best utilized to track incoming data every time requested from an API whereas the *ngFor, which is a structural directive used for rendering an array of iterable objects. The developers use *ngFor to create and manipulate the DOM by adding and removing DOM elements.

12. Lazy Loading

Any large application with many routes can rely on Angular lazy loading. This feature module offers significant performance improvements by creating a design pattern to load components, modules, and other NgModules assets only when a specific route is activated. Lazy loading prevents unnecessary loading of libraries or modules by keeping the bundle size small. Better responsiveness, reduced initial load time, bandwidth conservation, and resource optimization are vital benefits of using lazy loading routes in an Angular application.  

13. Pure Pipes

Pure Pipes are one of the most imperative features in Angular utilized for simple transformation of data or values in an Angular application. The core functionality working behind the default pure pipe is quite simple - if the value mentioned is incorrect, it enables an application to consider a default value instead. The built-in pure pipes are typically used to transform strings, currency amounts, dates, and other data. The successful adoption of Angular pure pipes helps in improving code readability across an Angular template.    

14. ChangeDetectionStrategy.OnPush

As the name explains itself, change detection is a component in the AngularJS framework that tracks every time there's a change in the Angular application. The OnPush change detection strategy reacts to triggered changes in the given @input parameters. It plays a vital role in the Angular 8 performance optimization by quickly disabling CD to run on a component and its children.

    enum ChangeDetectionStrategy {
        OnPush: 0
        Default: 1
    }

Wrapping Up

Optimizing the project performance is an uphill battle. However, knowing where to begin when performance issues are identified is an intimidating task. This creates an urgency to leverage the best angularjs development company to streamline the Angular Performance Optimization journey. Outsourcing AngularJS Development Services will provide access to a team of competent AngularJS developers ensuring the smooth deployment in an enterprise-level environment while adhering to the highest quality standards.