Search code examples
javascriptreactjsexpressreact-routermern

Does using the react-router to create 'single-page apps' waste server resources?


Note: I am kind of new to web development so please help me through any misconceptions I might have.

I am trying to learn the MERN stack. As an example, I am trying to make a two page site with a homepage and an about page. I made a ./public folder and added an index.html and an about.html to that folder. Then I started by learning some basic express where I have this line which will let the server serve static files from the ./public folder:

// set static folder
app.use(express.static(path.join(__dirname, 'public', )));

After I felt good about this, I wanted to add React to my existing project. This is where I ran into some confusion. It seems like React doesn't allow multiple pages in my website; I saw this SO post. So, React is good for building single page applications. I also saw this YouTube video where the first three minutes explain the difference between traditional multiple-page applications and React SPAs. He stated that all the pages will be sent at one time and the react-router will intercept any page requests and re-render the browser with the pages it already received on the first page load.

So, finally we get to my question. Going back to my example, suppose my about page is VERY large, with a lot of text and images. Isn't that potentially wasteful if I load the homepage, but the server has to send the entire website including the large about page, even though I might never even click on the about page? Once it is all loaded, I understand that the client has a smooth experience going from one page to the next without having to contact the server. But doesn't it mean that the client experiences long initial wait times. And, isn't this wasting server resources by sending pages the user might never click on. And the problem only seems to get worse the more unique pages the website has.


Solution

  • "He stated that all the pages will be sent at one time and the react-router will intercept any page requests and re-render the browser with the pages it already received on the first page load."

    This is an oversimplification that is at the root of your misunderstanding.

    Your react app is going to be a small amount of HTML that acts as the document root, and then a fair amount of CSS and JS. This JS React app will execute to generate your pages based on how you have configured your views and wired them to any data model. Generally with a SPA like this, you will load one view at a time, and it will, if applicable, make a request to the server for any data it needs to render, which will generally be returned as JSON. Once the JSON is received, it will get parsed in the browser into the data model and the UI will update to reflect the new state of the data model. Critically, each view (if wired correctly) will only fetch data from the server when the view loads; furthermore, any images or other assets in the UI will only be loaded when the UI renders them, so there will be no prefetching that wastes resources.

    Because the react components can basically act as templates, you can actually save bandwidth in this way. Say you had 100 product pages on your site that were identical except for the product information. If you were to serve a new HTML document for each page there would be duplicated bandwidth in the markup sent each time. However, in React you can define a single <ProductPage /> component that will fetch only the product information and load it into the markup template each time, removing the issue of sending duplicate HTML.

    There are also additional ways to split up your react app using tricks like lazy loading, to only fetch the salient JS when it is about to be used.

    So, no, using a React app does not mean that it fetches all the HTML pages and assets for the site all at once. While one could write a React app in a wasteful manner, most properly structured React apps should be smaller than the rendered totality of the site.