Improving End User Experience with AngularJS

Posted by on June 25, 2013

I recently started working with AngularJS for our service’s backend customer management component. It has been an exciting new tool so far as it has simplified our lives significantly. For those who haven’t looked into it yet, AngularJS is a “Superheroic JavaScript MVW Framework”.

From the AngularJS documentation we learn that “Angular tries to be an end-to-end solution, when building a web application. This means it is not a single piece in an overall puzzle of building a web application, but an end-to-end solution. This makes Angular opinionated about how a CRUD application should be built. But while it is opinionated, it also tries to make sure that its opinion is just a starting point, which you can easily change”.

First of all, lets talk about AngularJS cycles and how they map/replace server-side generated HTML. In this post we’ll use JSP as a server-side HTML generating mechanism.

AngularJS Cycles (Simplified Version)

In AngularJS the lifecycle of an application starts with the compilation part. What this means is that Angular needs to parse the DOM and collect all directive references. This will allow our app to know where to apply its magic! And here comes the linking. After knowing about the existing directives we must link everything together:

  • Use the templates associated with the directive
  • Link the scope which will be used to manage the directive

Let’s compare the same table being generated on the server-side and client-side:

SERVER-SIDE (JSP)

CLIENT-SIDE (AngularJS)

Look pretty similar huh? But there are huge differences.

Wire size

The server-side alternative will generate the entire HTML on the server-side and send it back over the wire, hence if you have a huge table that means a lot of bytes.

Don’t be fooled though. Even with AngularJS the information has to get to the client somehow. The “Angular way” is to send the information in JSON format and let directives manipulate data and bind it to the DOM. By sending JSON instead of HTML a lot of HTML Markup metadata doesn’t go through the wire!

The examples above are rather simple. A normal table will be much more complex but even such a simple example produces the following results (headers excluded):

wire_jsp_a
Figure 1: JSP wire size: 8.1KB
wire_angular_a
Figure 2: Angular wire size: 4.9KB

This represents a reduction in 39.5% of wire size in such a small example. This is even more relevant if we consider that the information is the same in both cases (100 rows) using the same object, meaning that the difference is caused by HTML alone. Not convinced? Let’s add something more to our example:

SERVER-SIDE (JSP)

CLIENT-SIDE (AngularJS)

Added some columns to the mix. Look at the wire size now:

wire_jsp_c
Figure 3: JSP wire size: 18.5KB
wire_angular_c
Figure 4: Angular wire size: 5.0KB

Yep, we went from a 39.5% reduced wire size to a 66.7% reduction! AngularJS wire size seems to increase gracefully. But how does the client know the HTML to generate?

Defer HTML Processing to the Client

As we mentioned in the AngularJS lifecycle section, most of the HTML processing is performed by AngularJS, on the client side!

Why?

  • Your server gets freed sooner to answer other requests
  • Your customer is likely to have more than enough idling power to handle it by himself, so use his computing power to save some of your own

This comes at a cost though. Because your deferring processing to the client this also means that the client will require more resources (both CPU and Memory).

memory_jsp_a
Figure 5: JSP Memory requirement
memory_angular_a
AngularJS Memory requirement
memory_angular_b
Figure 6: AngularJS in this case required 3.4 MB more compared to the JSP approach for that specific request.
The global memory usage was also significantly more.

Conclusion

Do you think that deferring computations to the customer is a good strategy? On one hand you are (in theory) using resources more efficiently, both your own and your customer’s. But in more complex cases this can cause your customer’s laptop fan to go crazy, because the computer is doing too much.

Our user experience was significantly improved because:

  • There is a lot less bits going over the wire. A backend can be rather complex and focusing on transmitting data rather than HTML makes requests significantly faster
  • The page “feel” has improved. When compared to many other javascript frameworks, AngularJS requires less javascript to accomplish the same task. Even considering AngularJS cycles, all tasks are only performed when they are needed
  • Client-side processing has been kept to a minimum. When “you’re doing it right”, for instance not nesting controllers inside controllers ad infinitum, you won’t make your customer’s laptop fan go crazy!

As an additional bonus, the maintainability of the components that use AngularJS has improved significantly! Less code is easier to maintain is it not?!

As you can imagine this is only the tip of the iceberg. There are a lot of variables to test and measure, but hopefully I was able to give you an idea of how AngularJS has helped us so might be worth giving it a try yourself. Feel free to drop a comment below with your opinion, questions, or experience with Angular.

Processing...
  • Very interesting read !
    The page took longer to load with Angular JS (1.03s) than with JSP (700ms) ? isn’t it against what we’re trying to do ?

    • João Peixoto

      Thank you for reading, you’ve got a good eye! The “Memory requirement” example is not relevant in terms of timings.

      For the memory component we used Chrome’s Timeline tool (https://developers.google.com/chrome-developer-tools/docs/timeline#timeline_panel_overview) which requires manual initialization and stopping.

      Since this section focused more on maximum memory usage rather than timing, the x-axis should be taken with a grain of salt.

      If you look at the “Wire size” section you’ll see that the timings gathered there are very relevant.

      • Jeff

        The network section only shows the amount of time it took to transfer the data. Even if the data is less and gets transferred faster, it may not be rendered and usable to the user faster. If you are concerned about user experience you should benchmark the amount of time until the page has completed all rendering.

  • Thank you ! It was caught in my blind spot :)
    I bookmarked the blog for future interesting readings and good luck for the startup adventure

  • red_square

    You forgot to gzip the reaponses!

  • I am not 100% following why the wire size is different from your examples.

    I know it’s because the table would have different populated variables and multiple rows. I don’t feel the 2 table examples explains the idea quite well enough. Maybe explode that part of the article to include some JSON data as well and a larger data set in the examples.

    But it’s a good point to make about the differences between using server or client side resources.

    Thanks for sharing!

    • Michael,

      To help out while you’re waiting for the blog post to get updated. You don’t actually need to see it in a larger data set — you just need to view the comparison of one ‘row’ of data that would be sent. Compare the byte size of the following A (server-side rendering HTML) and B (server-side JSON, client-side rendering HTML). Note: I added classes to A’s elements as well as minified B’s varnames to help visualize the difference that a more likely scenario would be

      A (121 bytes)
      ——-

      1
      Your Name
      123 Address Lane

      B (52 bytes)
      ——-
      {‘id’:1, ‘n’:’Your Name’,’addr’:’123 Address Lane’}

      Since the angularjs HTML template is client-side, you don’t have to send the (bloated) HTML from the server to the client — just the data. This could be shortened even more if needed by abbrv. things (ie: ‘index’ –> ‘id’, ‘name’ –> ‘n’, ‘address’ –> ‘addr’ all saves 9 more chars per row of data).

      Hope this helps.

      • it appears that the comment system here strips out html so just pretend ‘A’ has html similar to the blog post.

  • yangbai

    good!