Don’t let JS turmoil stop you from learning

Alex Standiford:

I have been reluctant to learn a modern JS framework because the network has felt too volatile for me to make a jump, and I really don’t see a point in learning something until I decide to use it in my daily workflow. I invest my time in getting really good at the tools I use instead of pretty good at a bunch of different tools.

Once the community makes this decision, I have a solid reason to learn one of these frameworks. Until then, I’ll just stick with jQuery, even though I dislike it.

This is not an uncommon sentiment, so I thought it would be useful to share my response:

The counter to this is that a number of the frameworks share concepts that are broadly applicable. Understanding what a component is applies to React, Vue, Angular and others. The knowledge transfers, even if the specific implementations are different between them, so there isn’t a reason to avoid learning one. Understanding React makes learning Vue easier, and gives you a better sense of what trade-offs are made when choosing one over the other.

Also, many of these frameworks follow a similar Flux-y pattern (actions up, data down), which is additional knowledge that again transfers regardless of framework. The volatility in the JS community has settled down since a few years ago, and these concepts are broadly applicable, so I’d highly recommend picking one (usually React) and learning it as much for its concepts/approaches as its specific implementation.

Using Observables to Control Render Scheduling

When I talk to other developers about Observables, it’s often hard to explain their benefits because on the surface, they just look like glorified event emitters, but it’s how they compose that make handling dependencies between async events such a breeze. While working on the code snippet editor in WP-Gistpen, I came across an example that shows how easily Observables handle async behavior.

So here’s the setup: building a snippet editor on top of PrismJS and borrowing some code from Dabblet, both from Lea Verou, and using Redux as an Observable of states, we need to rerender the editor as the text changes, keeping the syntax highlighting up to date. We keep the position of the cursor and the value of the editor in the Store, allowing the reducer to be responsible for the complex logic that handling special text editor keystrokes, like enter, tab, etc.

The issue is rendering the editor requires us to track & reset the cursor, as we have to reset the text with the latest from the store and rehighlight it. If we do that while the user is typing, we have the potential to interrupt her, so we need to delay the render until the user is no longer typing. The render itself is scheduled in a requestAnimationFrame, so if the user types before the next frame, we need to cancel the render request and wait until the user stops typing again. Otherwise, when the frame renders, the cursor will jump back to the position it was at when the render was scheduled.

So this is the problem we’re trying to solve.

In brookjs, a component is just a function that takes a DOM element & a stream of props$ and returns a stream of (usually Flux Standard) Actions from the element. Since we’re given an Observable of state, we’re able to get pretty fine control over exactly when the editor renders.

I’m using Kefir, but the same concepts apply any other Observable implementation. Here’s how I solved this:

import Kefir from 'kefir';

export default function EditorComponent(el, props$) {
    const keyup$ = Kefir.fromEvents(el, 'keyup');
    const keydown$ = Kefir.fromEvents(el, 'keydown');

    return props$.sampledBy(keyup$.debounce(150))
        .flatMapLatest(props =>

    function createRenderStream(props) {
        return => {
            const loop = requestAnimationFrame(() => {
                // Update the element

            return () => cancelAnimationFrame(loop);

This problem is obviously solvable in a stateful way, with the view being responsible for holding onto a reference to the render loop, scheduling it in one event callback if a render isn’t scheduled and cancelling the render on the other if it is. We’re not talking about a huge component here, so there’s no reason to think managing this state would be difficult.

But as this component grows in complexity (and it will), colocating the temporal dependencies makes it very easy to reason about how the component changes over time. In the above example, how keyup and keydown events interact with the render cycle is explicit, rather than bouncing between callbacks or methods to see how animations are scheduled and cancelled. There’s zero chance of accidental cancellations or double renders.

Side effects, like updating the DOM, are wrapped in a stream, so they can be handled asynchonrously and cancelled, if needed. Because an Observable comes with its own cleanup code (the function returned at the end of stream‘s callback), when the active Observable is switched, the animation frame request for the previous Observable is cancelled, ensuring the user isn’t interrupted as she types. The props$ stream has control over when the render happens, and flatMapLatest ensures only the newest Observable is being observed at a time, so as the props$ emits new state, previous renders are also cancelled.

brookjs provides some structure around this paradigm, but underneath, this is all that’s happening, and it provides some elegant solutions to thorny async problems. The canonical example is the autocomplete box, sending an AJAX request as a user types and cancelling the previous request. This is explained by Jafar Husain in this great talk.

Even after writing this article, the editor rendering continued to get more complicated, and handling it with Observables allowed me to focus on how particular events interacted with the render cycle, without worrying about how to manage what was actually happening at a given time. Let me know if you think the current implementation is easy to understand.

This post is part of the thread: Project: WP-Gistpen - an ongoing story on this site. View the thread timeline for more context on this post.

I had been working on oEmbed into WP-Gistpen, so I wrote this tutorial on customizing oEmbed content from WordPress yourself. How have you been using the new oEmbed feature in WordPress?

This post is part of the thread: Personal Milestone - an ongoing story on this site. View the thread timeline for more context on this post.