Analyze and optimize the performance of the censhare Web frontend.

AngularJS

Tutorial

Before making any performance related optimisations in angularJS, please make sure to first have a look on the tutorial below Speeding up AngularJS apps with simple optimizations.

censhare Specific Tips

Here will be analyze a few tips which are special for our application:

  1. If you use $compile, $controller and $http to fetch templates, be aware that $compile returns a function which can be "reused" to instantiate the same template multiple times. Then, parsing is avoided entirely but the on the first usage. It's worth mentioning that the dynamic controller is performing this same way as well, hence the item renders are benefiting from such kind of optimisations too.

  2. $timeout shouldn't be called with the third parameter as true (or omit the third). It triggers a global apply, which will digest everything.

  3. If you use a 'registerChangeListener', the listener is executed in the "angular" word and hence a digest is performed. The csServices it's optimized in a way that it will avoid triggering a global digest, instead it will trigger a digest on scopes involved. You can use the registerNativeChangeListener to avoid the digest. Be careful here as you will have to take care of updating the UI by yourself in these callbacks.

  4. Preloading modules - When in need (but should not be used too often), you can tell the client to load modules which will required later on. For example: in wizards, when the next wizard step it's going to display a layout manager, you can request the module loader to load the corresponding module of the layout manager one step before the layout manager is actually shown. If a timeout is used in the controller of the previous step (see 2.), you can let the client load the needed information for the next step, while the user is filling out a form. Then when pressing "next" the next step will be loaded faster, because JS and angular templates are not needed to be loaded. You must make sure in such optimisations that the user experience is not slown down. (Such optimisation was applied on the login frame and it saved ~750ms after the click to "login", which was ~25% of the time required to show the home screen after the login).

Advanced Tips

Maybe someone finds this following slideshow useful as well: (by Klemen Oslaj) Slides

How to use $timeout

In our current client the $timeout method of angular is used in many places to trigger asynchronous tasks later.

Therefore, we came up with some guidelines to ensure the $timeout is used in our project correctly and only when it makes sense.

  1. When possible, avoid using $timeout at all. It should be only used when there are no other alternatives (that is not always possible). It is typically better to find a way to react upon a change somehow by using a $watch, or by registering yourself as a change listener to an observable, or use a promise result, etc. $timeout is always fragile, because the timeout time to be used is questionable. The timeout time depends on the speed of the machine that the client is running on. When the goal is to execute something when the view is updated, then the timeout time should be 0.

  2. If you are forced to use $timeout for some reason, please be aware that a) You can use it with $timeout(function () { ... }, xx, false) b) and the $timeout(function () { ... }, xx, true) === $timeout( function () { ... }, xx) // true is the default https://docs.angularjs.org/api/ng/service/$timeout

As you can see, the third parameter makes it possible to avoid a global scope apply call. (This call invalidates all angular scopes in our application and digests them. This is an expensive operation, because in our application we have a lot of data in our scopes. (E.g: The results of all open searches. The digest takes multiple 100 milli seconds). When the application is running, this is not a big issue, but in a lot of cases the calls are also fired during the startup of a page. That is why our initial page impression as well as switching between different pages may be influenced negatively by calling $timeout with a true as third parameter.

If your timeout callback does not require a view invalidation (you just manipulate the DOM directly, your interaction with the server, you are using observables, etc.) you should give the version 2a) a try.

Angular