AngularJS Best Practices - About Nitor Infotech

Page created by Seth Howell
 
CONTINUE READING
AngularJS Best Practices - About Nitor Infotech
AngularJS Best Practices
  About Nitor Infotech
  Nitor Infotech is an Information Technology company specialized in providing Product Engineering
AngularJS Best Practices - About Nitor Infotech
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