Advanced AngularJS - Performance & Scaling & APIs & Progressive Saving

 AngularJS Performance

Tools
    1) use AngularJSBatarang - chrome extension
    2) Google Developer Tools Profiler (but must disable minification)
    3) performance.now()


Problems
    Javascript Problems
        slow DOM
        Single threaded
    Inefficient directives
        link vs compile
         $parse vs $eval vs interpolation
        Dirty Checking
        lots of watchers
        slow watchers
        too many calls to $apply

    When directive appears inside of a repeater
        compile is called only once
        link and constructor called once per iteration
    When create directive, do as much as possible in compile


    Directives: Transclusion
        for directives that wrap other content
        allows your directive to $digest its own scope without dirty checks on bindings

    Favor $apply
        use $apply
        has special error handling

    Watchers
        if argument to watcher is done many many times
        $watch = 2 comparision modes:
            referential (default) - quick, shallow compare
            deep comparision - slow, deep compare - obviously avoid

    $watchCollection
        goes 1 level deep
        better than deep watcher

    $eval, $parse and $interpolate
        better to call $parse once and save function rather than call $eval many times
        $parse is faster than $interpolate

    $watch before transforming, not after
        
    ng=repeat - track by $index
        reuses dom nodes

    ng-if vs. ng-show
        ng-if is better if not show because it not even create them so fewer bindings and fewer linkers called at startup

    $$postDigest
        Not really a best practive

    avoid dirty checking if possible by using custom directives

    ng-bind
        do not use if can use:
        fast bind on notify
        fast bind once


=========================================

AngularJS - How to scale

Kendo - for Background then Knockout then Angular
   Require.js
    Don't build directives if you don't need to
    Leverage Metadata
        Use Angular Responsibly

=========================================


MEAN (MongoDB, ExpressJS, AngularJS, and Node.js)

You can write your entire stack in one language.

Competing packages:
http://mean.io
http://meanjs.org


=========================================

** AUTHENICATION AND CONDITIONAL FEATURE LOADING **

A proposal to do conditional feature loading
https://gist.github.com/idosela/8421332

video of speech:
https://www.youtube.com/watch?v=62RvRQuMVyg

=========================================

Code Organization:
1) Inheritance = problem if too deep
    http://jsfiddle.net/3dPpK/9/

2) Mixins = problem if too much
    http://jsfiddle.net/dFNSW/11/

3) JS Object = Problem - no Angular dependency
    http://jsfiddle.net/RQy8K/4/

4) SUGGESTED - Angular Services - Singleton, good for common functionality or shared
    http://jsfiddle.net/E2nyQ/8/

5) SUGGESTED - Angular Helper Controller - Like regular object, but instantiate with $controller to get Angular DI
    http://jsfiddle.net/8M27W/8/
    
    Helper Controller usually need to share state to page
    Option 1) make controller use child scopre, access directly - good for lots
    Option 2) pass in configuration

=========================================

** API PROVIDER **
example:  jelbourn / api-provider.js on gist.github.com
          Jeremy Elbourn (jelbourn@google.com)

need to wrap $resource with apiProvider when you have lots of REST endpoints
that automatically wrap response data in logical entities by using $injector.instantiate
that automatically transform data to more UI friendly format (add  afterLoad and beforeSave )

apiProvider.endpoint('songs').
           route('songs/:id').
           customAction('POST', 'remix', {fresh: 'max'});
           model(app.Song);

   Usage:
     var songPromise = api.songs.get({id: 7});
     var remixPromise = api.songs.remix();

------------------------------------------------

need to wrap $httpBackend
   that exposes expect

=========================================

Use Jade instead of HTML because:
Encourages good code organization (data generation is separate from presentation code)
Output generation is more expressive (template syntax doesn't require a sea of string concatenation)
Better productivity (common problems such as output encoding, iterating, conditionals, etc. have been handled)
Generally requires less code overall (jade in particular has a very terse syntax)

Cons:
Jade isn't designed for speed, it's designed for elegance.
Yet another thing to learn

=========================================
Underscore.js
Lo-Dash.js  (http://lodash.com/)



Breeze, etc. - ORM
Ember.js does similar stuff

=========================================

*** John Papa - Progressive Saving  ***

http://jpapa.me/ng-z-wip
angular.breeze.storagewip

OPTION 1 - When leave, lose changes
OPTION 2 - Cannot leave
OPTION 3 - Auto Save (but how save incomplete)
OPTION 4 - WIP
            User Stories:  Listen for Changes, Save WIP Auto, Get WIP or Cancel WIP, Tell User

Menu Node for WIP (count)

Save or Delete WIP (count = count - 1)

Store to "local stash" (HTML5 Local Storage, Breeze.JS Import/Export APIs, Angular Directives, Angular Services)
    Row of changes (state with ID)
    Summary row of data.

QUESTION 1 - When to Stash?
  manager.entityChanged.subscribe (function (chargeArgs)
     if (chargeArgs.entityAction === breeze.EntityAction.PropertyChange)
        { common.$broadcast (events.entitiesChanged, changeArgs);

QUESTION 2 - How export? (Serializes entity - changes and state)
   var includeMetadata = false;
   var exportData = manager.exportEntities([entity], includeMetadata);

QUESTION 3 - How import?
   var importedData = $window.localStorage.getItem(key);
   var importResults = manager.importEntities(importedData);
   var importedEntity = importResults.entities[0];
   return importedEntity;

QUESTION 4 - How tell user (Angular Directive)
   <li data=cc=wip
       wip-"vm.wip"
       changed-event="{{vm.wipChangedEvent}}"> </li>

QUESTION 5 - How interact with WIP?
   key = zStorageWip.storeWipEntity (entity, key, entityName, description);
   zStorageWip.GetWipSummary();
   zStorageWip.clearAllWip();
   var importedEntity = zStorageWip.LoadWipEntity (key);
   zStorageWip.removeWipEntity (key);

Comments

Popular posts from this blog

Upgrading to .NET8 from desktop versions 4.8.X

GHL Chat Bots for Webpage

GHL > Set website so shorter URL address