How can I further optimize my game of life script(Client sided)

So I created a game of life script but the problems is that what you have a big grid size of lets say 75*75 you will most likely lag if you have a low “tick”/“wait” time between the script updating the grid. Here is the part of the script that handler the game of life:

RunService.Heartbeat:Connect(function(DeltaTime)
    --Using Delta Time for wait
    Elapsed += DeltaTime
    
    if Elapsed < WaitTime then
        return
    end
    
    Elapsed -= WaitTime
    
    --At the end of detecting the and going over the game rules the changed cells in the table will change 
    local ChangedCells = {}
    
    if Paused then return end --For Pausing
    
    for x = 1, #Grid do
        local Horizontal = Grid[x]
        
        for y = 1, #Horizontal do
            local NearbyCount = 0
            
            --Checking the horizontal side
            if y < #Horizontal then
                if Horizontal[y + 1].Color.R == 1 then NearbyCount += 1 end
                if x > 1 and Grid[x - 1][y + 1].Color.R == 1 then NearbyCount += 1 end
                if x < #Grid and Grid[x + 1][y + 1].Color.R == 1 then NearbyCount += 1 end
            end
            
            --Checking for the vertical side
            if y > 1 then
                if Horizontal[y - 1].Color.R == 1 then NearbyCount += 1 end
                if x > 1 and Grid[x - 1][y - 1].Color.R == 1 then NearbyCount += 1 end
                if x < #Grid and Grid[x + 1][y - 1].Color.R == 1 then NearbyCount += 1 end
            end
            
            if x < #Grid and Grid[x + 1][y].Color.R == 1 then NearbyCount += 1 end
            if x > 1 and Grid[x - 1][y].Color.R == 1 then NearbyCount += 1 end
            --Changing the cell based on the game rules
            if NearbyCount ~= 3 and not((NearbyCount == 2 or NearbyCount == 3) and Horizontal[y].Color.R == 1) then
                table.insert(ChangedCells, {
                    x,
                    y,
                    Color3.new(0, 0, 0)
                })
            else
                table.insert(ChangedCells, {
                    x,
                    y,
                    Color3.new(1, 1, 1)
                })
            end
        end
    end
    --Changing the cells
    for k, v in ipairs(ChangedCells) do
        Grid[v[1]][v[2]].Color = v[3]
    end
end)

This is not really an answer but you could try splitting the computation power required between the server and the client.

The whole script is managed by the client

That’s what I’m trying to state here, if the game is singleplayer you should utilize the server
I’m assuming so because conway’s game of life is considered a 0 player game lol

That will just cause more unnecessary lag, calling events will not help it, and using the server to manage this will be slower.

Well, it’s just a suggestion, I don’t know any other way you can optimize this