Live data from Hacker News

The Glimmer VM: Boots Fast and Stays Fast

yehudakatz.com

61–70 of 92 posts

Re: The Glimmer VM: Boots Fast and Stays Fast

#61
post #13

Earlier quoted context omitted.

> All development is 'just' re-solving an existing problem with better performance, or 'just' extending an existing algorithm to be more resilient, or 'just' implementing a legacy interface on a new platform. Only this is "re-solving an existing problem with worse performance that we had decades ago (on native), but slightly faster than the previous speeds we achieved having it run with its feet tied". (Where by "fee…

Can you explain how "native" solved the problem of performing minimal MVC-style updates to a UI "decades ago"? Decades ago, we had the Win32 API, which didn't even try to solve this—apps had to roll their own.

>Can you explain how "native" solved the problem of performing minimal MVC-style updates to a UI "decades ago"?

That's not an actual problem people have. Nobody says "what I want is minimal MVC-style updates to a UI". What they want is a fast UI.

So an actual problem is e.g. "having a slow UI" -- and native GUIs solved it "decades ago" by being able to do stuff faster and with less memory and power compared to the web stack.

That said, there were several frameworks that allowed that, especially since MVC didn't magically appear with the web -- the concept originated with Smalltalk. And even "dumb" native GUI frameworks were much closer to the metal than the DOM, and knew how to repaint e.g. only the area of a widget that changed.

Re: The Glimmer VM: Boots Fast and Stays Fast

#62

I love technical articles about how libraries are built. This is really great! I don't follow the last part of the article though. Specifically this part: > We accomplish this by (under the hood) allowing every bit of data that goes into a template to separate the process of computing its current value from the process of determining whether the value might have changed. When you say "bit of data", what exactly do yo…

Thinking about it a bit more I think might know what is going on here. In a traditional KVO view layer (I've worked on a couple of these myself, so my thoughts here are biased) when a property changes it triggers an event. The view layer is listening to this event and so it knows to update the DOM to reflect the changed value. What this means is that the view layer only works with evented KVO objects. What Glimmer ha…

Yep, this is pretty spot on!

At a high level, the Glimmer VM is built on top of two primitives:

1. References (as you describe, an interface implementation to provide the underlying value)

2. Tags, an interface that communicates "is it possible this value has changed?"

Every reference has an associated tag, so once you have a reference, at any time you can ask: Is it possible this thing has changed? If so, what is it's value?

In KVO systems, every time a dynamic value is used in the template, that view usually adds an observer on to the root object. This adds a fair bit of overhead to both rendering and teardown. And if multiple properties change, you have to figure out the optimal re-rendering strategy. (E.g., if a value inside an `if` changes, you probably don't want to re-render it if the conditional also changed from truthy to falsy!)

Today in Ember, the view layer no longer sets up observers. Instead, during rendering, we create a tag for each property. When you mutate a property (this.set('firstName', 'Matthew') for example), two things happen:

1. That tag is marked as dirty.

2. A revalidation of the entire tree is scheduled.

The revalidation process starts from the top of the render tree and walks down, asking every reference/tag "is it possible you've changed?" Because this is just an integer comparison, it's very very fast on modern JavaScript VMs, even if you have lots of data on screen.

The tag is like a Bloom filter, though. It means a change MAY have happened, not that one necessarily did. If the tag is dirty, we do a last chance identity check for primitive values. Only if it has actually changed do we update the DOM.

One nice thing that falls out of this is that the application developer can change as much component state as they'd like at once, and we can avoid doing any expensive computation to figure out the optimal place to start re-rendering (the `if` case I mentioned above). By revalidating the tree from the top down and keeping constant time factors low, you get that optimization "for free."

The other nice thing is that you can express all sorts of cool semantics on top. For example, if you have immutable data you can attach a tag that always says "I'm never modified." If you don't want to do any bookkeeping at all, you can attach a tag that says "Always recheck me to see if I've changed." Best of all, as Yehuda mentioned, you can mix and match these semantics in your components. It also allows the data to drive the change semantics, not the component, which you often don't want to have care about how model data might change.

If this is interesting to you, there is some WIP documentation in the Glimmer VM repository that talks more about the philosophy behind references and tags:

https://github.com/glimmerjs/glimmer-vm/blob/master/guides/0...

https://github.com/glimmerjs/glimmer-vm/blob/master/guides/0...

Re: The Glimmer VM: Boots Fast and Stays Fast

#64
post #47

Earlier quoted context omitted.

For 1) and 2), some frameworks solve the size issue by creating functions for the basic DOM ops, which then get minimized to single character names in production. So in your example, there might be a setNodeAttribute(node, name, val) function, such that the final code isn't `e.setAttribute("id", "bar")` but just `a(e,"id","bar")`, where `a` is the minimized name of setNodeAttribute. There's really not much noise in t…

In terms of #3, if you're yielding until the next requestAnimationFrame, the browser is telling you when you have the opportunity to do more work. Is there something that isn't covered by that? > they're already fast enough that most of the time is spent in rendering, not in javascript DOM manipulation That hasn't been my experience, but it's been awhile since I've benchmarked any of the frameworks in common use. Cha…

BTW if you're curious, browser DOM operations have advanced now to the point that doing work in dom fragments is often slower than just doing it right in the main tree. See, for instance, one of the recent optimizations to the vanillajs implementation of js-framework-benchmark: https://github.com/krausest/js-framework-benchmark/commit/2e...

Re: The Glimmer VM: Boots Fast and Stays Fast

#65
post #17

Apologies ahead of time if this is a stupid question. I am pretty much the walking stereotype of a web developer with very little experience with anything below javascript/ruby/python/php. Considering that Glimmer goes quite far in optimizing stuff, at which point would it perhaps make more sense to just emulate HTML elements on a pixel-level? Or am I vastly underestimating how complex the standard UI elements really…

> Or am I vastly underestimating how complex the standard UI elements really are? Or overestimating how much effort went into Glimmer?

Both, especially the first one.

Re: The Glimmer VM: Boots Fast and Stays Fast

#66
post #61

Earlier quoted context omitted.

Can you explain how "native" solved the problem of performing minimal MVC-style updates to a UI "decades ago"? Decades ago, we had the Win32 API, which didn't even try to solve this—apps had to roll their own.

> Can you explain how "native" solved the problem of performing minimal MVC-style updates to a UI "decades ago"? That's not an actual problem people have. Nobody says "what I want is minimal MVC-style updates to a UI". What they want is a fast UI. So an actual problem is e.g. "having a slow UI" -- and native GUIs solved it "decades ago" by being able to do stuff faster and with less memory and power compared to the w…

> And even "dumb" native GUI frameworks were much closer to the metal than the DOM

GDI wasn't "closer to the metal" than the CSS painting model was. It was reviled for not being close to the metal, in fact (which is why WinG and later DirectX were so important). On Windows NT you had to take a context switch to kernel mode to issue painting commands—how can that be "close to the metal"?

> and knew how to repaint e.g. only the area of a widget that changed

Browsers have been doing this for over a decade.

Actually, I think they should largely stop doing this, since in a double buffered scenario (which has been the norm since the Vista era) partial repaints become complicated, and GPUs are so good at blitting a window-sized area that it's really a non-issue. What are issues are state changes and overdraw, which native frameworks are exceptionally bad at minimizing (this is largely why Skia-GL is underwhelming on Android) and the declarative CSS model is good at supporting. Native frameworks such as Win32 and GTK are held back by having to support this obsolete model. None of the Win32 designers could have imagined that Z-buffers and early fragment tests would become universal.

A meta-note: Pretty much without fail whenever anybody has mentioned some specific thing that Web browsers supposedly fail to do that native can do (the incorrect idea that browsers don't do partial repaints being just the latest instance of it), browsers have been already doing that thing for years. This indicates to me that most people who complain about "native" vs. "Web" haven't really looked into how the Web works. I'm all for acknowledging the Web's shortcomings, but let's concentrate on real issues. (In my view, legacy browser design, which is largely the direct result of trying to be "native", is the biggest problem, not the Web.)

Re: The Glimmer VM: Boots Fast and Stays Fast

#67
post #59

Earlier quoted context omitted.

> This sounds like something written on top of a JavaScript VM, not a VM itself. You can write VMs in languages that are implemented with a VM. > Is it implemented with VM-like techniques? More than that, it is literally a virtual machine. > What does the instruction set look like? IIRC, it's a stack-based VM. Here's the opcodes, I believe: https://github.com/glimmerjs/glimmer-vm/blob/master/packages... (I have mostl…

OK so I guess the VM outputs a virtual DOM tree from a handlebars template, rather than text? I don't really see why you can't do that with a simple tree interpreter, but sure why not. I've implemented template languages in multiple languages. I've also thought of compiling different languages to the same VM with string instructions (IIRC the old Cheetah template language compiles to Python bytecode). I sort of see w…

> so I guess the VM outputs a virtual DOM tree from a handlebars template, rather than text?

As the article mentions, this technique is distinct from virtual DOM. The article is light on what specifically it does though. From the article:

> I'll describe the details of this approach in another post, but the short version is that we compile templates into "append-time" opcodes for a bytecode VM. The process of running the "append-time program" produces the "updating program", which is then run every time the inputs change.

anyway.

> If anything it sounds like there are a lot of other components besides the VM, which weren't really described in the blog post, and I couldn't find any links.

There's a little bit; that is, this post is specifically about Glimmer's VM; Glimmer itself has a few more things, just like React is more than just a virtual DOM implementation. In Glimmer's case, there's glimmer-component, which lets you write web components, and glimmer-application, which lets your register your components into a cohesive whole, etc.

TL;DR: Glimmer as a project is similar to react. It has some significant and novel implementation details that keep it speedy.

Re: The Glimmer VM: Boots Fast and Stays Fast

#68
post #46

Earlier quoted context omitted.

Smalltalk isn't native!

It is a matter of implementation. It was native on the Alto, as the primitives were implemented in microcode, which could be a FPGA nowadays. Also Squeak and Pharo are implemented in Smalltalk.

When people complain about "Web" vs. "native", they are not talking about the Web versus the Xerox Alto.

Re: The Glimmer VM: Boots Fast and Stays Fast

#70
post #27
post #17

Apologies ahead of time if this is a stupid question. I am pretty much the walking stereotype of a web developer with very little experience with anything below javascript/ruby/python/php. Considering that Glimmer goes quite far in optimizing stuff, at which point would it perhaps make more sense to just emulate HTML elements on a pixel-level? Or am I vastly underestimating how complex the standard UI elements really…

Whole websites were done in Flash, not long ago. It was not a good idea.

It feels like a bad dream now, but yeah this really did happen. It was awful.
Post reply on HN