this re-render completes, React will show it on the screen. However, if it suspends (the results for ` "ab" ` have not loaded yet), React will abandon this rendering attempt, and retry this re-render again after the data has loaded. The user will keep seeing the stale deferred value until the data is ready. 

The deferred “background” rendering is interruptible. For example, if you type
into the input again, React will abandon it and restart with the new value.
React will always use the latest provided value.

Note that there is still a network request per each keystroke. What’s being
deferred here is displaying results (until they’re ready), not the network
requests themselves. Even if the user continues typing, responses for each
keystroke get cached, so pressing Backspace is instant and doesn’t fetch
again.

* * *

###  Indicating that the content is stale

In the example above, there is no indication that the result list for the
latest query is still loading. This can be confusing to the user if the new
results take a while to load. To make it more obvious to the user that the
result list does not match the latest query, you can add a visual indication
when the stale result list is displayed:

    
    
    <div style={{  
    
    
      opacity: query !== deferredQuery ? 0.5 : 1,  
    
    
    }}>  
    
    
      <SearchResults query={deferredQuery} />  
    
    
    </div>

With this change, as soon as you start typing, the stale result list gets
slightly dimmed until the new result list loads. You can also add a CSS
transition to delay dimming so that it feels gradual, like in the example
below:

App.js

App.js

Reset  [ Fork
](https://codesandbox.io/api/v1/sandboxes/define?undefined&environment=create-
react-app "Open in CodeSandbox")

    
    
    import { Suspense, useState, useDeferredValue } from 'react';
    import SearchResults from './SearchResults.js';
    
    export default function App() {
      const [query, setQuery] = useState('');
      const deferredQuery = useDeferredValue(query);
      const isStale = query !== deferredQuery;
      return (
        <>
          <label>
            Search albums:
            <input value={query} onChange={e => setQuery(e.target.value)} />
          </label>
          <Suspense fallback={<h2>Loading...</h2>}>
            <div style={{
              opacity: isStale ? 0.5 : 1,
              transition: isStale ? 'opacity 0.2s 0.2s linear' : 'opacity 0s 0s linear'
            }}>
              <SearchResults query={deferredQuery} />
            </div>
          </Suspense>
        </>
      );
    }
    
    

Show more

* * *

###  Deferring re-rendering for a part of the UI

You can also apply ` useDeferredValue ` as a performance optimization. It is
useful when a part of your UI is slow to re-render, there’s no easy way to
optimize it, and you want to prevent it from blocking the rest of the UI.

Imagine you have a text field and a component (like a chart or a long list)
that re-renders on every keystroke:

    
    
    function App() {  
    
    
      const [text, setText] = useState('');  
    
    
      return (  
    
    
        <>  
    
    
          <input value={text} onChange={e => setText(e.target.value)} />  
    
    
          <SlowList text={text} />  
    
    
        </>  
    
    
      );  
    
    
    }

First, optimize ` SlowList ` to skip re-rendering when its props are the same.
To do this, [ wrap it in ` memo ` : ](/reference/react/memo#skipping-re-
rendering-when-props-are-unchanged)

    
    
    const SlowList = memo(function SlowList({ text }) {  
    
    
      // ...  
    
    
    });

However, this only helps if the ` SlowList ` props are _the same_ as during
the previous render. The problem you’re facing now is that it’s slow when
they’re _different,_ and when you actually need to show different visual
output.

Concretely, the main performance problem is that whenever you type into the
input, the ` SlowList ` receiv