Isomorphic Javascript is not the Answer yet

tl;dr:

Using Isomorphic Javascript is like opening Pandora’s box; it needs a framework to encapsulate the evil.


Isomorphic Javascript means JavaScript runs on both client-side and server-side. It is invented to solve the slow first-time loading of heavy single page applications.

The Myth of Isomorphic Javascript

Three obvious benefits of Isomorphic Javascript lead to its booming.

Faster first-time loading

It is true, no doubt. Rendering on the server side could make an app loading twice as fast. It is even memory efficient with React’s Virtual DOM mechanism . As far as I can see, this is the only solid benefit of using Isomorphic JavaScript.

Improving SEO

It is no longer true for Google crawler. But it does make a site discoverable for Bing and Yahoo crawlers which are not yet able to execute a site’s JavaScript.

The back-end and front-end sharing the same code

Sounds like I don’t have to write routing and validation twice anymore. It could be true if you were using Node/io.js as backend. But If you are using Rails, the fact is that libraries like React in non-javascript backend act as more or less a template engine and you are not getting the benefit of writing less code. If you want to reuse some piece of code, you should write it in a separate npm package. Some people may assume that using isomorphic can bring npm to the frontend. But isomorphic has nothing to do with npm. You can use npm as frontend package manager with Webpack or Browserify anyway.

What is Wrong with Isomorphic

I have tried isomorphic React and Meteor for about a week, and so far I have encountered two major flaws.

Server and browser are two different environments

A server environment is a black box while a browser environment is exposed. You may have some private API that is only accessible on the server side, and you may need the javascript window object that is only available on the client side. In Meteor, you have something like Meteor.isServer to check the environment, but doesn’t this make the code more complicated and unportable? It reminds me the days when I messed up the logic for guests and authenticated users. Checking environment is simply not part of the application logic. Instead it shall be encapsulated by the architecture (framework). At this point (April, 2015), none of the existing frameworks have achieved such level of encapsulation.

Your code executes twice in the first request

With Isomorphic Javascript, your code is first executed on the server side to render the page. On the browser side, the same code runs again to handle the following AJAX requests. This may cause a re-initialization issue. If you use React, React checks if the target DOM is rendered to avoid re-initialization. But remember React is just a view library, and you will write some code out of React classes. As a result, developers always have to remember to avoid re-initialization while writing the code.

In short, because Isomorphic Javascript merges the backend and frontend logic, developers have to put extra efforts to take care of it.

Solutions?

I think the ideal approach is to dismiss the factors that cause the problem in the first place and a lame way to solve this problem is to throw a patch. If you see the problem here as loading too slow, then just minimize the size of client code and the amount of requests.

Riot 2.0+

Riot is a React-like, 3.5KB user interface library. See How Riot differs from React and Polymer.

Zepto

Zepto is a minimalist JavaScript library with a largely jQuery-compatible API. Zepto is modularized, so selectively pick the part you need.

Pure

Pure is a set of small, responsive CSS modules in a total size of 4.0KB.

Best Practices

These are a set of best practices used by Sitespeed.io to decide if a page is optimized for performance.

Conclusion

Isomorphic Javascript is a smart idea, but it causes some new problems that have not been solved in a framework level yet. I would, however, change my mind if there was a new framework coming out that addresses my concerns. But before that happens, I would stick to the minimalist approaches listed above.