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.