Preface

I began my web development career many years ago, when I was hired as an administrative assistant at the University of California, San Diego. One of my job duties was to maintain the department website. It was the time of webmasters, table-based layouts, and CGI-BIN(s), and Netscape Navigator was still a major player in the browser market. As for my level of technical expertise, I think the following anecdote paints a clearer picture of my inexperience than Bob Ross’s desire for a happy little tree. I can clearly remember being concerned that if I sent an email with misspellings, the recipient would see my mistakes underlined in red the same way I saw them. Fortunately, I had a patient supervisor who assured me this was not the case and then handed me the keys to the website!

Fast-forward 15 years, and now I am an industry “expert” speaking at conferences, managing open source projects, coauthoring books, etc. I ask myself, “Well… How did I get here?” The answer to that question is not by letting the days go by—at least, not entirely so.

Why Isomorphic JavaScript

The latest chapter in my web journey is working on the Platform team at WalmartLabs, and it is here that my adventures in isomorphic JavaScript began. When I started at WalmartLabs I was placed on a team that was tasked with creating a new web framework from scratch that could power large, public-facing websites. In addition to meeting the minimum requirements for a public-facing website, SEO support, and an optimized page load, it was important to our team to keep UI engineers—myself included—happy and productive. The obvious choice for appeasing UI engineers would have been to extend an existing single-page application (SPA) solution. The problem with the SPA model is that it doesn’t support the minimum requirements out of the box (see “The Perfect Storm: An All-Too-Common Story” and “Single-page web application” for more details)—so we decided to take the isomorphic path. Here is why:

  • It uses a single code base for the UI with a common rendering lifecycle. This means no duplication of efforts, which reduces the UI development and maintenance cost, allowing teams to ship features faster.

  • It renders the initial response HTML on the server for a faster perceived page load, because the user doesn’t have to wait for the application to bootstrap and fetch data before the page is rendered in the browser. The improved perceived page load is even more important in areas with high network latency.

  • It supports SEO because it uses qualified URLs (no fragments) and gracefully degrades to server rendering (for subsequent page requests) for clients that don’t support the History API.

  • It uses distributed rendering of the SPA model for subsequent page requests for clients that support the History API, which lessens application server loads.

  • It gives UI engineers full control of the UI, be it on the server or the client, and provides clear lines of separation between the back- and frontends, which helps reduce operating costs.

Those are the primary reasons our team went down the isomorphic JavaScript path. Before we get into the details of isomorphic JavaScript, though, it is good idea to provide some background about the environment in which we find ourselves today.

The Evolution of a Platform

It is hard to imagine, but the Web of today did not always exist. It did not always have JavaScript or CSS, either. They were introduced to browsers to provide an interaction model and a separation of concerns. Remember the numerous articles advocating the separation of structure, style, and behavior? Even with the addition of these technologies, the architecture of applications changed very little. A document was requested using a URI, parsed by the browser, and rendered. The only difference was the UI was a bit richer thanks to JavaScript. Then Microsoft introduced a technology that would be the catalyst for transforming the Web into an application platform: XMLHttpRequest.

Ajax: Rise of an Application Platform

As much disdain as frontend engineers have for Microsoft and Internet Explorer, they should also harbor an even greater sense of gratitude. If it weren’t for Microsoft, frontend engineers would likely have much less fulfilling careers. Without the advent of XMLHttpRequest there would not be Ajax; without Ajax we wouldn’t have such a great need to modify documents; without the need to modify documents we wouldn’t have the need for jQuery. You see where this is going? We would not have the rich landscape of frontend MV* libraries and the single-page application pattern, which gave way to the History API. So next time you are battling Internet Explorer, make sure to balance your hatred with gratitude for Microsoft. After all, they changed the course of history and laid the groundwork that provides you with a playground in which to exercise your mind.

Ajax: Accumulation of Technical Debt

As influential as Ajax was in shaping of the web platform, it also left behind a path of destruction in the form of technical debt. Ajax blurred the lines of what had previously been a clearly defined model, where the browser requests, receives, and parses a full document response when a user navigates to a new page or submits form data. This all changed when Ajax made its way into mainstream web development. An engineer could now respond to a user’s request for more data or another view without the overhead of requesting a new document from the server. This allowed an application to update regions of a page. This ability drastically optimized both the client and the server and vastly improved the user experience. Unfortunately, client application architecture was virtually nonexistent, and those tasked with working in the view layer did not have the background required to properly support this change of paradigm. These factors compounded with time and turned applications into maintenance nightmares. The lines had been blurred, and a period of painful growth was about to begin.

The Perfect Storm: An All-Too-Common Story

Imagine you are on a team that maintains the code responsible for rendering the product page for an ecommerce application. In the righthand gutter of the product page is a carousel of consumer reviews that a user can paginate through. When a user clicks on a review pagination link, the client updates the URI and makes a request to the server to fetch the product page. As an engineer, this inefficiency bothers you greatly. You shouldn’t need to reload the entire page and make the data calls required to fully rerender the page. All you really need to do is GET the HTML for the next page of reviews. Fortunately you keep up on technical advances in the industry and you’ve recently learned of Ajax, which you have been itching to try out. You put together a proof of concept (POC) and pitch it to your manager. You look like a wizard. The POC is moved into production like all other POCs.

You are satisfied until you hear of a new data-interchange format called JSON being espoused by the unofficial spokesman of JavaScript, Douglas Crockford. You are immediately dissatisfied with your current implementation. The next day you put together a new POC using something you read about called micro-templating. You show the new POC to your manager. It is well-received and moved into production. You are a god among mortal engineers. Then there is a bug in the reviews code. Your manager looks to you to resolve the bug because you implemented this magic. You review the code and assure your manager that the bug is in the server-side rendering. You then get to have the joyful conversation about why there are two different rendering implementations. After you finish explaining why Java will not run in the browser, you assure your manager that the duplication was worth the cost because it greatly improved the user experience. The bug is then passed around like a hot potato until eventually it is fixed.

Despite the DRY (don’t repeat yourself) violations, you are hailed as an expert. Slowly the pattern you implemented is copied throughout the code base. But as your pattern permeates the code base, the unthinkable happens. The bug count begins to rise, and developers are afraid to make code changes out of fear of causing a regression. The technical debt is now larger than the national deficit, engineering managers are getting pushback from developers, and product people are getting pushback from engineering managers. The application is brittle and the company is unable to react quickly enough to changes in the market. You feel an overwhelming sense of guilt. Luckily, you have been reading about this new pattern called single-page application…

Client Architecture to the Rescue

Recently you have been reading articles about people’s frustration with the lack of architecture in the frontend. Often these people blame jQuery, even though it was only intended to be a façade for the DOM. Fortunately, others in the industry have already faced the exact problem you are facing and did not stop at the uninformed critiques of others. One of them was Jeremy Ashkenas, the author of Backbone.

You take a look at Backbone and read some articles. You are sold. It separates application logic from data retrieval, consolidates UI code to a single language and runtime, and significantly reduces the impact on the servers. “Eureka!” you shout triumphantly in your head. This will solve all our problems. You put together another POC, and so it goes.

What Happened to Our Visits?

You are soon known as the savior. Your newest SPA pattern is adopted company-wide. Bug counts begin to drop and engineering confidence returns. The fear once associated with shipping code has practically vanished. Then a product person comes knocking at your door and informs you that site visits have plummeted since the SPA model was implemented. Welcome to the joys of the hash fragment hack. After some exhaustive research, you determine that search engines do not take into account to the window.location.hash portion of the URI that the Backbone.Router uses to create linkable, bookmarkable, shareable page views. So when a search engine crawls the application, there is not any content to index. Now you are in an even worse place than you were before. This is having a direct impact on sales. So you begin a cycle of research and development once again. It turns out you have two options. The first option is to spin up new servers, emulate the DOM to run your client application, and redirect search engines to these servers. The second option is to pay another company to solve the problem for you. Both options have a cost, which is in addition to the drop in revenues that the SPA implementation cost the company.

Isomorphic JavaScript: A Brave New World

The previous story was spun together from personal experience and stories that I have read or heard from other engineers. If you have ever worked on a particular web application for long enough, then I am sure you have similar stories and experiences. Some of these issues are from days of yore and some of them still exist today. Some potential issues were not even highlighted—e.g., poorly optimized page loads and perceived rendering. Consolidating the route response/rendering lifecycle to a common code base that runs on the client and server could potentially solve these problems and others. This is what isomorphic JavaScript is all about. It is about taking the best from two different architectures to create easier-to-maintain applications that provide better user experiences.

The Road Ahead

The primary goal of this book is to provide the foundational knowledge required to implement and understand existing isomorphic JavaScript solutions available in the industry today. The intent is to provide you with the information required to make an informed decision as to whether isomorphic JavaScript is a viable solution for your use case, and then allow some of the brightest minds in the industry to share their solutions so that you do not have to reinvent the wheel.

Part I provides an introduction to the subject, beginning with a detailed examination of the different kinds of web application architectures. It covers the rationale and use cases for isomorphic JavaScript, such as SEO support and improving perceived page loads. It then outlines the different types of isomorphic JavaScript applications, such as real-time and SPA-like applications. It also covers the different pieces that make up isomorphic solutions, like implementations that provide environment shims/abstractions and implementations that are truly environment agnostic. The section concludes by laying the code foundation for Part II.

Part II breaks the topic down into the key concepts that are common in most isomorphic JavaScript solutions. Each concept is implemented without the aid of existing libraries such as React, Backbone, or Ember. This is done so that the concept is not obfuscated by a particular implementation.

In Part III, industry experts weigh in on the topic with their solutions.

Conventions Used in This Book

The following typographical conventions are used in this book:

Italic

Indicates new terms, URLs, email addresses, filenames, and file extensions.

Constant width

Used for program listings, as well as within paragraphs to refer to program elements such as variable or function names, class, data types, statements, and keywords. Also used for module and package names and for commands and command-line output.

Constant width bold

Shows commands or other text that should be typed literally by the user.

Constant width italic

Shows text that should be replaced with user-supplied values or by values determined by context.

Tip

This element signifies a tip or suggestion.

Note

This element signifies a general note.

Warning

This element indicates a warning or caution.

Using Code Examples

Supplemental material (code examples, exercises, etc.) is available for download at https://github.com/isomorphic-javascript-book.

This book is here to help you get your job done. In general, if example code is offered with this book, you may use it in your programs and documentation. You do not need to contact us for permission unless you’re reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing a CD-ROM of examples from O’Reilly books does require permission. Answering a question by citing this book and quoting example code does not require permission. Incorporating a significant amount of example code from this book into your product’s documentation does require permission.

We appreciate, but do not require, attribution. An attribution usually includes the title, author, publisher, and ISBN. For example: “Building Isomorphic JavaScript Apps by Jason Strimpel and Maxime Najim (O’Reilly). Copyright 2016 Jason Strimpel and Maxime Najim, 978-1-491-93293-3.”

If you feel your use of code examples falls outside fair use or the permission given above, feel free to contact us at .

Safari® Books Online

Note

Safari Books Online is an on-demand digital library that delivers expert content in both book and video form from the world’s leading authors in technology and business.

Technology professionals, software developers, web designers, and business and creative professionals use Safari Books Online as their primary resource for research, problem solving, learning, and certification training.

Safari Books Online offers a range of plans and pricing for enterprise, government, education, and individuals.

Members have access to thousands of books, training videos, and prepublication manuscripts in one fully searchable database from publishers like O’Reilly Media, Prentice Hall Professional, Addison-Wesley Professional, Microsoft Press, Sams, Que, Peachpit Press, Focal Press, Cisco Press, John Wiley & Sons, Syngress, Morgan Kaufmann, IBM Redbooks, Packt, Adobe Press, FT Press, Apress, Manning, New Riders, McGraw-Hill, Jones & Bartlett, Course Technology, and hundreds more. For more information about Safari Books Online, please visit us online.

How to Contact Us

Please address comments and questions concerning this book to the publisher:

  • O’Reilly Media, Inc.
  • 1005 Gravenstein Highway North
  • Sebastopol, CA 95472
  • 800-998-9938 (in the United States or Canada)
  • 707-829-0515 (international or local)
  • 707-829-0104 (fax)

We have a web page for this book, where we list errata, examples, and any additional information. You can access this page at http://bit.ly/building-isomorphic-javascript-apps.

To comment or ask technical questions about this book, send email to .

For more information about our books, courses, conferences, and news, see our website at http://www.oreilly.com.

Find us on Facebook: http://facebook.com/oreilly

Follow us on Twitter: http://twitter.com/oreillymedia

Watch us on YouTube: http://www.youtube.com/oreillymedia

Acknowledgments

Jason Strimpel

First, I have to thank my wife Lasca for her patience and support. Every day I am grateful for your intellect, your humor, your compassion, and your love. I feel privileged and humbled that you chose to go through life with me. You make me an infinitely better person. Thanks for loving me.

Next, I would like to thank my coauthor and colleague Max. Without your passion, knowledge, ideas, and expertise my efforts would have fallen short. Your insights into software architecture and observations inspire me daily. Thank you.

I would also like to thank my editor Ally. Your ideas, questions, and edits make me appear to be a much better writer than I actually am in reality. Thank you.

Finally, I would like to thank all contributors to Part III who have graciously given their time and chosen to share their stories with the reader. Your chapters help showcase the depth of isomorphic JavaScript and the actual diversity of solutions. Your unique solutions illustrate the true ingenuity at the heart of every engineer. Thank you.

Maxime Najim

Foremost, I’d like to thank my family—my wife Nicole and our children Tatiana and Alexandra—for their support and encouragement throughout the writing and publishing of this book.

I’m also eternally grateful to Jason for asking me to coauthor this book with him. I felt privileged and honored to write and collaborate with you throughout this book. This was a once-in-a-lifetime opportunity, and it was your ingenuity, knowledge, and hard work that made this opportunity into a reality. I can’t thank you enough. Likewise, a big thanks goes to our editor Allyson for her invaluable support and consultation throughout this process.

And finally, a big special thanks to the contributors to Part III who took time from their busy schedules to share their stories and experiences with us all. Thank you!

Get Building Isomorphic JavaScript Apps now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.