Front-End Web Architecture2017-05-28 // 13 minutes
- Desktop Replacement: Insomniac Games spent significant resources trying to make web tools work for their production pipeline. You can read the fascinating postmortem here, but the short takeaway is that you're going to hit a performance ceiling where web tools simply won't get the job done anymore. Insomniac ultimately abandoned their web tooling after years invested into the effort.
Goals for a new web project
- Readability: Does the physical layout of your project make sense? Would a new team member (or you 2 weeks removed from writing the code) be able to easily figure out what functionality lives where? Do your variable names make sense? Is your logical flow explicitly laid out such that I can easily follow or does your codebase live in the 7th level of abstraction hell?
- Speed: The code will never be actually fast, but it should avoid dumb things like touching the DOM more often than it needs to.
* The only caveat I would offer here is when you're transpiling from a native code base to a browser offering. Emscriptem provides an interesting option here, but you're still going to hit the performance problems I outlined above.
Project Pipeline Components
While the final product is just plain HTML, CSS, and JS, the number of tools used to manage that complexity has ballooned over the last decade (and a half?). As evidence, check out the pie chart provided in this article. Indeed, I am not going to cover every topic but this will provide a handy guide to my thought process as I set up a new project.
- Process Automation: I use Grunt for my build process automation. Here's a useful writeup of Grunt versus other tasks runners. You definitely want to use a task runner, since it saves you a lot of tedium and manual work. However, as long as your choice has all the modules you need, your choice does not matter. Gulp and Broccoli purport to be faster than Grunt, but I've only worked on one project where Grunt's speed was a problem. And for that project, the problem was actually the static site generator Jekyll (which you should avoid and use something that scales well like Hugo).
- JS Frameworks: JS frameworks save you the work of tedious tasks such as data-binding to a viewmodel or controller, templating, etc. You want to select one that isn't opinionated about how you structure your project and that you will spend a minimal amount of time fighting. I personally use Knockoutjs. That said, Angular (v2 only, v1 is a dumpster fire and was completely rewritten in v2), Aurelia, and a few others are good alternatives. If you do decide to try Knockout, I'd recommend this blog as a good resource on avoiding some of the gotchas.
- Testing: I tend to use a combination of Karma for my test runner and Mocha for my testing framework. If you're unclear on the difference, the accepted answer for this stack overflow question is worth a read. Pick a library that has the easiest to read output. They're all accomplishing the same goal.
- CSS Preprocessors: LESS or SASS are both very capable CSS preprocessors. I found LESS simpler to use, but SASS will help you reach your goals with a similar learning curve.
- HTML Templating: I was at first very excited about the Polymer project until I tried to set up a very simple template as a quick test. It's overly complicated, comes with a lot of code weight for features I don't need, and felt very opinionated about how I structure my code. I settled on this grunt task to manage html templating.
- Debugging: I sadly don't have any good recommendations here. Chrome's Developer Tools is lackluster when compared to something like Visual Studio's C/C++ debugger - which itself has plenty of room for improvement. Specifically, finding a js variable that I want to watch involves digging through so much crap that I don't need. My go to debugging method has been mentally working through the code with selective console logs.
React and Vue are currently capturing the next wave of front end zeitgeist. In the interest of full disclosure, I have yet to build anything non-trivial with React or Vue. However, Vue seems to suffer from the "yet another framework" problem when compared to Knockout. Indeed, Vue's own documentation states that Vue is very similar to Knockout. It also argues that Knockout's development has slowed, but that currently isn't a compelling reason to switch as it has all the features I need. Put another way, Knockout is stable - which is very appealing to me.
From the writeups I've read on React, people are excited about it as a replacement (or at least a viable alternative) for native code. As I covered above, I do not expect this to come to fruition to the extent that people want. Indeed, some developers have written at length why they would recommend skipping React. That said, there are some features that are potentially compelling for me. For your consideration, Slant has again provided a very useful comparison. If you are building a project that will manipulate a large number of table rows (think 1000+), Knockout may no longer be an appropriate choice. It is worth noting that I've worked around this by adding in some fancy paging functionality, but that may not be the right solution for your team.
One of the common critiques I've seen against Knockout is that it becomes overly complex in large codebases or slow with large datasets. Indeed, in this benchmark comparison Knockout does not compare well to Reacts in terms of tabular manipulation. However, I'd argue that in inexperienced hands, large codebases can become a mess no matter what tools you use. For my part, I've built a complex web based IDE using Knockout that was both performant and easily maintained.* But if I was building a new app heavily centered around manipulating tabular data, I would definitely take a second look at React.
* Sorry, I can't share. The code lives in a private repo of a former employer.
As a quick review, JS browser apps/sites are appropriate for small to some medium scoped projects. The toolchain I prefer to build manageable, scalable codebases includes the following foundations:
In the first section I contend that there's a limit to what you can realistically do with browser based projects. I can't stand "don't reinvent the wheel" arguments, but the deluge of new JS frameworks have offered ever diminishing returns. The projects I prefer to work on in my spare time are computationally expensive, where JS is a wildly inappropriate choice. Since JS work keeps a roof over my head, I settled on the aforementioned set of tools that allow me to build sites in a sensible manner.
Even if this pipeline doesn't work for you, I hope this post has encouraged you to make sure your selected tech stack is the right tool for the job and to not get caught up in the madness of always chasing the next framework - unless that's how you really want to spend your free time.