内容简介:When it comes to great UX, performance is one of the key factors. While working on large scale applications we often encounter situations where we have to compromise user experience to keep our apps fast. But what if we could find a way to build apps that
In a recent post , we discussed building great user experiences using React Suspense. Continuing on that post, we will have a look at how React’s new experimental Concurrent mode helps us develop responsive and fast apps.
When it comes to great UX, performance is one of the key factors. While working on large scale applications we often encounter situations where we have to compromise user experience to keep our apps fast. But what if we could find a way to build apps that are highly performant by default with smooth UX and developer-friendly APIs? React Concurrent Mode is the answer to all of these wishes.
Concurrent React is something that has been under development at Facebook for the past 2 years now. React Fiber, a complete rewrite of React, was done with concurrent mode as central motivation. Though all of the other benefits of React Fiber are worth it themselves but enabling Interruptible Rendering and concurrency is the best amongst them.
React Concurrent Mode - A Theory
What is concurrent React?! As React Docs mention:
Concurrent Mode is a set of new features that help React apps stay responsive and gracefully adjust to the user’s device capabilities and network speed.
Diving deep, Concurrent React can work on multiple tasks at a time and can switch between them depending upon the priority.
The way UI libraries work today is the blocking render approach: when the library has started rendering it cannot go back, no matter how important the next update is. For example, once the browser has started rendering a list of search results, any change in the search input field has to wait until this rendering is finished.
This is not the case anymore with concurrent mode. React starts rendering updates in memory and high priority tasks such as a change in an input field can interrupt that rendering process. So when there is a change, React will let the browser paint the change and the rendering process will continue once this high priority task is completed.
Afterward, upon completion of list rendering, React will commit it to DOM and also be displayed on the screen. In short, With Concurrent React, you can render large amounts of work without blocking user inputs and other high priority tasks on the main thread.
Add ButterCMS to your React app in minutes
Concurrent React can partially render a tree without committing the result to the DOM. For example, React starts rendering an update and it encounters a component that hasn’t finished loading. React will wait for loading to be finished without necessarily rendering some fallback component.
One of the best use cases to demonstrate this will be navigation between different pages. Once a user taps on a link and code to display the component, an appropriate loading state is not available. Here React can wait for a little and keep showing the current screen fully interactive to avoid bad loading state. Once sufficient data or code is available this transition can be completed. Though it can be done via different techniques Concurrent mode makes it more intuitive for developers.
All of this is done by just a few lines of code as React uses heuristics to decide how urgent updates are.
Enabling React Concurrent Mode
As we discussed in our previous post , the developer experience has been at the core of React’s growth. The same goes for Concurrent React, as it is super easy to adopt. Either you’re relying on class components or cruising with hooks, Concurrent React will support both.
Though Concurrent React is used in production at Facebook, for open source users its available in an experimental version of React. To install the experimental version you can use the following command
npm install react@experimental react-dom@experimental
Unlike other features that don’t require any changes in the existing code base, Concurrent mode requires a little change on the root of the React component tree. Here is that small change
import ReactDOM from 'react-dom'; // Current React - Or Blocking Rendering React: // // ReactDOM.render(<App />, document.getElementById('root')); // // Concurrent Mode - Or Interruptible Rendering React: ReactDOM.createRoot( document.getElementById('root') ).render(<App />);
One important notice here, the lifecycle methods that were marked as
UNSAFE_
in previous React releases are truly unsafe with Concurrent Mode. It is highly recommended that you move to new lifecycle methods for a secure transition to Concurrent Mode.
Understanding APIs
In order to fully utilize Concurrent Mode and develop highly responsive interfaces, React gives developers an intuitive API to handle the transition between states and loading states.
useTransition
As discussed above unlike blocking rendering where all updates are treated with the same priority, Concurrent Mode allows developers to de-prioritize slower updates to keep interfaces interactive.
The useTransition
hook allows developers to schedule work after higher priority work.
Continuing with an example of showing search results under input, updates in the input are of highest priority to keep UI interactable. However, fetching data and rendering lists is of low priority. Wrapping our update in
startTransition
communicates to React that these updates are of lower priority and can be scheduled after high priority tasks.
A number of research about handling loading states suggests that gestures like hover and input change should be handled at the highest priority to avoid laggy outlook of the interface. However, a little bit of wait on click and during page transitions is bearable for users. Supporting this research
useTransition
hook allows developers to wait for a time period before displaying any loading state.
Here is full API of
useTransition
hook:
const [startTransition, isPending] = useTransition({ timeoutMs: 2000, });
startTransition
-
Method to wrap low priority updates
isPending
-
Boolean indicating if there is any pending low priority update, likely used for showing loading state.
timeoutMs
-
Milliseconds after the update is marked as pending.
useDeferredValue
React Concurrent Mode allows developers to produce the magic of
useTransition
themselves
.
With
useTransition
we get isPending
available right away, whereas
useDefferedValue
gives us the previous value of state that is in transition. API looks like the following:
const deferredValue = useDeferredValue(value, { timeoutMs: 2000 });
deferredValue
will have a previous version of the value for at most timeout milliseconds.
Add ButterCMS to your React app in minutes
This is commonly used to keep the interface responsive when you have something that renders immediately based on user input and something that needs to wait for a data fetch.
SuspenseList
SuspenseList is a component that wraps a bunch of child Suspense components and gives you handles for how to show all of the various loading states.
In apps that render a number of suspense components together, SuspenseList provides the ability to handle how these components are revealed to the user. Let's take an example to render a list of Blog posts on our page. List Component of our page will look like the following.
<SuspenseList revealOrder="forwards"> <Suspense fallback={<Loader />}> <BlogPostItem id={1} /> </Suspense> <Suspense fallback={<Loader />}> <BlogPostItem id={2} /> </Suspense> <Suspense fallback={<Loader />}> <BlogPostItem id={3} /> </Suspense> ... </SuspenseList>
SuspenseList takes two props:
-
revealOrder: [forwards | backwards | together]
It defines the order in which the children Suspense components should be revealed.-
together
: Quite similar to thePromise.all
API, it renders complete list once all items are available -
forwards/backwards
: This will reveal in sequence one after another, top-down or bottom, even if the component after next is ready it will keep it suspended until the next component is revealed.
-
-
tail: [collapsed | hidden]
It determines how suspended items in the list are shown. By default React will display fallback for all items in the list.- collapsed : It will show only the fallback of the next item in the list
-
hidden
: It will hide all fallbacks in the list
Conclusion
As we see today, React Concurrent Mode will allow front-end engineers to develop fast, reliable and scalable interfaces easily, paving the way for higher standards in user experience.
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。