ajax – Async Loading of Custom Posts

I have a wordpress page template, where I’m loading custom posts.

The code for fetching these custom posts looks as follows:

template-parts/content-page.php

<article id="songs">
    <?php get_template_part( 'partials/content/custom', 'songs' ); ?>
</article>

partials/content/custom/songs.php

$args = array(
    'posts_per_page'   => 0,
    'offset'           => 0,
    'category'         => '',
    'category_name'    => '',
    'orderby'          => $orderBy,
    'order'            => $order,
    'include'          => '',
    'meta_key'         => '',
    'meta_value'       => '',
    'post_type'        => 'custom_song',
    'post_mime_type'   => '',
    'post_parent'      => '',
    'author'           => '',
    'post_status'      => 'publish',
    'suppress_filters' => true
);
$songs_array = get_posts( $args );

if (count($songs_array) > 0){
    ?>
    <ul>
    <?php
    foreach ($songs_array as $mysong){
        set_query_var( 'mysong', $mysong);
        get_template_part( 'partials/content/custom', 'normal' );
    }
    ?>
    </ul>
    <?php
}
?>

The problem is that there are over 2000 records. And I want all of them to be loaded at once without any pagination. The above code works and it does load all the posts, but the page is slow because of this query.

Can you please help me how I can optimize this and make the load faster? Is there a way I can load this asynchronously? So that I can show a loading icon in this part of the page till the posts are loaded?