Understanding React Fiber Architecture - DZone Web Dev

Understanding React Fiber Architecture – DZone Web Dev

React 16.0 was released with an update to the React core algorithm. This new core architecture is named “Fiber.” Facebook has completely rewritten the internals of React from the ground-up while keeping the public API essentially unchanged; in simple terms, it means only changing the engine of a running car.

With this release, some new features are also added, like Asynchronous Rendering, Portals, Error Boundaries, Fragments (i.e. return array of elements). Incremental rendering is the headline addition to React, which adds the ability to split rendering work into chunks.

React Fiber is the new reconciliation algorithm. Reconciliation is the process of comparing or diffing old trees with a new tree in order to find what is changed or modified. In the original reconciliation algorithm (now called Stack Reconciler), the processing of component trees was done synchronously in a single pass, so the main thread was not available for other UI related tasks like animation, layouts, and gesture handling. Fiber Reconciler has different goals:

  • Ability to split interruptible work in chunks.
  • Ability to prioritize, rebase, and reuse work in progress.
  • Ability to yield back and forth between parents and children to support layout in React.
  • Ability to return multiple elements from render().

Sierpinski triangle rendering using Stack and Fiber:

You may also like: Everything React: Tutorials for Beginners and Experts Alike.

In the above example, there are two different kinds of updates going on — one that makes the triangle narrow and wide which has to happen every 16ms (60 FPS) in order for the animation to look smooth and one that updates the numbers contained inside every single dot, which happens approximately every 1000ms.

fiber (not Fiber with a capital ‘F’) is a JavaScript object that contains information about a component, its input, and output. At any time, a component instance has at most two fibers that correspond to it: the current fiber and the work-in-progress fiber. A fiber can be defined as a unit of work.

Fiber prioritizes work on 7 levels:

  1. NoWork – no work is pending.
  2. SynchronousPriority – for controlled text inputs. Synchronous side-effects.
  3. TaskPriority – completes at the end of the current tick.
  4. AnimationPriority – needs to complete before the next frame.
  5. HighPriority – an interaction that needs to complete pretty soon to feel responsive.
  6. LowPriority – data fetching, or result from updating stores.
  7. OffscreenPriority – Won’t be visible but do the work in case it becomes visible.

React Fiber performs reconciliation in two phases: Render and Commit

1. Lifecycle methods called during render phase:

  • UNSAFE_componentWillMount()
  • UNSAFE_componentWillReceiveProps()
  • getDerivedStateFromProps()
  • shouldComponentUpdate()
  • UNSAFE_componentWillUpdate()
  • render() 

2. Lifecycle methods called during commit phase:

  • getSnapshotBeforeUpdate()
  • componentDidMount()
  • componentDidUpdate()
  • componentWillUnmount() 

The earlier whole reconciliation process was synchronous (recursive), but in Fiber, it is divided into two phases. Render phase (a.k.a. Reconciliation phase) is asynchronous, so three of the lifecycle methods were marked unsafe because putting the code with side-effects inside these methods can cause problems, as lifecycle methods of different components are not guaranteed to fire in a predictable order.

React Fiber uses requestIdleCallback() to schedule the low priority work and requestAnimationFrame() to schedule high priority work.

Problems with Current Implementation:

  • Long-running tasks cause frame drops.
  • Different tasks have different priorities.

So in a nutshell, what makes Fiber interesting?

  • It makes apps more fluid and responsible.
  • In the future, it could parallelize work a.k.a. Time Slicing.
  • It would improve startup time while rendering components using React Suspense.

Fiber is currently available for use but it runs in compatibility mode with the current implementation.

Further Reading

Source link

A Whole Bunch of Places to Consider Contrast in a Single Par...

A Whole Bunch of Places to Consider Contrast in a Single Par…

When we’re thinking about choosing colors in design, we’re always thinking about accessibility. Whenever colors touch, there is contrast and, if we’re talking about the color contrast of text, it needs to be high enough to be readable. This benefits people with a variety of visual disabilities, but also everyone appreciates easily readable text.

Let’s look at the color contrast considerations of just a single paragraph!

A link in a paragraph is probably set in another color to distinguish it as a link.

This link color has insufficient color contrast.

Focusable elements, like links, need to have focus styles as well. By default, we’ll probably get a fuzzy blue outline, so we’ll need to check that that has sufficient color contrast. And if we customize it, that customization will need good color contrast as well.

We’ll also need a hover state for mouse users. Here, I’ll use a background effect that covers about half the text. When you do something like that, the effect needs to be strong enough to be noticeable on hover, and the contrast needs to work on both backgrounds.

It’s not ultra common, but you can style :visited links as well. The styling is somewhat limited (you can’t change opacity or background, for example, because it’s a security concern), but you can change the color. If you do that, it also needs proper contrast. Perhaps we could yank the color differentiation away with color: inherit; to somewhat de-emphasize the link but still indicate it.

Another thing to consider is people highlighting text. On my machine, I have it set up to highlight in an orange color by default (it’s normally a light blue on macOS).

Hopefully, the link colors hold up under any highlight color choice a user might have. They tend to be very light shades.

The text selection colors on macOS Catalina

You can control text selection color through CSS as well with ::selection { background: purple; }. If you’ve done that, you have to check all your colors again to make sure you’ve gotten sufficient contrast.

You can try to take measures into your own hands by changing both color and background.

But note that the link inside the text has lost some of its contrast here. We could keep going down the rabbit hole by setting new colors on a::selection and every other element that has its own colorations within the text.

I’d say a good rule of thumb is to go very light if you’re going to do a custom highlighting color and then not do any further customizations specifically for the selected text.

The idea for this post came from some bug reports I’ve gotten from people reporting that links are hard to read on this site when highlighting text, then focusing a link. I tried fixing it by getting more elaborate, but there are limits to what you can do.

::selection a:focus { /* nope */ }
a:focus::selection  { /* nope */ }
a::selection:focus  { /* nope */ }

It’s better handled by doing less than more.

I recently read Ethan Muller’s Designing for Design Systems post and he makes a similar point about contrast, but across a color spectrum rather than across contexts. For example, your blue link color might work just fine on a few of your design system colors, but not so much on others.

There are a couple things that might help with this.

  • The generic advice of “every time you declare a background-color, declare a color” might help.
  • I’ve used parent-level classes like on-light to change colors of things broadly inside light-colored containers.
  • I’ve used a Sass mixin to help make it easier to change links and the link states, so I’m more apt to do it when changing backgrounds.
@mixin linkStyleText($linkColor) {
  a {
    // Update generic link styles with $linkColor
    &:focus {
      // Also change the hover/focus styles, probably by altering $linkColor programatically

.variation {
   background: $someNewBGColor;

Well, thanks for coming on this journey with me. It just occurred to me that color contrast isn’t quite as simple as checking a single link color on a background to make sure it passes. There might be a dozen or more things to check depending on how many things you colorize in your body copy.

The font in these screenshots is Ibarra Real Nova, which was just recently released on Google Fonts.

Source link

Moving Rainbow Underlines | CSS-Tricks

Moving Rainbow Underlines | CSS-Tricks

I absolutely love the design of the Sandwich site. Among many beautiful features are these headlines with rainbow underlines that move as you scroll. It’s not scroll-jacking — it’s just a minor design feature that uses scroll position to enact a little movement.

To draw the rainbows themselves, we could use a linear gradient with hard-stops, the same kinda concept as drawing stripes in CSS. That’s a big ol’ chunk of CSS, which is fine, but I see they’ve opted for a background-image instead. Here’s that as an SVG, which is 661 bytes (tiny tiny). We can make it look like an underline by setting the background-size to limit the height and position it along the bottom with background-position.

We’ll do it on an inline element so the underline breaks where the words break:

h1 {
  span {
    background-image: url(spectrum.svg);
    background-repeat: repeat-x;
    background-size: 100vw 0.2em;
    background-position: left bottom 5px; 

To animate it, we move the background-position-x. Not a particularly performant thing to animate, but we’re not really animating it anyway — it’s just moving based on scroll position. Rather than manually manipulate the background-position-x, we’ll set it with a custom property, then manipulate the custom property with JavaScript.

background-position-x: var(--scrollPos);

Updating that variable while the page scrolls is easy peezy:

window.addEventListener("scroll", e => {
  let scrollTop = document.body.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop; 
  let newPos = scrollTop + "px";
  document.documentElement.style.setProperty('--scrollPos', newPos);

Here it is working!

See the Pen
Rainbow Underlines
by Chris Coyier (@chriscoyier)
on CodePen.

See that kinda janky line where I’m either using document.body or document.documentElement? That’s a stupid cross-browser thing where the “scrolling element” is different in Safari versus everything else.

While doing this I learned that you can use document.scrollingElement instead to avoid the pain there. I’ll leave a comment in the code about that, but leave the original line for posterity.

Source link