My FeedDiscussionsHeadless CMS
New
Sign in
Log inSign up
Learn more about Hashnode Headless CMSHashnode Headless CMS
Collaborate seamlessly with Hashnode Headless CMS for Enterprise.
Upgrade ✨Learn more

Virtual DOM based App shell rendering

Jon's photo
Jon
·Oct 8, 2016

When we say "HTML rendering", it may refer to several scenarios. I guess we already have 2 x 3 which is 6 possible ones:

where?                  how?


Browser                 Template Engine
Server        ✕
Gulp                    Virtual DOM

And by "Gulp" I mean "static building". I can be finished with Webpack, npm scripts or even Makefiles. But it's more likely to be Gulp.

Most front-end developers today have known client rendering with template and with libraries like React and Angular. And server side rendering is not strange too since they are very popular in the old days. Also, partial rendering with only App shell was also used frequently in the age of template engines.

Virtual DOM today

Now it's different. People does use template engines as before. Incremental updates with template engines can be tricky. EmberJS is a modern framework with a template engine called Glimmer, but it's not as popular as AngularJS and React.js , which use virtual DOM. I don't known why, but it's the fact. More people are using virtual DOM for new projects thanks to the growing React.js and AngularJS users.

App shell rendering is also useful today. Server side rendering can be slow since virtual DOM based code costs a lot, and client rendering is also not good enough due to the white first screen. As the term "Progressive Web Apps" comes out, App shell rendering may be even more important. Since we already have tasted the benefits of single pages Apps, I guess not many people will prefer rendering half of the page with template engine and the load dynamic content with virtual DOM based libraries.

So I suggest rendering App shell with virtual DOM too. Like React.js does.

App Shell

If you are not familiar with "App shell" or "Progressive Web Apps", you can read docs by Addy Osmani:

https://developers.google.com/web/fundamentals/architecture/app-shell

https://medium.com/google-developers/instant-loading-web-apps-with-an-application-shell-architecture-7c0c2f10c73#.obym6y8d2

And App shell is often the static part of a page, mostly including navigation bar and the footer, which can be rendered without obtaining data from database. It does look like a shell of the page:

Rendering App shell during static building has some benefits:

  • Users see the page earlier, though they see the page without content
  • No cost of rendering of a web server
  • It changes smoother when dynamic content is loaded

Surely we could achieve them with template engines. But by introducing virtual DOM the develop experience can be improved a lot. We can hardly reuse components and do declarative programming with only template engines. Nothing like hot module replacement either.

React.js

Server side rendering is famous in React.js . It can be as simple as calling a function to render the virtual DOM:

https://facebook.github.io/react/docs/environments.html

var React = require('react');
var ReactDOMServer = require('react-dom/server');

var element = React.createElement('div', null, 'Hello World!');
console.log(ReactDOMServer.renderToString(element));

However things can be complicated when Redux is used as the Model. Instead of assembling the props the component need directly, we have to prepare the whole Store of Redux. Read more here:

http://redux.js.org/docs/recipes/ServerRendering.html

I'm not going to the details. But with the help of uni-directional data flow, solutions with React.js can be really flexible.

There's also an interesting aspect here. The HTML page rendered by react-dom/server comes with a checksum field corresponding to the HTML content. When the DOM is rendered again in a browser, it will check it the content is identical with the value in checksum. If they match, identical and no DOM changes, or the old DOM will be replaced. By this solution it could get rid of the flash caused by the DOM replacement during the rendering of first screen.

Vue 2

As Vue 2 is released, SSR is implemented too. Vue does not provide an API like React.js does. It's more like Redux. You can created a renderer with a whole app, and eventually generate HTML with the renderer. The docs is nice:

https://vuejs.org/guide/ssr.html#Hello-World

Angular

I'm not familiar with the solution provided by Angular. But there is a demo using Angular as a renderer of ExpressJS and do server side rendering:

https://youtu.be/MtoHFDfi8FM?t=897

https://github.com/angular/universal-starter/blob/master/src/server.ts#L40

But it can be tricky when we want to render App shell with that. I'm not sure.

Respo

Respos is my side project to explore virtual DOM solution with ClojureScript. It supports App shell rendering too. I enhanced that part as I came to this topics last month.

In React.js , it is supposed that the first screen rendered in a browser is identical with the one generated on the server, by comparing the checksum. But real world problems can be tough and they are probably derived from each other.

Respo can handle the difference between the a Gulp-rendered HTML and a browser-rendered DOM by utilising powers of virtual DOM. It's turned into a patch on the old DOM, so no whole page deletion:

http://respo.site/guide/server-rendering.html

It's more like an experiment so I'm not going to the details. You can find more if interested:

https://github.com/Respo/ssr-stages

Also I updated Respo router to support building pages based on paths of the router, like what I did with React:

https://github.com/Respo/shell-pages

Conclusion

Virtual DOM based App shell rendering is very useful especially in React.js projects. Also we can do more to make use of patching, like i did in Respo, to provide better first screen experience. This will also help in Vue projects.