You would be better off preloading all the images for the current page ahead of actually outputting them. Then you reduce the queries from n*2
(there are actually two database queries per get image call, one from the wp_posts
table, the other from wp_postmeta
) down to just two.
$images = [];
foreach ( $pages as $page )
$images[] = ( int ) get_post_meta( $page->ID, 'image_field', true );
if ( $images = array_filter( $images ) ) {
new WP_Query([
'post__in' => $images,
'posts_per_page' => -1,
'no_found_rows' => true,
'post_status' => [ 'publish', 'inherit' ],
'post_type' => 'attachment',
]);
}
This is just for demonstrative purposes, but the idea is you build an array of just image ID’s, then use a query to pull them all into memory at once. Subsequent image function calls for said IDs will hit the cache rather than the database.