Let's create a single page application using WordPress, Javascript, XMLHttpRequest, and PHP so we can keep users on the same page without reloading, redirecting, or navigating. In turn this will also limit the number of database queries made. This technique can be implemented with the WordPress styles but I won't be demonstrating that. I will simply be showing you how to retrieve your posts from the WordPress API and place them into JSON objects using XMLHttpRequest calls. There are many ways to get your posts. You can choose to retrieve all your posts at once or use a paginated approach. If you have a large number of posts, you may want to go the paginated route to keep the database queries to a minimum as it is unlikely a user will actually browse every single post. But if you have a manageable number of posts you can simply grab all of them, even from multiple categories, which will actually be quite performant and require less work from your database.

window.onload = function()
{
    var
    //create new request
    xhr = new XMLHttpRequest(),
    //create new form data
    fd = new FormData(),
    //The query we'll send to WordPress API
    //'paged' is our pagination property
    //'posts_per_page' can be set to -1 to grab everything
    query = {
        orderby: 'date',
        category_name: 'blog',
        order: 'DESC',
        paged: 1,
        posts_per_page: 10
    };

    //add that query to our form data
    fd.append('query', JSON.stringify(query));

    //When we get a response from the server
    xhr.onload = function()
    {
        //log our response as a JSON Object
        console.log(JSON.parse(this.response));
    }
    //POST data to our PHP file asynchronously
    xhr.open('POST', 'getPosts.php', true);
    //Send off our POST data
    xhr.send(fd);
}

In the code above, we first create our XMLHttpRequest and FormData objects. Then we build our query object. This is the meat of the code. We send this query object to our php file to create a new WP_Query object. This can be formatted with the same variables as any other WP_Query object. There is quite an extensive list of variables we can create a WP_Query object from. See the WordPress Codex The rest is rather boilerplate XMLHttpRequest code. We append our query and JSON.stringify it to our FormData object as 'query'. We will retrieve this variable in our $_POST variables. Then when the server has responded we will log out the response and JSON.parse it to turn it into a usable object.

//get the variable that was sent via XMLHttpRequest
//Decode the json so we can use it as an array
$myQuery = json_decode($_POST['query']);
//We haven't loaded WordPress yet so let's load it
include('../../blog/wp-load.php');

//Let's create a new WP_Query object using what was sent
$the_query = new WP_Query($myQuery);
//We will create a new empty array to add our post
$myPosts = array();

//"The Loop" as WordPress calls it
while ( $the_query->have_posts() ) : $the_query->the_post();
    //Let's create an array for our post variables
    $singlePost = array(
        'link' => get_permalink($post->ID),
        'title' => $post->post_title,
        'time' => the_date('F j, Y','','',false),
        'content' => apply_filters( 'the_content', get_the_content() )
    );
    //Then we push that array into our main array
    array_push($myPosts, $singlePost); 
endwhile; 

//finally send that array as JSON data back to our javascript
echo json_encode($myPosts);

exit;

In the code above, we grab the 'query' variable sent from our javascript and json_decode it to turn it into an array. We then load up WordPress if we haven't done so yet so we can use all of its functions. After that we create the WP_Query I spoke about earlier. This is what goes to the database and grabs everything you have specified with our 'query' object in our javascript. Next is the plain ol' WordPress loop but instead of using the functions that echo our post data, we use the  properties in our $post variable. You can read about the different properties in $post in the WordPress Codex. Some things are not accessible in our $post variable so we have to use some get functions like I did for the permalink. Also, $post->the_content will leave us without the formatting that WordPress does for our page breaks so we have to apply a filter to the content. After we've created our array that holds associative arrays of posts, we send it back to the javascript as JSON data using json_encode. Now if you open up your console you should see the posts you queried. There are too many things you can do with this to describe in a single blog post. Some things you can do is create single page pagination then send the user to the actual blog post when they click the link. You can also load up the post in the same page since you can query the data without reloading, redirecting, or navigating. Try out different queries to see what will work for you. Keeping down on database queries is probably your biggest hurdle. And with the default WordPress theme, the user is constantly querying with every page click. Using the technique described you can control exactly when the database is queried.