How Tubes Uses a Reactive Data System to Optimize Multi‑Screen Rendering

The article explains how Tubes employs a reactive data system to handle multi‑screen rendering, compares loop‑based and reactive approaches, details classic and hash‑table implementations, and demonstrates significant performance gains, offering valuable insights for frontend developers seeking efficient rendering architectures.

Taobao Frontend Technology
Taobao Frontend Technology
Taobao Frontend Technology
How Tubes Uses a Reactive Data System to Optimize Multi‑Screen Rendering

This article details the use of a reactive data system in Tubes, a terminal rendering solution for C‑end scenarios, and explains three different designs and principles of the reactive data system.

Tubes is a terminal rendering solution for C‑end scenarios, supporting flexible expansion, extreme performance, and high stability, widely used in Alibaba platforms such as Double 11, 618 events, and the mobile Taobao homepage.

1. Introduction

A reactive data system means that a program automatically subscribes to the data it uses; when the subscribed data changes, the program responds to the change.

Reactivity is Vue.js's most distinctive feature (formerly called reactive, Vue 3 translates it as reactivity), but Tubes's reactivity principle differs slightly from Vue.js.

2. Role of Reactive Data System in Tubes

Tubes needs a reactive data system to solve the screen‑split rendering problem, i.e., the design issue of multiple Tube executions.

If you are unfamiliar with Tubes, think of it as solving the multiple‑execution problem of Express.js middleware or Webpack loaders.

Split‑screen rendering means that the page first renders first‑screen modules, then second‑screen modules. In Tubes, executing from the first Tube to the last completes one render, similar to the Express middleware chain.

To render the second screen, the Tube execution loop needs to run a second round. Two design schemes were created:

2.1 Scheme 1: Loop‑based implementation

Based on a loop system, Tubes‑Engine provides properties and methods (e.g., current loop count, once) so developers can declare whether a Tube needs to run only once or multiple times.

The issues are that not all Tubes need multiple executions, developers must explicitly declare once, handle loop logic, and deeply understand the loop mechanism.

Only Tubes closely related to first‑screen/second‑screen rendering need multiple executions; other Tubes must explicitly declare they run only once.

Pros: Simple internal implementation, less error‑prone.

Cons:

Need to use once for single‑execution Tubes.

Multiple‑execution Tubes must manage loop count and notify the engine.

Developers must deeply understand the loop mechanism.

Each Tube must handle loop‑related logic.

This scheme is straightforward but imposes high usage cost on developers.

2.2 Scheme 2: Reactive data system implementation

A Tube is an idempotent execution unit: its output becomes the next Tube's input, forming a pipeline.

Tube is an execution unit for rendering; Tubes' design uses simple units to progressively compute results rather than a complex process.

Idempotency means identical input yields identical output; only when input changes does the Tube need to re‑execute.

The key idea is to decide which Tube to re‑execute based on input/output changes, using a reactive data system.

Only when the data a Tube uses changes does the Tube re‑execute in order; if multiple Tubes share the same data, they execute sequentially.

For example, after rendering the first screen, a data Tube requests second‑screen data and stores it; this update triggers the dependent Tubes to re‑execute, forming a dependency‑based execution chain.

Advantages and disadvantages:

Pros:

No extra burden on Tubes (no new methods or attributes).

Tubes are unaware of multiple executions in first‑screen/second‑screen scenarios.

Only Tubes that need to run are executed.

Cons: Complex internal implementation, prone to errors.

Based on these benefits, the reactive data system was chosen.

3. Design and Principles of the Reactive Data System

Historically, three versions were designed; this section focuses on the second and third versions.

3.1 Classic implementation

The three core aspects are reactive data, dependency collection, and dependency triggering.

3.1.1 Reactive Data

The two core components are listeners and dependency storage.

3.1.1.1 Listeners

Common interception methods are Getter/Setter, Proxy, and custom Set/Get API. Tubes uses the custom API to let developers modify raw data without triggering reactivity until a later point.

const data = this.store.get('data'); // bind dependency here
const name = data.name; // this read should not trigger Getter
data.name = name + '!'; // this set should not trigger Setter
this.store.set('data', data); // trigger reactivity here

3.1.1.2 Dependency storage

Dependencies are stored in a __dep__ property attached to the data.

3.1.2 Collecting Dependencies

When to collect: during data reads. Who: the subscribers, which are Tubes (or groups of parallel Tubes). How: example code shows how the current Tube and its group are recorded when ctx.store.get is called.

function get(keypath) {
  this.ctx.tb.store.effect = effect;
  this.ctx.tb.store.tube = tube;
  const res = this.ctx.tb.store.get(keypath);
  this.ctx.tb.store.tube = null;
  this.ctx.tb.store.effect = null;
  return res;
}

Where: dependencies are stored on the data itself, as well as on all parent and child nodes to ensure that changes propagate correctly.

In Tubes, the subscriber is actually a group of parallel Tubes; if only one Tube in the group uses a piece of data, the group contains that single Tube, otherwise it contains multiple Tubes.

3.1.3 Reading Dependencies

Dependencies are triggered when data is modified; the found dependencies are sent to the scheduler for execution.

3.2 Hash‑table based Reactive Data System

This approach stores dependencies in a hash table, improving speed because operations no longer depend on data size.

3.2.1 Why Use a Hash Table

Using a hash table decouples dependency operations from data size, avoiding costly traversal of all child nodes on large data structures.

3.2.2 Storing Dependencies

The keypath serves as the hash key, and the value is a list of dependencies with deduplication.

3.2.3 Reading Dependencies

When a key changes, dependencies for the key, its parents, and its children must be retrieved from the hash table and deduplicated before execution.

3.2.4 Performance Improvement

On low‑end Android devices, read speed improved by 1,349.8× (from 64.79 ms to 0.048 ms) and first‑screen rendering time decreased by 452.6 ms. Detailed benchmark data:

Read speed: 1,349.8× faster (64.79 ms → 0.048 ms).

Write speed: unchanged.

Time complexity: Old algorithm O(N), new algorithm O(1).

Impact on first‑screen speed: improved by 452.6 ms (old 2,924.7 ms → new 1,917.5 ms).

Test environment: low‑end device (Redmi 7, Android 9) on the activity center page.

3.2.5 Summary

The hash‑table approach differs from the classic implementation only in how dependencies are stored, leading to more efficient algorithms.

4. Conclusion

This article introduced the application of a reactive data system in Tubes, described three design versions, and noted that while the project is internal to Alibaba, the concepts are valuable for developers to study and apply.

References

[1] Activity Center page: https://pages.tmall.com/wow/a/act/tmall/dailygroup/2035/wupr?wh_pid=daily-211925

Performance optimizationFrontend Architecturedependency trackingreactive datatubes
Taobao Frontend Technology
Written by

Taobao Frontend Technology

The frontend landscape is constantly evolving, with rapid innovations across familiar languages. Like us, your understanding of the frontend is continually refreshed. Join us on Taobao, a vibrant, all‑encompassing platform, to uncover limitless potential.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.