What do you think of server rendering into innerHTML?

This is continuing of this tread. Sort of…

In my search for ways to build an web app, I have found at least 3 ways todo this:

  1. Let the server do the job (SSR). All rendering at server side. (https://nav.go4webdev.org)
  2. Let the client do most of the job (CSR). Most rendering done in the browser (no example)
  3. Let the server render, but let the client paste content into innerHTML using AJAX (SCSR?))(https://nav2.go4webdev.org)

The main advantages of SCSR (found no valid abbreviation for this) are basically NO flickering. And NO url showing. The main disadvantage is that no history is saved, which also at the same time can be an advantage.

My question is what you think of mixing server side rendering AND populating a rendered page into innerHTML?

I for myself try to move as much “workload” on the client. Servers are expensive, clients do exists.
So if I have an application (which is normal at my work) that is used by more then 10000 users, I need to rent a really big and powerful cloud server to make all the work on the server but the clients are doing nothing than displaying the result. So why not do this work on the 10000 clients and rent a small server?

1 Like

Anything that’s not security sensitive or needing to directly communicate with a database (which would require passwords, hence the security sensitive, etc) can be rendered at the client end without much trouble these days.

Microsoft are slowly but surely dragging Edge mostly into line with other browsers, so you dont have large gaps on what needs to be delivered (or decided) based on browser type anymore; we’ve fairly passed the generational gap of “but what about IE”.

Think the only other time it’d be a concern is if you were trying to have multiple users interacting with a single object, as you then have to handle synchronization issues.

1 Like

I have not thought of this way. Thank you.

Though, I can think of these reasons in favor for server rendering:

  1. Security. A compiled server is more secure.
  2. Go is not that expensive with many connections.
  3. Trade secrets etc are more visible in Javascript.
  4. Speed. Many lines of Javascript code that slows down the site onload.
  5. Go is way simpler than Javascript callback hell.
  6. Maintainability. Go is simpler to maintain.

As my experience is at the beginner status, I may regret these statements when I have learned more…

Should I interpret that traditional web pages is better? Or javascript rendered pages is better?

A javascript rendered webpage simply generates the HTML that a “traditional” webpage uses. It’s no different - at the end of the day, whether you use Javascript or a server side system to generate it, you end up with an HTML file that the browser displays.

I will say that the reliance on Javascript means that anyone who disables javascript in their browser won’t be able to see your page if its generated at the client end; but that movement is somewhat in the past too.

I understand (I think). But when I try to generate pages (normally lists) using Javascript I end up with tons of code for each page. That is the main reason for me to avoid to generate all pages using Javascript.

This is the only generic Javascript code I need for almost all Go rendered pages. Selects the correspondent navigation element in a separate function.

function content(page) {
  sessionStorage.setItem("sub", page);
  fetch("https://nav2.go4webdev.org/content/" + page, {
      headers: {
        "Content-Type": "application/json"
      },
      credentials: "same-origin"
    })
    .then((res) => res.text())
    .then((response) => {
      document.getElementById("content").innerHTML = response;
    })
    .then(() => {
      this.select();
    })
    .catch((error) => alert("Error content:", error))
}

The Go code is even simpler and shorter…

You can do a lot using Javascript, but IMHO it soon become messy and almost impossible to maintain.

Why is code to produce html lists in javascript longer than in GO? That’s not true.

Can you give a concrete example where you think you can make smaller code with GO than with Javascript?

I can make Go more generic and reuse code. As I use Go templates and populate them with sql data just before rendering.

Go is smaller in the sense that it is more reusable than Javascropt and can be more generic. And more maintainable.

Here is the “base.html” that works as a template for all other pages:

<!DOCTYPE html>
<html lang="en">
  {{template "httphead"}}
  <body data-theme="default">
    {{template "icn"}} {{template "nav"}}
    <main>
      {{template "header"}}
      <div id="content"></div>
    </main>
    {{template "httpend"}}
  </body>
</html>

and the content in a Go sub template for navigation. Filled by a generic function for every page:

<ul id="mainlist">
  {{ range . }}
  <li id="{{.menu_id}}" onclick='submenus({{.menu_id}},{{.menu_sub}})' )>
    <svg class="icn56"><use xlink:href="{{.menu_icn}}" /></svg
    ><span>{{.menu_txt}}</span>
  </li>
  {{ end }}
</ul>

The rendering of all pages is also generic.

This is Javascript code that you have to repeat for each and every list or template. At least I have no clue how to make it generic. And I guess you have to add the HTML stuff making the code even bigger.

function filllist1(data) {
  let mainlist = document.getElementById("mainlist");
  data.forEach(function(item) {
    let li = document.createElement('li')
    li.setAttribute('id', item.menu_id)
    li.innerHTML = `<a href="` + item.menu_lnk + `"><svg class="icn56"><use xlink:href="` + item.menu_icn + `"/></svg>` + item.menu_txt + `</a>`
    mainlist.appendChild(li)
  })
}
function filllist2(data) {
  let mainlist = document.getElementById("tsklist");
  data.forEach(function(item) {
    let li = document.createElement('li')
    li.setAttribute('id', item.tsk_id)
    li.innerHTML = `<a href="` + item.tsk_lnk + `"><svg class="icn57"><use xlink:href="` + item.tsk_icn + `"/></svg>` + item.tsk_txt + `</a>`
    mainlist.appendChild(li)
  })
}
....And so on for each and every list/table etc...

Go uses html templates which is very easy to maintain.

But Javascript code must be unique for each table or list. This generates tons of Javascript functions. (disclaimer: I have not found any way to make it generic)

And the main reason I avoid Javascript if I can is that you have to fill the content (table, list or whatever) in a callback function. But this is a personal opinion…

Well your primary problem there is your data structure.

function filllist1(data) {
  let mainlist = document.getElementById("mainlist");
  data.forEach(function(item) {
    let li = document.createElement('li')
    li.setAttribute('id', item.menu_id)
    li.innerHTML = `<a href="` + item.menu_lnk + `"><svg class="icn56"><use xlink:href="` + item.menu_icn + `"/></svg>` + item.menu_txt + `</a>`
    mainlist.appendChild(li)
  })
}

Consider: remove “menu_” from all of the data attributes.

function filllist(data,targetid,classnum) {
  let mainlist = document.getElementById(targetid);
  data.forEach(function(item) {
    let li = document.createElement('li')
    li.setAttribute('id', item.id)
    li.innerHTML = `<a href="` + item.lnk + `"><svg class="icn`+ classnum +`"><use xlink:href="` + item.icn + `"/></svg>` + item.txt + `</a>`
    mainlist.appendChild(li)
  })
}

so instead of calling filllist1(menudata), fillist2(itemdata), you would instead call

filllist(menudata,"mainlist","56");
filllist(taskdata,"tsklist","57");

Yes and perhaps No.

How do you deal with tables with unknown number of columns and unknown and multiple random data types (drop downs, icons etc)? As long as there are predictable structure I agree. But will there be a generic Javascript for totally unpredictable data structure?

Well generally my answer would be “I wouldnt have that many tabular pieces of data on a single page because it washes out the purpose of the page.”

Will there be a generic Javascript for totally unpredictable data structure? Yes, but it’ll be very generic.
Will there be GO templating for a “totally unpredictable data structure”?

Yes and No. The Go html sub template contains the data structure. And you fill this container with data from SQL. But you have to fill the correspondent template.

You can say that the structure is moved from “javascript” to the “html template”. Sort of…

The main advantage is that the never ending dead sea rolls of javascript are moved to separate html tables. Called when you need the page. Very easy to maintain IMO.

IMHO using 100 templates is easier to manage than 100 javascript functions.

<ul id="mainlist">
  {{ range . }}
  <li id="{{.menu_id}}" onclick='submenus({{.menu_id}},{{.menu_sub}})' )>
    <svg class="icn56"><use xlink:href="{{.menu_icn}}" /></svg
    ><span>{{.menu_txt}}</span>
  </li>
  {{ end }}
</ul>

Then it’s not unpredictable…

At this point, you’ve convinced yourself that Javascript is the devil and Go is the angel, so run with it.

We’ll be here to tell you there’s little to no difference if applied equally.

No. I like Javascript until I have to deal with the “callback hell” :slight_smile:

shrug from my perspective, you created a thread about “which way is a good way to do this”, and then spend the entire thread trying to convince other people that there is a certain way that is best. Feels like you came at this with a preconceived conclusion and were just looking for people to nod their heads.

My original question was:

Is it better to let the server do the job (SSR) OR let the server render the page and then fill the innerHTML?

My question is what you think of mixing server side rendering AND populating a rendered page into innerHTML?

I have found several examples using Javascript to build things, but i cannot remember I read about updating a chunk of pre rendered html code. So hence I was doubtful if this was the right way to go.

I did not mention either Go or Javascript from the start. :slight_smile:

That’s fair enough, and the answers you got in posts 2-3 i think probably answer that, but you brought in Go and Javascript in Post 4, and stated your preference for Go, and since then the thread has been about that. :person_shrugging:

1 Like

For me, it’s about source of truth. If it’s dynamic data being loaded from my server, then I see no sense in rendering part of it to have it come back and hit my server again to render data I could have provided the first time. That’s extra bandwidth which doesn’t need to be paid for, nor does the extra rendering time seem worth it (to me).

That being said:

  • If it’s things like paginated data, the main code to render the initial page and the subsequent pages is the same, just how it’s called.
  • If it’s static data (like a menu), then I’ll push the data to the client once and load it client side.
  • If the data is not mine (like a twitter feed, etc), then that will definitely get loaded client side.

@m_hutley’s first paragraph in post #2 covers it a little more succinctly :shifty:

1 Like

To sum up: Thank you all for your input. At the moment I do not agree completely, but as always your good advise will slowly sink in and I may reconsider and start over again.

As I said before rendering at server and fetch the entire rendered html code into innerHTML may not be as common as I thought. Or?

Moving the work to the client is my initial intention to avoid. Mainly to increase the speed and reduce flickering. But also make the code easy to maintain as possible. Everything I can avoid to load into the browser may reduce the user experience. I want to avoid the “spinning wheel” if I can.

Thanks!