Episode: 2102
Title: HPR2102: AngularJS's ng-repeat, and the browser that shall not be named
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr2102/hpr2102.mp3
Transcribed: 2025-10-18 14:19:05

---

This in HPR episode 2,102 entitled, and your JSNG repeat, and the browser that shall not be named.
It is hosted by RON and is about 11 minutes long.
The summary is a method for optimizing the rendering of items when using and your JSNG repeat directive.
This episode of HPR is brought to you by an honesthost.com.
Get 15% discount on all shared hosting with the offer code HPR15, that's HPR15.
Better web hosting that's honest and fair at an honesthost.com.
Hi, this is Rowan and welcome to my second submission to Hacker Public Radio.
At my work we are in the process of revamping our internal call logging system.
Moving from a .NET and Microsoft ASPX pages for both the client side and back-in processing,
to an HTML5-based single-page application using AngularJS for the client side and a face
with a .NET web API service for the back-in processing.
The main page for both versions contains a list of the current days calls laid out in
a table with nine columns.
Users are able to switch to a specific days calls by selecting a date via calendar widget
or by moving one day at a time via previous or next buttons.
By the end of the typical day the page will contain between 40 and 50 calls.
During recent testing of the SBA client on a proprietary browser we all love to hate
or at least have a love hate relationship with if you have to support it, I noticed that
rendering of a whole days worth of calls would take seconds, freezing the UI completely.
This page is changing dates painful as we reload the data anytime you enter the page.
That's how we manually pull for new data.
We are planning to implement either a timer-based polling or a push service or web sockets
eventually, but it didn't make the page almost unusable with that seven-second freeze.
The page did render fine in both Mozilla and WebKit-based JavaScript Gid engines, but
Microsoft's engine just would choke on it.
For a bit of search for AngularJS slow rendering and AngularJS optimized, I found many references
about using Angular's ng-repeat directive when rendering a long list of data.
For those of you who are not sure what AngularJS is, it's a JavaScript framework designed
to help you write single-page applications, basically lets you put custom HTML tags or
custom attributes within your HTML tags, which then binds some JavaScript and CSS to
those either tags or attributes.
I tried a couple of methods mentioned to optimize the ng-repeat directive.
I used the track by feature of ng-repeat to use the calls ID as the internal ID of the
row.
So ng-repeat didn't have to generate a hashed ID for each row.
I implemented Angular's one-time binding feature to reduce the number of watches being created,
reducing the test day's number of watches from 11, 20, to 596.
But even these two combined optimizations didn't have enough effect to render the page
in acceptable amount of time.
The next optimization I played with was using ng-repeat with the LimitTube filter.
This limits the number of items rendered in the list that the ng-repeat is looping
through.
This is particularly useful combined with the paging of data.
I set the LimitTube option to different values to see how it affected the rendering time.
I found that rendering 5 rows was fast and consistent for every day's worth of data
I viewed.
From my reading, I knew if I updated the LimitTube amount while keeping the array of items
the same ng-repeat would only render any un-rendered items and not render the whole list.
Within your code, you basically set up an ng-repeat equal to, say, c or item in your list
of items and then you filter it by a certain size.
For me, I'm limiting it to initially 5, but you're basically setting the LimitTube filter
to a variable which you will be incrementing.
If you look in the show notes, you'll see how the code might use to update the LimitTube
variable.
Any time the list is updated, the display render size, which is the number of things
currently being rendered, is reset to the default number for this example 5.
Then I have a function called update display render size, which is called.
This function calls itself repeatedly via Angular's timeout service and timeout is just
a wrapper for JavaScript set timeout function.
It increments the display render size variable, which is being watched by the LimitTube
filter of the main ng-repeat each time this play render size variable is incremented.
ng-repeat renders the next set of items.
This is repeated into all the items in the list of rendered.
The magic happens because ng-repeat blocks any other JavaScript, which does not affect
Angular's digest path for Angular.
It basically sets up all these different watches on variables, and then anytime there's
a change, it then re-figures out what's changed and what in your HTML needs updated, and
so it goes down, this recurses down through all these different paths, and then renders
everything.
So by calling the function update display render size with a timeout, the function doesn't
get called again until after the next set of items is renders.
I make the timeout delay to zero, so normally with a timeout you'd be setting it for so
many seconds or minutes to occur again in the future.
I say zero so that it will be called immediately after the rendering stops blocking.
And it was cool because in this instance the sum of the rendering time for parts of
the list is shorter than the sum of the rendering time for all of the list items at one time.
So it went from like seven seconds to under a half a seconds in rendering time.
There are a couple small glitches with this solution, scrolling can be a bit jerky as
the chunk sized renders cause a series of micro UI freezes instead of one big long one.
This settles down once the whole list is rendered.
Also if you don't have a fixed or 100% wide table layout and you don't have fixed column
sizes, the table layout will dance a little on the screen until the columns have been filled
with their largest amounts of data.
This is a result of the table layout being recalculated as more data fills it.
This all being said, the solution works great and move the pause, like I said before, from
seconds to under half a second or less, making the page go from unbearable to usable on
Microsoft's latest browser offerings.
I hope you found this little bit of esoteric, angular optimization interesting and hopefully
helpful.
Thanks for listening.
You've been listening to HackerPublicRadio at HackerPublicRadio.org.
We are a community podcast network that releases shows every weekday, Monday through Friday.
Today's show, like all our shows, was contributed by an HPR listener like yourself.
If you ever thought of recording a podcast, then click on our contributing to find out
how easy it really is.
HackerPublicRadio was founded by the digital dog pound and the infonomicon computer club
and is part of the binary revolution at binrev.com.
If you have comments on today's show, please email the host directly, leave a comment
on the website or record a follow-up episode yourself.
Unless otherwise stated, today's show is released under Creative Commons, Attribution,
ShareLite, 3.0 license.
