HTML canvas print is slow for large data:image/png but not numerous small ones

I have been stuck on this rendering issue for my video game for a few days now and I’m at a complete loss … I have terrain which is defined by a list of vertices, a center and a height. These terrain assets are pre-compiled to fill the areas and crop/transform the textures then convert them to a data:image/png which is stored then printed on the fly.

The problem is is that the walls you see have been exaggerated to includes almost 500 vertices which means 500 individual data images for just the walls. If I print JUST these walls (image 2) the time delay on my print loop is <= 1ms. However if I include the print of the terrain tops (image 1), which there are only about 10 of, the time delay shoots up to 25-40ms!!
At first I thought it may be related to the area that the data image takes up BUT I’ve created a terrain object that covers the ENTIRE screen with just its wall (image 3) and the runtime is still <= 1ms per frame o.O. I am completely lost. I’ve removed almost everything in the display driver and it still remains true that the runtime only goes up when the terrain tops are included … is it because the terrain top is a complex polygon while walls are always simpleish?? How do I work around it

Note: the frame drop occurs even when there are a reasonable number of walls as well, like 30 walls and 5 tops. Also crazy enough, the shadow stack and its associated clip / restore for shadows near the edge of terrain plays NO part in this delay. Removed or not the outcome of this scenario remains the same. UGHHH

The loop is as simple as…

let time = Date.now();

entities.map_print.forEach((V, index) => {
    if (V.type == 'terrain_wall') {
        this.printTerrainWall(V, ctx, half_width, half_height, computed_stash.camera_position);
    } else if (V.type == 'terrain_ground') {
        this.printTerrainTop(V, ctx, half_width, half_height, computed_stash.camera_position, computed_stash.shadow_stack[V.index_ref_to_map]);
    }
});

console.log(Date.now() - time);


printTerrainWall(V, ctx, half_width, half_height, camera_position) {
        // draw wall texture
        ctx.drawImage(
            V.src,
            precise(half_width + V.position.x - camera_position.x + V.first_vertice[0] - V.offset.x),
            precise(half_height - ((V.position.z - camera_position.z) + (V.position.y - camera_position.y) + V.first_vertice[1]) - V.offset.y)
        );
    }

printTerrainTop(V, ctx, half_width, half_height, camera_position, shadow_stack) {
        
        // draw top texture
        ctx.drawImage(
            V.src,
            precise(half_width + V.position.x - camera_position.x - V.offset.x),
            precise(half_height - ((V.position.z - camera_position.z) + (V.position.y - camera_position.y)) - V.offset.y)
        );
}

enter image description here

enter image description here

enter image description here