Grab a coffee, settle in, and read slow. Our review doesn’t miss much.
Web development has always been a fast-moving field — making it hard to keep up with all the browser changes, library releases, and new programming trends that can inundate your mind over the course of the year.
The industry is growing bigger every year, making it harder for the average developer to keep up. So let’s take a step back and review what changed in the web development community in 2018.
This launched a golden age of web development. Many of the most popular tools, libraries, and frameworks today first became popular right after ES2015 was released. Even before major browser vendors supported even half of the new standard, the Babel compiler project allowed thousands of developers to get a head start and experiment with the new features themselves.
Frontend developers for the first time were not beholden to the oldest browser their company supports but were free to innovate at their own pace. Three years and three ECMAScript editions later, this new age of web development shows no signs of slowing down.
New JS language features
Compared to previous editions, ECMAScript 2018 was rather light feature-wise, only adding object rest / spread properties, asynchronous iteration, and Promise.finally, all of which have been supported by Babel and core-js for a while now. Most browser and Node.js all of ES2018 except Edge, which only supports Promise.finally. For many developers, this means that all the language features they need are supported in all browsers they support — some wonder whether Babel is really necessary anymore.
New regular expression features
- Lookbehind assertions, providing the missing complement to the lookahead assertions that have been in the language since all the way back in 1999.
- s (dotAll) flag, which matches any single character except line terminators.
- Named capture groups, which make using regular expressions easier by allowing property-based lookup for capture groups.
- Unicode property escape, which makes it possible to write regular expressions that are aware of unicode.
Although many of these features have had workarounds and alternative libraries for years, none could hope to match the speed that native implementations provide.
New browser features
Although WebAssembly v1 support was added to major browsers last year, it has not yet been widely adopted by the developer community. The WebAssembly Group has an ambitious feature roadmap for features like garbage collection, ECMAScript module integration, and threads. Perhaps with these features, we will start to see widespread adoption in web applications.
Graphics APIs such as Canvas and WebGL have been supported for several years now, but they have always been limited to rendering only in the main thread. Rendering can, therefore, be blocking. And that leads to poor user experiences. The OffscreenCanvas API solves that problem by allowing you to transfer control of a canvas context (2D or WebGL) to a web worker. The worker can then use the Canvas APIs like normal while render seamlessly in the main thread without blocking.
Given the significant performance savings, you can expect chart and drawing libraries to look into supporting it soon. Browser support right now is limited to Chrome, Firefox supports it behind a flag, and the Edge team hasn’t made any public indication of support. You can expect it to pair well with SharedArrayBuffers and WebAssembly, allowing a Worker to render based on data existing in any thread, from code written in any language, all without a janky user experience. This might make the dream of high-end gaming on the web a reality, and allow even more complex graphics in web applications.
There is a major effort underway to bring new drawing and layout APIs to CSS. The goal is to expose parts of the CSS engine to web developers to demystify some of the “magic” of CSS. The CSS Houdini Task Force at W3C, made up of engineers from major browser vendors has been hard at work over the last two years publishing several draft specifications which are now in the final stages of design.
The CSS Paint API is among the first to reach browsers, landing in Chrome 65 back in January. It allows developers to paint an image using a context-like API that can be used wherever an image is called for in CSS. It uses the new Worklet interface, which are basically lightweight, high-performance Worker-like constructs intended for specialized tasks. Like Workers, they run in their own execution context, but unlike Workers, they are thread-agnostic (the browser chooses what thread they run on) and they have access to the rendering engine.
As CSS-Tricks notes, WAAPI offers a significantly better developer experience over just CSS animations, and you can easily log and manipulate the state of an animation defined in JS or CSS. Browser support at the moment is mostly limited to Chrome and Firefox, but there is an official polyfill that does everything you need.
Performance has always been an issue with web animations, and this has been addressed by introducing the Animation Worklet. This new API allows complex animations to run in parallel — meaning higher frame rate animations that aren’t impacted by main thread jank. Animation Worklets follow the same interface as the Web Animations API, but inside the Worklet execution context.
It’s due to be released in Chrome 71 (the next version as of the time of writing), and other browsers likely sometime next year. There’s an official polyfill and example repo available on GitHub if you’d like to try it out today.
The Spectre timing attack wasn’t the only web security scare of the year. The inherent vulnerability of NPM has been written about a lot in the past, and last month we got an alarming reminder. This was not a security breach of NPM itself, but a single package called event-stream that is used by many popular packages. NPM allows package authors to transfer ownership to any other member, and the hacker convinced the owner to transfer it to them. The hacker then published a new version with a new dependency on a package they created called flatmap-stream, which had code designed to steal bitcoin wallets if the malicious package was installed alongside the copay-dash package.
These kinds of attacks will only become more common given how NPM works and the communities’ cavalier propensity to install random NPM packages that appear useful. The community places a great deal of trust on package owners, trust that has been questioned greatly. NPM users should aware of each package they are installing (dependencies of dependencies included), use a lock file to lock down versions and sign up for security alerts like those provided by Github.
NPM is aware of the security concerns of the community and they have taken steps to improve it over the last year. You can now secure your NPM account with two-factor authentication, and NPM v6 now includes a security audit command.
The Reporting API is a new standard that aims to make it easier for developers to discover problems with their applications by alerting when issues happen. If you’ve used the Chrome DevTools console within the last few years you might have seen the [intervention] warning messages for using obsolete APIs or doing potentially unsafe things. These messages have been limited to the client, but now you can report them to analytics tools using the new ReportingObserver.
There are two kinds of reports:
- Deprecations, which warn you when you’re using an obsolete API and tell you when it’s expected to be removed. It will also tell you filename and line number of where it was used.
- Interventions, which warn you when you’re using an API in an unintended, dangerous, or insecure way.
While tools like LogRocket give developers insight into errors in their applications. Until now, there hasn’t been any reliable way for third-party tools to record these warnings. This means issues either go unnoticed or manifest themselves as difficult-to-debug error messages. Chrome currently supports the ReportingObserver API, and other browsers will support it soon.
For those unaware, there is no unified CSS3 specification analogous to ECMAScript. The last official unified standard was CSS2.1, and CSS3 has come to refer to anything published after that. Instead, each section is standardized separately as a “CSS Module”. MDN has an excellent overview of each module standard and their status.
While there has been talk in the past of adding support for nested rules to CSS (like LESS and SASS), those proposals didn’t go anywhere. In July the CSS working group at W3C decided to take another look at the proposal, but it’s unclear if it’s a priority at all.
Node continues to make excellent progress keeping up with ECMAScript standards and as of December, they support all of ES2018. On the other hand, they have been slow to adopt the ECMAScript module system and thus are missing a critical feature that is preventing feature parity with browsers, which have supported ES modules for over a year now. Node actually added experimental support in v11.4.0 behind a flag, but this requires that files use the new .mjs extension, leading to concerns about slow adoption and what impact this would have on Node’s rich package ecosystem.
If you’re looking to get a jump start and you’d rather not use the experimental build-in support, there’s an interesting project from the creator of Lodash called esm which gives Node ES module support with better interoperability and performance than the official solution.
Tools and Frameworks
React had two notable releases this year. React 16.3 shipped with support for a new set of lifecycle methods and a new official Context API. React 16.6 added a new feature called “Suspense” that gives React the ability to suspend rendering while components wait for a task to be completed like data fetching or code splitting.
The most talked about React topic this year was the introduction of React Hooks. The proposal was designed to make it easier to write smaller components without sacrificing useful features that were until now limited to class components. React will ship with two built-in hooks, the State Hook, which lets functional components use state, and the Effect Hook, which lets you perform side effects in function components. While there is no plan to remove classes from React, the React team clearly intends Hooks to be central to the future of React. After they were announced, there was a positive reaction from the community (some might say overhyped). If you’re interested in learning more, check out Dan Abramov’s blog post comprehensive overview.
Next year React plans on releasing a new feature called Concurrent mode (formerly known as “async mode” or “async rendering”). This would allow React to render large component trees without blocking the main thread. For large apps with deep component trees, the performance savings could be significant. It’s unclear exactly what the API looks like at the moment, but the React team is aiming to finalize it soon and release sometime next year. If you’re interested in adopting this feature, make sure your codebase is compatible by adopting the new lifecycle methods released in React 16.3.
Webpack 4 was released in February, bringing huge performance improvements, build-in production and development modes, easy to use optimizations like code splitting and minification, experimental WebAssembly support, and ECMAScript module support. Webpack is now much easier to use than previous versions and previously complicated features like code splitting and optimization are now quite simple to set up. Combined with Typescript or Babel, webpack remains the bedrock tool for web developers and it seems unlikely a competitor will come along and replace it in the near future.
Babel 7 was released this August, the first major release in almost three years. Major changes include faster build times, a new package namespace, and deprecation of the various “stage” and yearly ECMASCript preset packages in favor of preset-env, which vastly simplifies configuring Babel by automatically including the plugins you need for the browsers you support. This release also adds automatic polyfilling, which removes the need to either import the entire Babel polyfill (which is rather large) or explicitly importing the polyfills you need (which can be time-consuming and error-prone).
Babel also now supports the Typescript syntax, making it easier for developers to use Babel and Typescript together. Babel 7.1 also added support for the new decorators proposal, which is incompatible with the obsolete proposal widely adopted by the community but matches what browsers will be supporting. Thankfully, the Babel team has published a compatibility package that will make upgrading easier.
A common complaint is that applications that use Electron tend to use too much memory since each app packages an entire instance of Chrome (which is very memory-intensive). Carlo is an Electron alternative from Google that uses the locally installed version of Chrome (which it requires), resulting in a less memory hungry application. Electron itself hasn’t made much progress with improving performance, and recent updates have focused on updating the Chrome dependency and small API changes.
Recent releases have added more developer-friendly error formatting and powerful refactoring features like automatic import updating and import organizing, among others. At the same time, work continues on improving the type system with recent features like conditional types and unknown type.
Plug: LogRocket, a DVR for web apps
LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.