- about SPA - in my comment I said no word about SPA, it's a more complex layer on top. I only arguing about template-data separation approach to decrease data duplication and traffic consumption. And no, you don't need to rewrite your app as SPA and no react/preact/javascript frameworks required. You can use your server-side rendering and just change format of what you are sending to user. Instead of sending index.html with repetitive html markup for every list item you can basically send script-tag where you loop over data and build html-markup directly on a client
<doctype html>
<html>
<body>
....
<div id="books"></div>
<script>
const data = [{title: "...", author: "...", description: ""}, {...}]
document.querySelector("#books").innerHtml = data.map(item=>`
<div class="book">
<div class="book-title">${item.title}</div>
<div class="book-author">${item.author}</div>
<div class="book-description">${item.description}</div>
</div>
`).join(``);
</script>
</body>
</html>Yes, it lacks http streaming but - less repetitive html markup -> smaller size -> less time to download -> http streaming becoming less useful
And again - you can use your favorite http compression (gzip, brotli, etc) on top of this template-data separation approach to compress even more