AngularJs Virtual Repeater with a Grid

So I had a grid of images I displayed with an Angular ng-repeat, where the number of images was in the hundreds. This was just killing performance and overloading the DOM. I was getting super frustrated with the choppy scrolling and overall slow loading.

It occurred to me to use a virtual repeater, however, they either support vertical or horizontally stacked elements, not a grid. In order to get this to work, I need to structure my elements in a 2D array. That way I could still use the repeater on spitting out rows of image arrays and gain a performance boost through that.

2D Structure:
[
[img, img, img, img] ,
[img, img, img, img] ,
[img, img, img, img] ,
[img, img, img, img]
]

img = the image source url

The first thing I did, was make sure I knew the width of the total space for the grid and width of each element. I want to make sure I fill the space, so I did the math to know how many elements will fill the total space and that will be my column count. I recommend to setup some listeners on the grid width to catch changes from the user changing the window size, I won’t be showing that part in this example. The snippet below shows the creation of my 2D array that will be fed to the repeater.

//Passing in my array of images that I need to break down into a 2D array
//Also, including the width of the entire grid space and each image's uniformed width
function computeRows(imageArray, width, imageWidth) {
    var rows = [];
    if (imageArray) {
        const rowCount = width/ imageWidth;
        const copy = imageArray.slice(); //using a copy instead of affecting actual element
        while (copy.length) { //create the 2D array by looping through the imageArray and splicing it into chunks
            rows.push(copy.splice(0, rowCount)); 
        }
    }
    return rows;
}
//Will need to bind computeRows() to the scope

Once I have my 2D array, I bound it to me scope and used it in my template. I chose to use vs-repeat because it was very quick and easy to implement.

<div vs-repeat vs-excess="10">
    <div ng-repeat="row in rows">
        <img 
            ng-repeat="img in row"
            ng-src="{{img}}"/>
    </div>
</div>

That was it, the end result was awesome, vs-repeat handled just showing what was necessary for the user experience and loading the remainder DOM elements as the user scrolled through the grid.

AngularJS Setup Environment

Similar to yesterday’s post, I started a basic AngularJS startup environment, something I can just grab and program with whenever I want to start a new angular app. It’s just a pain re-setting up the environment each time.

Borrow if you like or contribute, thanks!


Screenshot of github.com
angular-setup-environment
Initial Angular Environment Setup