Standardizing Signals in TC39

Rate this content
Bookmark

Modern web frameworks work with one-way data flow. What is displayed on the screen is a function of the application state, and updates to that state only update the particular part of the DOM to which it relates. Through their own paths, many other web frameworks have arrived at solutions which are analogous to each other, often called “Signals.” Now, a group of signal library authors and maintainers of front-end frameworks are working together in TC39 to standardize some of the core data structures and algorithms that will be required for JS implementations of Signals, and we could use your help pushing JavaScript forward.

This talk has been presented at JSNation US 2024, check out the latest edition of this JavaScript Conference.

FAQ

LittleDan, also known as Daniel, has been working with the TC39 JavaScript Standards Committee since 2016, focusing on projects like BigInt and Private fields using the hashtag.

Signals help in maintaining the DOM in sync with data changes by separating data from the DOM, making it easier to manage state updates and ensuring that only necessary UI components are re-rendered.

Signals in modern JavaScript frameworks facilitate reactivity by allowing state to be managed separately from the DOM, enabling a one-way data flow and reducing the complexity of updating UI when state changes.

Traditional state management often involves distributed state across the DOM or global variables, while signals centralize state with a one-way data flow, allowing for more efficient and organized reactivity.

The TC39 signals proposal is currently at stage 1, indicating it's an early proposal under discussion, with no final agreement on its adoption yet.

Signals use a dependency graph to track state changes, and only re-evaluate computations when necessary, avoiding issues like the glitch problem by using pull-based evaluation.

Developers can join the public chat room, participate in bi-weekly meetings, try out the experimental signals library, and provide feedback by filing issues or commenting on GitHub.

Bloomberg actively contributes to JavaScript standards through its use of web technologies in its applications, aiming to ensure stability and longevity in its systems by adopting common standards.

The signal utils repository provides tools to make signals easier to use, such as decorators for reactive fields and proxy objects for auto-tracking in JavaScript applications.

Standardized signals allow for shared code across different frameworks, enabling framework-agnostic business logic and reducing the need for framework-specific code.

Daniel Ehrenberg
Daniel Ehrenberg
29 min
18 Nov, 2024

Comments

Sign in or register to post your comment.
Video Summary and Transcription
I'll be talking about standardizing signals in TC39. Immediate mode wipes out the whole screen and writes a new one, while retained mode changes only what is necessary. Signals represent a cell of data that can change over time. The correct solution is to topologically sort dependencies and evaluate them in a coherent order. Standard signals allow for code sharing across frameworks and the creation of reusable infrastructure. The signal API is designed to be wrapped by different frameworks. Standards can achieve more portability and reduce the need to lock into specific ecosystems. The API includes a watcher, a set of signals being observed, with a synchronous callback made when the first member becomes potentially dirty. The speaker discusses how signals relate to state management libraries in React and mentions the potential for signals to become a web standard in the future.

1. Introduction to Signal Standardization

Short description:

I'll be talking about standardizing signals in TC39. I work on BigInt and Private using the hashtag. I moved from coastal Catalonia to New York City. The Bloomberg terminal is a big application suite.

I'll be talking about standardizing signals in TC39. To introduce myself, I go by LittleDan on the internet at Bloomberg. I've been working in TC39, the JavaScript Standards Committee, since 2016. And some of the bigger things that I work on include BigInt, the arbitrary size integers that you have in JavaScript, and Private using the hashtag. A couple of years ago, I moved from coastal Catalonia, where you can see my town's tiny coastline. It's sort of shaped like going to a point. And now, dark New York City.

So the Bloomberg terminal is, my job is to work on that, and standards is, you know, ties into that. The Bloomberg terminal is a big application suite that's all based on Chromium on the inside. So it's kind of like an electron app. And so frontend is written in JavaScript, generally. And this is why it's really important to us to push forward the JavaScript language, as well as HTML and CSS, all the web technologies. So going back to basics of why signals, let's think about why we use UI frameworks. So the old model, which maybe many of you aren't familiar with, was PHP on the server, or something different on the server, that has your templating, then you ship something to the client, and that has a little JavaScript script in it, with maybe jQuery or maybe just vanilla JavaScript. And generally, the model was, you have one way of doing the initial way that your page gets rendered, and then you make fixups later on the client. And one of the patterns was the state in the DOM. I have an example on the next slide. And the new model with React and its descendants, sort of all modern frameworks, follow this model where you do templating the same way for initial renders versus subsequent renders, and state rather than being trapped in the DOM or random global variables, can be centralized with one-way data flow.

So here's a simple example. In the old model, you might have a page with a button and counter, so this kind of canned example of reactivity. It's very simple with the vanilla.html on the left, to make it so you have a button, and whenever you click it, you get the content of the span, you increment it, and you write it back into the same place. It looks very terse and clean. But the problem with it is, if you need to do something more complicated when the state changes, for example, persists the fact that the counter incremented on the server, now you have to be kind of reacting to changes in the text content. Because the state is just distributed into the DOM, it becomes really complicated to organize your subsequent computations. On the other hand, in React, you can create your state separately, and your template can be based on that state, so the span includes the count. You never update the span directly, you update the count, and then that's reflected. This allows for different kinds of uses of that, and different dependent computations. This is what signals facilitate solving. So, the key job of UI frameworks is to keep the DOM up to date with the data. That lets you separate the data from the DOM, and then, you know, the framework puts it back.

2. Understanding Signal-based Reactivity

Short description:

The view is a pure function of the model, which applies to the paradigm of React. Most frameworks have the signals concept. Immediate mode wipes out the whole screen and writes a new one, while retained mode changes only what is necessary. Signal-based reactivity combines immediate mode behavior with retained mode performance. Signals represent a cell of data that can change over time. There are common behavior patterns across frameworks, such as auto tracking.

One way to talk about this using old words is the view is a pure function of the model. Maybe you've heard of model view controller, and don't know what it means. This is an old way of talking about the view being the UI, the model being kind of the data under it. This applies completely to the paradigm of React, if you think about it this way.

So, eventually, everyone arrived at kind of a common point in frameworks. If you look at ten years ago, there was a lot of diversity in how to handle this templating situation. But at this point, most frameworks have this signals concept. And React has a similar programming model where you're still basing everything that you do on what you want the final thing to look like, and doing it as a function of that. There are different algorithms for reaching that, but it's ultimately the same kind of pure function model.

Once you have your user interface as a function of the state, there are multiple ways to try to evaluate that. Immediate mode is every time something changes, you wipe out the whole screen, and you write a completely new thing on. So, these are terms used back in the day in game development. Retained mode is different. In retained mode, you're not describing how the whole screen is painted. When some piece of the state changes, you figure out exactly what to change in the UI to get the right result. So, that's a little bit more like my vanilla JS example before. What you get with signal based reactivity is immediate mode behavior with retained mode performance. So, the programming model is you describe how the model, how the data state is converted into the view, the DOM. But when it actually runs, it only updates what's needed. And only if it's needed. It even only does the calculations if they're needed. So, this is also the programming model of React.

Signals represent a cell of data which may change over time. So, you have a mutable base cell called state, which you can create it, get or set values, and then a cached derived computation called a computed signal, which is created by passing in a function, and then you have a way to get the value of it. These are the APIs used in the standard signal proposal. I'll show some examples later. But let's talk about how they work. There's a lot of common behavior across current frameworks. One is auto tracking.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Future Features of JS?!
JSNation 2022JSNation 2022
28 min
Future Features of JS?!
Top Content
Welcome to the future features of JavaScript, including proposals for array operations, throw expressions, records and TPUs, pipeline operators, and more. The talk covers the introduction of type assertions for imported files, non-mutating array operations, and the simplification of error handling. It also explores the concept of immutability with records and TPUs, and the use of the pipeline operator to simplify code. Other proposals include Map.implace, IteratorHelper, slice notation, type annotations, Array UNIQBY, number ranges, and the Function 1 proposal.
ES?.next()
JSNation Live 2021JSNation Live 2021
31 min
ES?.next()
The Talk discusses various proposals for the next version of ECMAScript (ES Next) and the TC39 process. It covers features such as binding syntax, shorthand property assignments, pattern matching, async match, operator overloading, and more. These proposals aim to simplify code, make it more readable, and introduce new functionalities. The Talk also addresses questions about the committee's decision-making process and the experience of being part of the TC39 committee.
ESNext: Proposals To Look Forward To
JSNation Live 2020JSNation Live 2020
9 min
ESNext: Proposals To Look Forward To
ES Next proposal stages include straw person, proposal, draft, candidate, and finished. Optional chaining and null coalescing operators are solutions for handling undefined and null values. Logical assignment and null coalescing operators are seeking advancement to stage four. Decimal type is introduced to address floating point math issues. Cancellation API and abort control are solutions for canceling promise execution. Pattern matching allows matching the shape of a vector and performing actions based on it.
Temporal: Modern Dates and Times in JavaScript
JSNation US 2024JSNation US 2024
22 min
Temporal: Modern Dates and Times in JavaScript
I'll speak today about the temporal proposal, which adds modern date and time handling to JavaScript. Temporal is an API that'll be available in browsers soon and will add a built-in library for dates and times, avoiding the need for external libraries like Moment. It offers strong typing with different types for different data, such as calendar dates with or without time. Temporal objects are immutable and designed to work with JavaScript's internationalization facilities. It addresses deficiencies in the global date object and introduces types like instant and plain types for accurate representation of time and dates across time zones. With the old date, representing a date without a time can be problematic, especially in time zones where midnight is skipped due to daylight saving time. Temporal introduces types like plain date, plain time, plain year month, plain month day, and zone date time to accurately represent different scenarios. Additionally, there is a type called duration for arithmetic operations and unit conversion. Now that I've introduced you to the cast of characters in temporal, it's time to show how to accomplish a programming task. We'll start with an easy task: getting the current time as a timestamp in milliseconds using the instant type. To convert between Temporal types, you can either drop or add information. The two zone date time method is used for conversion and requires adding a time zone and a time. Although Temporal objects are immutable, you can create new objects with replaced components using the with method. Migrating from the old date object to Temporal offers a more reliable solution and avoids potential bugs. Check out the documentation for more details and enjoy using Temporal in your codebase!