RenderingNG

Ready for the next generation of web content

Chris Harrelson
Chris Harrelson

RenderingNG is a next-generation rendering architecture, that greatly outperforms what came before. RenderingNG was built over more than eight years and represents the collective work of many dedicated Chromium developers. It unlocks a huge amount of potential for fast, fluid, reliable, responsive and interactive web content.

Sketch of the different elements of RenderingNG
RenderingNG

Here, you'll learn what we built, why we built it, and how it works.

North star goal

The north star goal motivating RenderingNG is that the browser engine implementation, and the richness of its rendering APIs, should not be a limiting factor of UX on the web.

You should not need to worry about browser bugs making features unreliable, or breaking your site's rendering.

There should be no mysterious performance cliffs. And, you should not need to work around missing built-in features.

It should just work.

RenderingNG is a huge step towards this north star goal. Before RenderingNG, we could (and did) add rendering features and improve performance, but struggled to make those features reliable for developers, and there were many performance cliffs. Now we have an architecture that systematically squashes many of those problems, and also unblocks advanced features that were not considered feasible before. It:

  • Has rock-solid core features across different platform, device, and operating system combos.
  • Has predictable and reliable performance.
  • Maximizes usage of hardware capabilities (cores, GPU, screen resolution, refresh rates, low-level raster APIs).
  • Performs only the work that's needed to display visible content.
  • Has built-in support for common visual design, animation and interaction design patterns.
  • Provides developer APIs to easily manage rendering costs.
  • Provides rendering pipeline extension points for developer add-ins.
  • Optimizes all content—HTML, CSS, 2D Canvas, 3D canvas, images, video, and fonts.

Comparison with other browser rendering engines

Gecko and Webkit have also implemented most of the same architectural features described in these blog posts, and in some cases even added them before Chromium.

Any browser getting faster and more reliable is cause for celebration and has real impact. The ultimate goal is to advance the baseline for all browsers, so that developers can rely on it.

The pyramid of success

My philosophy is that success is the result of first achieving reliability, then scalable performance, and finally extensibility.

Pyramid with labels Reliability at the base,
Performance in the middle, extensibility at the top

As with a real-life pyramid, each level provides a necessarily-solid foundation for the level above.

Reliability

Sketch showing how with RenderingNG features can be added without a large increase in frustration

If rich and complex user experiences are to be possible at all, the first thing we need is a rock-solid platform. The core features and underpinnings must work correctly, and keep working over time. And it's just as important that those features compose well and don't have strange edge-case behavior or bugs.

Sketch shows circular nature of adding features, getting feedback, improving reliability

For this reason, reliability is the single most important part of RenderingNG. And reliability is the result of good testing, quality feedback loops, metrics, and software design patterns.

To give a sense of how important I think reliability is, we spent most of the last eight years nailing just this part. First, we built a deep knowledge of the system—learning from bug reports where the weak points were and fixing them, bootstrapping comprehensive tests, and understanding the performance needs of sites and limitations of Chromium's performance. Then we carefully and incrementally designed and rolled out key design patterns and data structures. Only then were we ready to add truly next-generation primitives for responsive design, scalability and customization of rendering.

Sketch graph shows reliability, performance, and extensibility improving over time

This is not to say that nothing was improved over that time in Chromium. In fact, the opposite is true! Those years saw a steady and sustained increase in reliability and performance as we refactored and rolled out each improvement step-by-step.

Testing and metrics

Over the past 8 years, we have added tens of thousands of unit, performance and integration tests. In addition, we have developed comprehensive metrics measuring many aspects of how Chromium's rendering behaves in local testing, in performance benchmarks, and in the wild on real sites, with real users and devices.

But no matter how great RenderingNG (or another browser's rendering engine, for that matter) is, it still won't be easy to develop for the web if there are lots of bugs or differences in behavior between browsers. To address this, we also maximize use of Web Platform Tests. Each of these tests verifies a usage pattern of the web platform that all browsers should aim to pass. We also closely monitor metrics for passing more tests over time and increasing core compatibility.

Web Platform Tests are a collaborative effort. For example, Chromium engineers have added only about 10% of the total WPT tests for features of CSS; other browser vendors, independent contributors, and spec authors contribute the rest. It takes a village to raise the interoperable web!

Tests passing in different engines
From wpt.fyi/compat2021, measuring pass rate of WPTs for core features

Good software design patterns

Reliably delivering quality software is, in turn, a whole lot easier if the code is easy to understand, and designed in a way that minimizes the likelihood of bugs. We'll have a lot more to say about RenderingNG's software design in subsequent blog posts.

Scalable performance

Achieving great performance—across the dimensions of speed, memory, and power use— is the next most important aspect of RenderingNG. We want interactions with all web sites to be smooth and responsive, yet not sacrifice the stability of the device.

But we don't just want performance, we want scalable performance—an architecture that performs reliably well on low-end and high-end machines, and across OS platforms. I call this scaling up—taking advantage of all that the hardware device can achieve, and scaling down—maximizing efficiency and reducing demand on the system when needed.

To get there, we needed to make maximum use of caching, performance isolation, and GPU hardware acceleration. Let's consider each in turn. And to make it concrete, let's think about how each of them contributes to the performance of one extremely important interaction on web pages: scrolling.

Caching

In a dynamic, interactive UI platform such as the web, caching is the single most important way to dramatically improve performance. The most well-known kind of caching in a browser is the HTTP cache, but rendering also has many caches. The most important cache for scrolling is cached GPU textures and display lists, which allow scrolling to be extremely fast while minimizing battery drain and working well across a variety of devices.

Caching helps battery life and animation frame rate for scrolling, but even more important is that it unblocks performance isolation from the main thread.

Performance isolation

On modern desktop computers, you never have to worry about background applications slowing down the one you're working in. That's because of preemptive multitasking, which is in turn a form of performance isolation: making sure independent tasks don't slow each other down.

On the web, the best example of performance isolation is scrolling. Even on websites that have lots of slow JavaScript, scrolling can be very smooth, because it runs on a different thread that doesn't have to depend on the JavaScript and layout thread. We put a ton of effort into RenderingNG to make sure that every possible scroll is threaded, through caching that goes well beyond just a display list to more complex situations. Examples include code to represent fixed- and sticky-positioned elements, passive event listeners, and high-quality text rendering.

Sketch shows that with RenderingNG performance stays solid even when JavaScript is very slow.

GPU acceleration

A GPU makes generating pixels and drawing to the screen dramatically faster—in many cases, every pixel can be drawn in parallel with every other pixel, resulting in an enormous speed increase. A key component of RenderingNG is GPU raster and draw everywhere. This uses the GPU on all platforms, and all devices, to hyper-accelerate the rendering and animating of web content. This is especially important on low-end devices or very high-end ones, which often have a much more capable GPU than other parts of the device.

Sketch shows that with RenderingNG performance does not degrade so much.

Extensibility: The right tools for the job

Once we have reliability and scalable performance, we're now ready to build on top a host of tools to help developers extend the built-in parts of HTML, CSS and Canvas, and in ways that do not sacrifice any of that hard-won performance and reliability.

This includes built-in plus JavaScript-exposed APIs for advanced use cases of responsive design, progressive rendering, smoothness and responsiveness, and threaded rendering.

The following open web APIs, championed by Chromium, were made possible by RenderingNG, and were previously considered infeasible.

All of them were developed with open specifications and collaboration with open web partners—engineers at other browsers, experts, and web developers. In subsequent blog posts, we will dive into each of these and explain how RenderingNG makes them possible.

  • content-visibility: allows sites to easily avoid rendering work for offscreen content, and cache rendering for not-currently-shown single page application views.
  • OffscreenCanvas: allows canvas rendering (both the 2D canvas API and WebGL) to run on its own thread for reliably excellent performance. This project is also another major milestone for the web—it's the very first web API that allows JavaScript (or WebAssembly!) to render a single web page document from multiple threads.
  • Container queries: allows a single component to responsively lay itself out, unblocking a whole universe of plug-and-play components (currently an experimental implementation).
  • Origin isolation: allows sites to opt into more performance isolation between iframes.
  • Off-main-thread paint worklets: gives developers a way to extend how elements are painted, with code that runs on the compositor thread.

In addition to explicit web APIs, RenderingNG allowed us to ship several very significant "automatic features" that benefit all sites:

  • Site Isolation: puts cross-origin iframes in different CPU processes, for better security and performance isolation.
  • Vulkan, D3D12, and Metal: takes advantage of lower-level APIs that use GPUs more efficiently than OpenGL.
  • More composited animations: SVG, background color.

Additional upcoming features unblocked by RenderingNG that we're excited about include:

Key projects that make up RenderingNG

Here is a list of the key projects within RenderingNG.

CompositeAfterPaint

CompositeAfterPaint disentangles compositing from style, layout and paint, allowing much-improved reliability and predictable performance, increased throughput, and using less memory without sacrificing performance.

Year Progress
2015 Ship display lists.
2017 Ship new invalidation.
2018 Ship property trees part 1.
2019 Ship property trees part 2.
2021 Completed shipping the project.

LayoutNG

A ground-up rewrite of all layout algorithms, for greatly improved reliability and more predictable performance.

Read more about LayoutNG.

Year Progress
2019 Ship block flow.
2020 Ship flex, editing.
2021 Ship everything else.

BlinkNG

We've refactored and cleaned up the Blink rendering engine into cleanly separated pipeline phases. This allows for better caching, higher reliability, and re-entrant or delayed-rendering features such as content-visibility and container queries.

GPU Acceleration everywhere

GPU acceleration provides an enormous speedup for most content, because every pixel can be processed in parallel. It is also an effective method for improving performance on low-end devices, which tend to still have a GPU.

Year Progress
2014 Canvas support. Shipped on opt-in content on Android.
2016 Ship on Mac.
2017 GPU is used on over 60% of Android page views.
2018 Ship on Windows, ChromeOS, and Android Go.
2019 Threaded GPU rasterization.
2020 Ship remaining Android content.

Threaded scrolling, animations, and decode

A long-term effort to move all scrolling, non-layout-inducing animations, and image decoding off of the main thread. It is ongoing.

Year Progress
2011 Initial support for threaded scroll and animation.
2015 Layer squashing.
2016 Universal overflow scrolling.
2017 Image decodes on compositor thread.
2018 Image Animations on compositor thread.
2020 Always composite fixed-position.
2021 Percentage transform animations, SVG animations.

Viz

A centralized raster and draw process for Chromium that increases throughput, optimizes memory, and allows optimal use of hardware capabilities. It has other benefits less visible to web developers but very visible to users, such as unblocking Site Isolation and decoupling the rendering pipeline from browser UI rendering.

Year Progress
2018 OOP-R shipped on Android, Mac and Windows.
2019 OOP-D shipped. OOP-R shipped everywhere (except Canvas). SkiaRenderer shipped on Linux.
2020 SkiaRenderer shipped on Windows & Android. Vulkan shipped on Android.
2021 SkiaRenderer shipped on Mac (and ChromeOS soon).

Definitions of terms in the chart above:

OOP-D
Out of process display compositor. Display compositing is the same kind of activity as an OS compositor. Out of process means doing it in the Viz process instead of the web page's render process or the browser UI process.
OOP-R
Out of process raster. Raster is converting display lists into pixels. Out of process means doing it in the Viz process instead of the web page's render process.
SkiaRenderer
A new display compositor implementation that can support execution on a range of different underlying GPU APIs such as Vulkan, D3D12 or Metal.

Threaded and accelerated canvas rendering

This is the project that made OffscreenCanvas possible.

Year Progress
2018 Ship OffscreenCanvas.
2019 Ship ImageBitmapRenderingContext.
2021 Ship OOP-R.

VideoNG

VideoNG is a long-term effort to provide efficient, reliable, and high quality video playback on the web.

Year Progress
2014 Introduced a Mojo-based rendering framework.
2015 Shipped Project Butter and video overlays for smoother video rendering.
2016 Shipped unified Android and desktop decoding and rendering pipelines.
2017 Shipped HDR and color-corrected video rendering.
2018 Shipped Mojo-based video decoding pipeline.
2019 Shipped Surface-based video rendering pipeline.
2021 Shipped 4K protected content rendering support on ChromeOS.

Definitions of terms in the chart above:

Mojo
A next-generation IPC subsystem for Chromium.
Surface
A concept that is part of the Viz project design.

Illustrations by Una Kravets.