It’s been two very active years since the release of ES6, and we’ve seen pretty substantial changes in how we build JavaScript applications. While some complain of fatigue, there’s never been a more exciting time to be a JavaScript engineer. So with the new year upon us, it’s time to look at where we are, and where things are going!
Current Trends
While there are always new ideas that diverge, we’ve seen a fair amount of convergence around the following topics.
Reactive Architectures
While React brought reactive architectures to the mainstream JS developer, efforts had started on a number of projects prior, and efforts continue to provide solid reactive programming principles in JavaScript. ES8 is working to standardize the Observable pattern that was popularized by RxJS, and we see reactivity at the forefront of React, Angular 2, Dojo 2, Preact, Inferno, and many more. Dojo 2 recently replaced RxJS with an ES8 Observable shim.
ES6+ Features, Transpilation, and Patterns
We have seen widespread adoption during development with ES6+ features, improving the language grammar and efficiency in writing applications. In particular, having native promises, generators, async/await and async functions have greatly improved how we author asynchronous code. And yet due to somewhat inconsistent support for ES6 features in browsers, some ES6 features lagging behind ES5 in performance, and ES modules not having a finalized loader specification, the most common approach is still to transpile most code to ES5, whether with the popular Babel project, or the TypeScript transpiler which also includes support for types and interfaces.
Stronger JavaScript?
It’s no secret that we’re huge fans of TypeScript at SitePen, and that we’re helping create Dojo 2, Intern 4, and dgrid 2 in TypeScript. Other approaches to typing such as Flow and Tern.js also exist, with Flow being arguably easier to just type some of your source code, and Tern.js being a library to add type information in normal JavaScript files. For us, the benefits of typing are not just about types, but the extension to interfaces, making it much easier to describe the intent and shape of each API. This becomes incredibly useful with autocomplete/Intellisense in the IDE. However, not everyone has bought into TypeScript or even typing in general, because the development workflow does take time to learn and perfect. We think we have that problem solved very nicely with Dojo 2.
TypeScript is interesting in that types and interfaces are an authoring tool, but are removed from production JavaScript code. We’d love to see a system that can use type information to define constraints and validation rules for forms, which might help add further value. So while we expect that TypeScript adoption will continue to grow, it’s clear that the industry has agreed to disagree at this time.
State, a problem everyone has
State is simply any data that can change. For many years, this was overly complex in JavaScript because the only thing we could really track was function calls, so early versions of this in Dojo 1.x included requiring all state changes to be invoked via calls to get and set methods. Early implementations of watching and observing property changes were slow and brittle. Native getters and setters eventually arrived to the language which made this a bit easier to manage. Later a proposal was made for Object.observe (Dojo 2 and others had shim to support and improve it), but it was withdrawn as a proposal as it had too many issues. In parallel, as reactive programming emerged, the ES8 Observables feature has become the standardized form of RxJS Observables, providing a very efficient way to track changes.
React and first Flux and then Redux have recently got everyone thinking about how to manage state in a predictable manner for JavaScript applications. Angular 2 can be used with Redux, there’s a version of Redux for Vue.js users, and Dojo 2 has solid support for managing state in a manner similar to Redux, where the general approach is to manage the state of your app in an object tree. Changes in the state tree emit an action, and then reducers specify how actions transform the state tree.
Whether you follow this approach or one of many others, it’s become clear that state is a big challenge to get right in application architecture, and we’re still in the early stages of having an approach that makes a lot of sense. We’re at the point of having some very nice native language improvements, coupled with strong influences from other functional languages like Elm and PureScript.
Mobile and Progressive web apps
Progressive Web Apps are user experiences that have the reach of the web, and are reliable, fast, and engaging, giving the experience of a very fast mobile app using pure web technologies. It’s a collection of techniques and best practices that are essential for building web apps that are competitive with native mobile apps.
We’re still in the early days of widespread adoption, but the checklist of features and underlying technologies including Service Workers and Web Components are essential to make the web a completely competitive platform for the future.
In the interim, we still have intermediaries like PhoneGap/Cordova, React Native, NativeScript, IBM MobileFirst, Xamarin and Weex which allow us to use web technologies to create native mobile apps.
Rethinking the DOM
Manipulating the DOM has been one of the largest performance bottlenecks over the years. Early approaches to resolve this included the batching of DOM operations, virtual scrolling grids (e.g. dgrid), virtualized rendering (e.g. abstracting the differences between SVG and Canvas in drawing APIs, and infinite scrolling). When React was announced, they popularized a trend known as the virtual DOM, which allows JavaScript engineers to abstract the API for writing to the DOM into a reactive API that then renders exactly what is needed by an end user. This trend has become increasingly popular with dozens of different virtual DOM implementations in use with React, Dojo 2, Ember, and others. Angular 2 implements a similar reactive approach known as change detection. In Dojo 2 we have chosen to use a VDOM implementation that accepts HyperScript rather than markup or hybrid markup such as JSX. When combined with TypeScript, this gives an incredibly efficient developer experience, as even the VDOM nodes you create, benefit from autocomplete and typings.
In parallel, the web components specification has also evolved, with the two primary features being Custom Elements and the Shadow DOM. Custom Elements are by far the most widely used feature of web components, allowing developers to define the initial configuration and state of a web component. This is performed through the registration of a Custom HTML Element and binding that component to relevant Markup, JavaScript, and CSS information. Its approach is very similar to the work done in the early days of Dijit, except that the API and capabilities are native to the browser.
The Shadow DOM holds the promise of masking a web component’s underlying DOM from the rest of the page, arguably making it safer and easier to work with CSS across components. Alternative approaches such as CSS modules exist to provide similar benefits to the Shadow DOM.
Overall it’s a very exciting time for improvements in how we work with the DOM. Reducing the time our applications spend rendering and repainting/reflowing during changes to application state, improves how we define and build applications.
WebVR
2016 was at a minimum the year VR hit the mainstream and AR was popularized via Pokemon Go. Typically, such major changes to the platform take a while to reach the web, but we’re already seeing significant movement in building a robust WebVR API in browsers, with experimental releases already available for Chrome and Firefox browsers.
While we wait for native WebVR APIs, including game controller functionality to evolve, we also have A-Frame and React VR available. A-Frame extends the feature-rich but challenging to use Three.js library (which wraps the low level WebGL library). AFrame provides a DOM-based API for working with WebVR scenes and features, and React VR takes a React-based approach for building WebVR apps.
Where We’re Heading
Based on the current state of JavaScript, these are some of our expectations for trends emerging in 2017.
High Quality WebVR
2016 was mostly a time to start experimenting with WebVR. 2017 is likely to see substantial progress on WebVR implementations, taking it from experiments to something close to production-ready applications.
We remain hopeful that WebVR will prevent the need for Web to native VR intermediaries.
Decorator Growth
Decorators, a language enhancement that make it possible to annotate and modify classes and properties at design time, were shipped in TypeScript 1.5 to support Angular 2, and are likely to become part of ES8 or ES9. We expect to see significant implementations of decorators amongst popular frameworks. Whilst decorators can significantly reduce the amount of code you need to write, debugging will become a bit more obfuscated by decorator hand-offs. Hopefully developer tools will keep pace with what is effectively a form of AOP on native classes and properties.
Externalization
Dojo and Intern share a strength which is that they aim to provide a consistent environment for wiring together and configuring applications and testing stacks. As the number of dependencies grows, so does the complexity of how we configure applications. We expect this to continue to be a challenge.
Performance focus
Performance is a constantly moving target and while many things are getting faster, the bottlenecks are changing and we’re constantly looking for ways to improve performance. This year will see even more efforts to improve the way we test and measure performance.
React to Reactive
React has become very popular, but more importantly is has mainstreamed reactive programming. Combined with ES6+ features and ES8 Observables, we expect that reactivity will be the standard way in which we think about constructing JavaScript applications going forward.
Functional Programming
Beyond reactive programming, ES6+ (and even ES5) have added numerous functional constructs to JavaScript. As we look for more inspiration to create code without side effects, the patterns of pure and higher order functions will become increasingly important in how we build our applications.
Enterprise Features
Ignored for a bit with the emergence of ES6 and reactive programming, now more than ever, we need coherent support for enterprise features. Dojo 2 treats accessibility, internationalization, large data sets, and data visualizations as top priorities to provide a coherent stack for enterprise development, and we’re unlikely to be alone in making these features a high priority while supporting very modern architecture standards.
We also see enterprises increasing embracing cloud computing, in particular AWS and Google Cloud. In particular features like AWS Lambda are particularly interesting to JS applications. We’re also curious to see how voice recognition and machine learning APIs from cloud providers are leveraged for future web applications, as well as features like web payments.
Choice
With many great open source choices, and with significant similarity and interoperability between them, we don’t expect one project to dominate the mindshare going forward. After all, what we are building are applications with JavaScript. So whether you prefer Vue.js, React/Redux, Dojo 2, Aurelia, Ember, Angular or one of many other great choices, you should find the approach that best matches the goals of your organization and the strengths of your engineering team.