Blend/ Combine CSR and SSR in meteor

I have a meteor app that uses blaze and flow-router. first page load is a disaster but pages loaded thereafter have acceptable speed (4-6 seconds on mobile and 1-3 seconds on pc browser). I wrote the same app in react, react router and meteor using only SSR. First page load is fast (1-3 seconds on pc browser 4-7 seconds on mobile). Pages loaded after the first page are a disaster (can sometimes take over 20 seconds on mobile). If flow router CSR after the first page is fast and react/meteor SSR for first page load is fast how do I combine SSR (first page load) and CSR (all other subsequent pages)? I have searched the internet and there is not one example that at-least MDG accepts that I found. In this thread David Greenspan, discusses why CSR and SSR should be combined in Isomorphic platforms such as meteor and goes on to say he is working on combining them in meteor. But I searched the net to find his final product (or POC) with no luck.Here @diaconutheodoralso wants SSR and CSR to be blended. Not sure if his solution solved the problem or if it is acceptable to MDG, here.

Is there currently an easy way to blend CSR with SSR? I do not mind if the solution uses flow-router. I also do not mind if the solution uses react-router instead, as long as it is fast enough on both mobile and pc browser. Can someone point me to an example or hack an example. This will be great help to the community at large as both CSR and SSR when used in appropriate cases (SSR - first render, CSR -rest of app) they make the app acceptably fast before using other techniques to speed up apps. Infact this would make the other techniques just a bonus (cherry on top)

Please note that my app has a menu at the top and below that is the content which changes for each route navigation. The menu only changes when you login to a logged-In menu.

Just a stupid question: Can the output of react router (first render) be combined with flow-router? What I was able to do is display the output of react router on top followed by the output of flow-router. When I click on a link on react router menu a change happens on flow router output as expected. What I want essentially is a single output that is controlled by flow-router once the first render is done. Like I said it is a stupid question, just thinking out loud.

I’ll preface this by asking what you mean by page load times? Are you referring to transitions between pages (not technically loads), or literally hitting refresh? If you’re not tied to using Blaze, react has server side and client side rendering capabilities, although I’ve not personally worked with react.

SSR with Blaze for serving content is pretty hard in Meteor. If your content is mostly static, there is a workaround you can try, failing that you can always directly intercept the requests with use of WebApp.connectHandlers.use. I’ve tried it with the workaround AND with the direct intercept, load times are < 1 second on a PC.

Meteor’s WebAppInternals global provides a few useful methods/objects for this:

  1. WebAppInternals.getBoilerplate({...}, "web.browser") - this returns the bolierplate HTML required to render a page. You can also pass in web.browser.legacy.
  2. WebAppInternals.staticFilesByArch["web.browser"][pathDef] = { content: populatedHtml }; - you can cache “static” HTML here. If you use a package which enables reactivity on the server you can even update this value when the template you want to render changes. populatedHtml is the combination of the boilerplate + the route specific HTML you’ve generated.

Failing this, you can directly intercept the request using WebApp.connectHandlers.use - however, you ultimately use the same function getBoilerPlate.

May I ask what do you have on the page? It takes 4-6 seconds rendering the page or loading data/images over network or querying from database ? You may want to look at the problem from different angle.

1 Like

@baris I mostly have text and links or button which link to other routes. please note that it is 4-6 seconds when the page is opened from a mobile device and it is not an app that is installed on the device itself. 1-3 seconds on pc. I am open to other ideas to tackle this.

@znewsham Thanks for your reply and advice. I am talking about initial page load, after that transition between pages (thanks for clearing that). If pc load time is < 1 second? How about mobile device load time when you open the page on mobile device browser? I did not mention it above but I am mostly concerned with mobile device performance.

@znewsham, were you able to combine links rendered in the html that was rendered by WebApp.connectHandlers.use with flow-router routes. If so can you please share. Code will be appreciated.

I don’t understand the question, SSR returns the full rendered HTML for the initial view, which includes all the script tags, which include the JS for client side rendering.

I think there is a misconception that SSR will make your page faster. SSR is ok for some cases and doesn’t fit the specs for others. (Examples of SSR not fit for a projects here) May I/we please have a URL of your project. I personally don’t use SSR and I prefer the prerendering which anyway is not a part of the first page load. My scores are more than satisfactory. I am pretty sure your problem is not Meteor, Blaze, React, SSR, CSR. Your problem is somewhere else and there are big chances that if we have a link, things can easily clarify.

1 Like