Vocabulary Exercise App – Progressive Enhancement by serverside Rendering with Node.js and React

In the last iteration I suppressed my desire to develop the complex app part of the Vocabulary Exercise Web App and master the technical challenge first. Instead I made the app visualize the data I have in order to give search engines to eat and get visitors and have some substance to show until the whole app is finished. This part still has to be worked on to improve usability and appearance.
In this iteration I solve the technical problems to actually make the app which is more than presenting static data. Until now I am still thinking about how to do justice to the progressive enhancement thing. I still feel that it is the best way to develop web sites for the internet. If you develop a business web site progressive enhancement might be less important. Then, you agree with your users on using a special browser and to have Javascript activated. In this case, there are no search engines which you depend upon to have a successful product and the content does not have to be found. Performance is also no big problem then. You arrange with the users about using Wifi to connect to the server for getting all the big Javascript files for frameworks and libraries. The website is not showing anything until all needed Javascript files are downloaded and the GUI is generated. Since everything is created by Javascript, there is a chance, that something will break and the app does not even show anything. But sure, the Javascript code runs without errors, so that the GUI is not only visible but also usable. But when developing an internet web site there is a much stronger demand for accessibility and usability. There is no one you can dictate your terms to. The site has to be as friendly as possible. Customers, that don’t know you, have to be won over anonymously. Visitors turn away immediately if Javascript loads too long to render something or render faultily. People can not find you if search engines can only see empty pages. It is not only about the few people that have Javascript disabled.
Especially the offline feature requires to do intensive client side rendering since this will not be rendered on the server. But this alone is not enhancement! Enhancement means that content and the layers of structure and appearance are rendered on the server and on the client there is a bevavior layer written in Javascript on top of it. So I need both, rendering on server and client whereas the client is enhanced by the fancy stuff like the ability to run offline or event handling. Since the offline part requires the app to fully run clientside the whole functionality must be generated via Javascript. So I need a framework! Now I know something about Javascript but programming the whole app by myself does not feel productive. The first idea is AngularJs by Google, a framework which is known for building single page apps. But single page apps implement a total different concept than progressive enhancement. They are not designed for playing together with serverside generated content. How to solve this problems? As a software developer it feels very bad to duplicate code for rendering the same content on server and on client. It clearly violates the DRY (don’t repeat yourself) principle and is not efficient. Progressive enhancement is no religion and if it is too expensive to realize there must be made compromises.

But there is a way to render the GUI on both server and client with the same code! What if the Javascript that runs on the client is used on the server too? It is called isomorphic Javascript and can be realized in a different kind of ways. There is the Javascript V8 engine by Google which is famous for its speed and can be compiled on any platform. V8 is also used in Chrome. And there is React, a Javascript library for building user interfaces by Facebook. React was developed by Facebook to build large websites with data that changes. DOM rendering is very slow. So in React there is a virtual DOM, holding the view model and representing the real DOM. When new data is passed to the virtual DOM only the corresponding parts of the real DOM are updated. Therefore it is suggested to modularize the GUI into reusable components which can contain other components like in the DOM elements contains other elements. In SPA (single page application), like AngularJs enable it, serverside rendering is no issue. The SPA architecture lets the whole bunch of Javascript files load and execute on the client. But React works on the server too. For PHP there is V8Js which is a wrapper from PHP to the V8 library. I did not manage to make this running on openshift. I failed at compiling an installing V8 on openshift. The specific build tools from Google are not easy to install if you do not have an own server. Running an own server … great challenge, but I want to stay focussed on programming. Finding shared hosting is also a great problem. In the end you do not want to depend on one sigle webhosting company. Node.js is the solution. On openshift I start another cartridge with node.js on it. I set up a REST service using express that takes a JSON view model and returns HTML and CSS and Javascript rendered by React and bundled by Gulp. Whenever I change the Javascript code the whole React app and its dependencies is bundled into one file. This file is included into the serverside rendered web page. If the Javascript file is executed on the client side it adds event handling to enhance the app. The Javascript that is being executed on the server is the same as the code which is executed on the client. If the offline behavior takes over the JSON view model will be composed from IndexedDB and given to the client side code to rerender certain parts of the GUI.

I added a prototype page to let the user find the missing word. Here is where the exercise begins. The first level is to find missing words which are easy to find. But while searching for the missing word, you have to read definitions of the word that you probably don’t know. That’s the learning part where you expand your word pool.