AngularJS Best Practices - About Nitor Infotech
←
→
Page content transcription
If your browser does not render page correctly, please read the page content below
AngularJS Best Practices About Nitor Infotech Nitor Infotech is an Information Technology company specialized in providing Product Engineering
Overview AngularJS based client side development is becoming a norm in modern enterprise web application development. AngularJS has provided following value to the development: Faster development: Framework features such as two way binding allows you to do lot of operations in fewer lines Maintainable: Object oriented design helps software become maintainable. AngularJS focuses on Model as source of truth. This means we can think of using object oriented design principles to make software maintainable. AngularJS focuses on MVW (Model- View-Whatever) pattern which is a preferred UI pattern among developers Re-usability: Templates feature allows re-usability of HTML views. Using of directives help create custom DOM elements promoting re-usability across your applications Testability: AngularJS supports dependency injection which is a core principle to testing. API support for server communication Deep linking: State of Application can be referred thru a unique URL, hence flexibility to retrieve the state easily This article focuses on various best practices and performance related considerations, which needs to be considered while developing. This document will help beginners and intermediate experienced developers to gain knowledge and improve their code quality. Note: Most of the best practices mentioned are valid from AngularJS 1.2 or above. The Best practices mentioned are categorized in to below 3 categories: Improve Re-usability Improve Performance Improve Scalability and Maintainability Re-usability Best Practices will focus on different AngularJS features which will help promote re-usability across your angular app. Performance Best Practices will focus on different considerations a developer need to take to ensure that un-necessary performance bottlenecks is not created. Scalability and Maintainability Best Practices will help developers to write better quality code which is easily maintainable as well as avoid potential issues as the code grows. Confidential | Nitor InfoTech | www.nitorinfotech.com Page |1
Best Practices: To help improve re-usability Defer Controller logic to Services: Business logic, validation logic and any other binding related code is written in Controller of the AngularJS. There is often situations when the controller logic needs to be re-used. By using “Services” feature of AngularJS along with dependency injection, one could make sure that it is re-used across different controllers. Refactoring at later stage can be costly, hence identifying re-usable code and moving to “Services” will improve quality of development. $http and $resource are two popular in-built services provided by AngularJS. Refer https://docs.angularjs.org/guide/services for more details. Defer Views to Templates: HTML snippets within a view which have re-usable value can be moved to templates. Using $routeProvider one could easily configure routes on which the templates along with controller to be called. For e.g.: Consider an ERP application where you need to search for vendor code in various modules of the application. Vendor search view can be developed as Template which could be called upon in any other module. Directives: Using of directives will help you add behavior or transform the DOM element as you need. A simple e.g.: is using of Calendar control across your application. By creating a Directive ng- calendar and attaching the calendar behavior to it will ensure any DOM element showing calendar control. Refer https://docs.angularjs.org/guide/directive for more details: Module: Use Angular Module, you could create namespaces and containerize each of the components. For e.g.: Data Services related components can be built as separate module. They can be injected as dependency wherever required. Confidential | Nitor InfoTech | www.nitorinfotech.com Page |2
Best Practices: Improve Performance AngularJS performance improvements has been improving as the newer versions get released. However, there are some best practices developers need to know. If not followed, could lead to performance bottlenecks by making DOM heavy or Angular processing slow. Destroy your Directives Make sure when Directives are used, it’s destroyed. Directives often are left floating and result in heavy DOM. Using $destroy on scope will make sure the directives are destroyed. Minimize or avoid using $watchers Each time Model is updated, either through user input in view or service input to controller, Angular $digest cycle iterates thru entire bindings and checks for values which changed. More data bindings will result in increase of $watchers and $scope objects which will slow down the $digest cycles. Hence it is important that we optimize on our data bindings to reduce dirty checking cycles. Use track by in ng-repeat Every time the model (List of objects or array) against which the ng-repeat is bound is refreshed, angular removes the DOM elements and re-binds everything. However, in reality the model bound may have only few rows that are newly added. Re-binding the entire DOM is expensive. By using “track by” along with ng-repeat, only the rows which are added will get rebind in DOM. Use “limitTo” with ng-repeat While creating a grid using ng-repeat, try to restrict the results to be bind using “limitTo” filter expression. Adding pagination by using this filter will help in avoiding heavy DOM. Use Bind once with one-time expression (“::”) Each time Model is updated, all the expressions in view is recalculated. With increasing two- way databinding’s these re-calculations can add to the performance overhead. By using one-time expression, we can avoid such re-calculations. Use caching with $http Whenever dealing with services, try to use “cache” option of $http. This will ensure that similar requests is fetched from cache rather than hitting the server. In case the default cache needs to be extended, we could use $cacheFactory and implement the same. Use ng-model-options for controlling how the model updates are done There are use cases where-in the model updates (in 2-way data binding scenario) needn’t be real time. For e.g.: As the user is entering the value in a text control, simultaneous update on model doesn’t make sense. Probably, when the focus is out it makes sense to update the Model. Such strategies will reduce the $digest cycles and hence improve performance. Some of the popular ng-model-options that can come handy are: “updateOn” Confidential | Nitor InfoTech | www.nitorinfotech.com Page |3
and “debounce”. “updateOn” allows you to specify event on which the input be bound to. “debounce” allows you to specify milliseconds value after which the model be updated. Refer https://docs.angularjs.org/api/ng/directive/ngModelOptions for more details. ng-if instead of ng-show Whenever dealing with hide/show feature, its better to use “ng-if” rather than “ng-show”. The reason being “ng-if” when evaluated to false will remove the DOM elements that it supposed to show, whereas “ng-show” makes the display none. If there are significant number of show/hide modules within a view, “ng-if” will ensure that DOM is not heavy. Avoid ng-repeat if possible With each iteration of ng-repeat, new child scope gets created. With increasing scopes, the watchers list also increase. Hence, use of ng-repeat to be validated well before using it. For e.g.: if the requirement is to display a static grid, we can avoid using ng-repeat and instead use static html and render the same. Use filtering in JS instead of DOM filters Applying filters at the controller level will improve performance compared to adding filter at DOM level. Filter at DOM level will result in dealing with the entire result set, whereas filter at JS level would trim the result set hence the rendered DOM will be lighter. Avoid Server calls within a loop There are situations when lookup values need to be populated against each of the property in loop. Calling server side API and doing the same can be costly from performance point of view, instead modifying the original API to accommodate the values will be better Dealing with large result set Use native JS or Lodash library functions instead of angular functions for operations such as like, foreach, copy, isDefined etc. It has been proven that Lodash libraries perform better compared to angular functions. Check out https://jsperf.com/angular-foreach-vs-native-for- loop/29 for some proof. Use ng-bind instead of “{{ }}” Any model represented using “{{ }}” will have expression calculated every time any other model value changes. Ng-bind will ensure that expression is calculated only if the corresponding model is updated. Use ng-style over ng-class Ng-style has proved to be much faster than ng-class. Check out http://ng- perf.com/2014/10/29/tip-3-ng-style-is-much-faster-than-ng-class/ for more details. Make sure debug code is suppressed in production Ensure following code snippet to make sure any stray debug calls is disabled. app.config(function($compileProvider){$compileProvider.debugInfoEnabled(false)}); Confidential | Nitor InfoTech | www.nitorinfotech.com Page |4
Best Practices: Improve Scalability and maintainability Exception Handling Angular provides a built-in global exception handling service called $exceptionHandler. Its features are: 1. All uncaught exceptions are handled by this service 2. Logs any exception to the browser console 3. Customizable for messages or any other behavior Wrap AngularJS components in IIFE Wrapping AngularJS components in an IIFE (Immediately Invoked Function Expression) prevents variables and function declarations from colliding with other variables. Use Named functions not anonymous By using Named functions, the code will be readable, re-usable and easier to debug as well. Anonymous function help you code faster but trades off with above mentioned pointers. Avoid function expression to avoid hoisting issues JavaScript hoisting feature ensures that JavaScript variables or functions are moved to the top of the current scope. Function expression prevents from enabling this feature. Use Bindable members at Top to improve readability As a best practice, we would advise to declare the bind able members at the top of the scope. This will ensure readability is better. Use Promise pattern to avoid Callback Hell Chaining of multiple asynchronous processes is tricky and leads to too much of nesting callbacks and calls in each other. By using promise pattern ($q service) we can avoid callback hell. Use Bower for dependency management Bower works by fetching and installing packages from all over, taking care of hunting, finding, downloading, and saving the stuff you’re looking for. Bower will ensure right version of a particular package is picked up. Refer http://bower.io/ for more details. Use ControllerAs syntax in View with model Situations where nested scopes are used result in model value conflicts. By using “ControllerAs” we can create namespace to each controller defined. Hence every model bind in view will be referred as “namespace.model”. This will ensure no model value conflict happens. Confidential | Nitor InfoTech | www.nitorinfotech.com Page |5
Min safe dependency injection using “[ ]” syntax. If not, use ng-annotate with gulp or grunt. Also can use $inject. While developing not many developers think of minification errors. Post minification, the dependencies passed as argument to a controller is re-worded and results in “not found” errors. One of the popular technique is using ng-annotate with gulp or grunt. This will ensure $inject annotation is added which will ensure the scripts are minification safe. Another popular technique is displaying all the dependencies as an array of string. This will ensure all the dependencies are not affected by minification. Use JSHint to help better code Using of JSHint will give detailed compile time errors hence increase your efficiency. Check out http://jshint.com/ for more details. Use JSDoc for documentation Code documentation is a good practice. Use JSDoc one could annonate JS source code files. Later on when you need comprehensive documentation describing your code, you can always use different tools which will generate the HTML or RTF file based on the JSDoc comments. Confidential | Nitor InfoTech | www.nitorinfotech.com Page |6
Conclusion The Best practices aids smooth development and optimal efficiency. It also helps beginners in developing AngularJS based App. In further release, we will discuss more about Unit testing with AngularJS. About Nitor Infotech Nitor specializes in IT engineering management practices such as Product Engineering, Data Engineering and Business Intelligence, Enterprise Mobility and Business Quality Assurance (Testing) services. Our track record boasts of creating world class products and services with cutting edge technologies across domains. Our DNA has been two fold – Business Excellence and Innovation. With almost a decade of industry and technology expertise, we nurture and grow our customers across our 4 defined categories – Funded Start-ups, Growing, Transforming and Matured. We are strategic business growth partners for funded start-ups to matured ones – delivering solutions from rapid prototyping to expeditionary go-to-market with business consulting and technological implementation. For enquiries, please write to us at: info@nitorinfotech.com For any additional details, please refer our website: www.nitorinfotech.com Confidential | Nitor InfoTech | www.nitorinfotech.com Page |7
You can also read