Mozilla’s Rejection of NativeClient Hurts the Open Web

Update: To avoid potential confusion, I will plainly state my overall thesis. The primary benefit of the internet is its openness, connectedness, standardness. By not adopting a technology capable of competing with native apps on iOS, Android, Windows, and Mac, web vendors are preventing important classes of applications such as high-end games and simulations from moving to the open web.

Tom Forsyth writes that clock speeds have grown disproportionately relative to memory access, implying that dynamic languages such as Python or JavaScript, which perform more dependent memory reads, don’t reap the full benefits of Moore’s law. Tom then digs into Data-Oriented Design, whose proponents think primarily about how data is laid out in memory (physical structure) and secondarily about code’s syntax (logical structure). I would have loved to have seen Tom dig into empirical data about the performance of Python and JavaScript across a variety of architectures, especially now that memory subsystems are better and tracing JITs have caught on, but his point stands: memory analysis is critical for low-latency code on today’s architectures. Dynamic languages and virtual tables are at odds with predictable memory access patterns.

How does this apply to the web? Google has developed an x86 sandboxing technology called NativeClient which allows web pages to securely embed x86 code. NativeClient enables Data-Oriented Design on the web, bringing web applications to the same playing field as native applications, especially in domains such as 2D and 3D graphics, video encoding/decoding, audio processing, and simulation.

Mozilla publicly rejects NativeClient and its portable LLVM equivalent, PNaCl. Instead, Mozilla is choosing to invest in JavaScript improvements, predicting that JavaScript performance will come “close enough” to native code performance.

I argue that native code’s primary benefit lies in memory layout and access patterns, not instruction set benefits such as SIMD. With typed arrays, WebGL has brought some degree of explicit memory layout to JavaScript, but it’s still restrictive: typed arrays don’t provide pointers, structures, structure-of-arrays vs. array-of-structures, or variable-width records. These aren’t always easy to specify in C either, but at least NativeClient gives us the possibility to innovate on systems-level design, while preserving the convenience, security, and portability of web-based code.

Predictability is a further advantage of native code. In today’s browser climate, the JavaScript engines have sometimes wildly different performance characteristics. Even if each browser vendor implements its own x86 or LLVM sandbox, it’s unlikely that an application would run differently across browsers.

Beyond performance, NativeClient gives us the ability to target existing code written in C, C++, or even languages like Haskell, to the web. Emscripten and similar “translation taxes” are no longer necessary.

Finally, notice that web-based installation of native code is becoming more prevalent: iOS App Store, upcoming Mac App Store, Games for Windows Live, and Steam have shown it’s possible to make a seamless and compelling native code installation experience. However, these are all restrictive walled gardens! For the open web to compete, it needs a realistic answer to native code.

I believe that Mozilla’s insistence on pushing JavaScript over NativeClient hurts the open web by giving native applications an indefinite leg up. I want the web to support applications as rich as Supreme Commander, a game with thousands of units where each weapon trajectory is physically simulated. NativeClient would give us that capability.

Preemptive response: But NativeClient is x86! Basing the open web on a peculiar, old instruction set is a terrible idea! That’s why I point to LLVM and Portable NativeClient (PNaCl). It’s not a burden to target PNaCl by default, and cross-compile to x86 and ARM if they matter to you.