It used to be that my natural inclination would be to wire my view templates in a manner that made assumptions about the users’ intentions and expectations, based on my understanding of the requirements. This could be seen not only in the way that I named the properties and methods that would be exposed by the controller / view model, but in the way that the view interacted with these properties and methods. Take the following AngularJS view template code as an example:
As an accompaniment to my blog post entitled ‘Lazy Loading In AngularJS’, I provided a link to a sample app that was intended to provide a very basic example of how to lazy load artefacts using RequireJS. This sample app, however, was not initially setup with unit testing in mind. This was because my aim was merely to give a very simple and easy to follow example of lazy loading and nothing more. My thinking was that the more I added to the project, the more complicated it would become for others to follow. As others have been trying to integrate the concepts found in the sample app, however, some have found that they are not able to test artefacts that are to be lazy loaded. As a result, I have now refactored the app slightly so that these artefacts can now also be easily tested. If you have not yet read the blog post in question, I would recommend that you first do so in order to gain the proper context before reading any further.
Being able to lazy load artefacts such as controllers and directives in AngularJS is great because in addition to saving on bandwidth costs, it results in the initial load time of your AngularJS app being much shorter. This is because only the assets that are needed to render the particular route in question, are delivered to the browser, and nothing more. If too many files are being lazy loaded at a time, however, the time between the initial load of your app and when the app is actually ready to present its first route, may significantly increase. The same applies for the time it takes to change routes. This can happen when the browser has reached its ‘maximum concurrent connections’ limit and as a result, has to wait for the first set of concurrent downloads to complete before starting another set of downloads. One way to mitigate this issue is to present some sort of ‘loading’ message to the user while the lazy assets are being loaded. At times, however, the message may not be enough to maintain the perception of the app being performant. At this point, the only thing that can then be done is to combine the lazy assets into fewer files that can be delivered much faster to the browser.
When building large sites or apps with many routes/views in AngularJS, it would be good to not have to load all artefacts such as controllers, directives etc., on the first load. Ideally, on first load, only the artefacts that are needed for the route in question, will be loaded. This may be either in one download or multiple depending on the app, however, it will only be what is needed to render the particular route. Then as the user navigates the app by changing the route, other artefacts that have not already been loaded, will then be loaded as and when there are needed. Not only should this potential speed up the initial page load, but it should also result in bandwidth not being wasted. With this post, my aim is to show how the lazy loading of artefacts such as controllers and directives can be achieved with AngularJS.
Recently I was trying to setup some external tools on WebStorm (Mac OS X) for Grunt and NPM, and I kept getting errors similar to the following:
Error running install:
Cannot run program “npm” (…): error=2, No such file or directory
On my windows setup it all worked perfectly, however, on OSX it refused to work. After some googling, I was eventually able to get it to work by following the instructions found in the comments of an issue on the WebStorm issue tracker entitled: ‘WI-10333 Unable to add npm to command line tool support‘. The experience though was not straightforward. This was partly due to the link hopping that resulted from searching for answers in the comments of the issue, as well as partly due to my inexperience with MacOSX and UNIX systems in general. Hence, my aim with this post is to detail the steps I took in solving the problem with the hope of saving others like myself the hassel.