Antony Denyer

Tilling the land of software

about me

I am passionate about creating great software and am particularly interested in associated supporting methodologies, namely XP and TDD.

recent public projects

Status updating…

found on

contact at

email@antonydenyer.co.uk

Angularjs Performance Tweaks

- - posted in angularjs | Comments

Performance tips for angularjs

Two way data binding using AngularJS is pretty sweet, but it comes at a cost. When dealing with complex data structures or large lists things can get very slow very quickly. Here are some simple things you can check to give your site the performance boost it needs.

Watcher count

A good rule of thumb is to keep the number of watchers as low as possible. In a nutshell when you tell angular to watch something it will keep checking it to see if it has changed. Whenever you do an expression or use a directive that takes an expression (e.g. ng-src=“expression”) in your html template or a $scope.$watch in your controller code Angular adds a watcher to the digest cycle.

Personally I use ng-stats to keep an eye on things.

ng-if vs ng-show

The difference between ng-if and ng-show is that ng-if actually removes or recreates the element where as ng-show will, obviously, just hide or show the element. The intersting thing about this is that if you have something that is hidden any watchers you have will still be updated even though you are not presenting the information to the user.

So for example consider the following:

1
2
3
4
5
6
7
<div ng-if="showexpression">
    <span ng-bind="expression"></div>
</div>

<div ng-show="showexpression">
    <span ng-bind="expression"></div>
</div>

They will have the same amount of watchers if the showexpression evaluates to true. However, if the showexpression evaluates to false in the ng-if then there will be less watchers because it is not rendered onto the DOM.

Prefer simple expressions

This is not usually a big issue but try and make sure all your expressions are properties rather than functions. So favor things like:

1
2
3
<div ng-if="model.show">
    <span ng-bind="expression"></div>
</div>

Rather than:

1
2
3
<div ng-if="model.showFunction()">
    <span ng-bind="expression"></div>
</div>

showFunction will be called every time there is a digest cycle which can cause performance pains.

One time binding

There are many scenarios where all you are doing is displaying data and don’t need two-way data binding. This is where bind once comes in. It allows you to specify what to bind to and when to watch for changes on the thing that you have bound to.

For example:

1
2
3
4
5
6
<div bindonce="Person" bo-title="Person.title">
    <span bo-text="Person.firstname"></span>
    <span bo-text="Person.lastname"></span>
    <img bo-src="Person.picture" bo-alt="Person.title">
    <p bo-class="{'fancy':Person.isNice}" bo-html="Person.story"></p>
</div>

Basically there’s only one watcher on Person. When that changes all the other bo-* directives will fire. This is in contrast to having a watcher on every single expression.

Continuous Delivery - Chaos Build/Release Monkey

- - posted in continuous, delivery | Comments

I think some people are missing the benefits of continuous deployment and are focusing on infrastructure and tools rather than process. The initial incarnation of this chain of thought was continuous integration, where by whenever you check in your code it’s built by a central server. Ensuring that your code builds with other people’s code. Then it was taken a step further by having an automated deployment process. Your code would be automatically deployed after your build & unit test has successfully run. Then people took it further and started declaratively building the infrastructure that was required to run your application.

I think we’ve missed a step.

I think we’ve missed the continuous part of the puzzle. When you’re actively working on a project this isn’t a problem, code is being deployed on a regular basis, your tests are running and everything is being deployed. Most software projects are not being actively developed, they’re the legacy applications that’s running your cms system. In my opinion to truely benefit from continuous deployment you need to be building and deploying your code continuously, even if there’s no new code. This helps keep everything upto date. Some automatic updates may break your deployment process and you won’t know until you try and deploy that urgent bug fix. If your CI server is updating external dependencies you’ll know when something gets deprecated straight away rather than in six months.

This is why we need a release chaos monkey

The Netflix Chaos Monkey brings about the idea of randomly failing infrastructure to push you into a state where your code and infrastructure becomes anti-fragile. Your builds and deployments should be the same, you should be able to deploy at a moment’s notice. The only way to, in my opinion, is to be randomly deploying your code. The tangential benefits are numerous. Your monitoring will improve as you won’t be sitting there watching a deploy go out to production. The cost of code maintenance will be moved to the forefront as things break sooner. Developers will be less scared to work on legacy code as they know it’s in a deployable state.

In summary ….

Release all the things

Angularjs Decorator to Support Ie8 Catch

- - posted in angularjs | Comments

When using the angularjs $q library with ES3 browsers (IE8 etc) you get an ‘Expected identifier’ error when you try and use the catch method on angularjs $q library. This is because catch is a reserved word in ES3 and reserved words are not supported as property names in ES3. To get round the problem you can access the function using square bracket notation. Personally I find this kind of syntax rather ugly.

1
2
3
doSomething()
.then(doSomethingElse)
["catch"](allTheThings);

The first thing I wanted to do was provide a nicer syntax. The following artice has a good explanation of how to create a decorator for the $q service so that you can add your own methods onto it. The problem with the $q service is that you need to decorate the thing that gets passed back from the functions ‘defer’, ‘when’ ‘reject’ and ‘all’. Rather than just putting it on $q.

This means that we can now call

1
2
3
doSomething()
.then(doSomethingElse)
.error(allTheThings);

and IE8 wont complain about it. Wonderful. The other thing I wanted to do was to make sure that everyone uses error instead of catch. So to guide people into this I’ve re-implemented catch to throw an exception.