IOS web browser, "will-change" cause render issue

246 Views Asked by At

Css attribute "will-change" make animation performance better. But seem like it'll disable some render in IOS mobile browser under special condition.

The behavior of following code in IOS mobile browser:

  1. Click "click me", add count to length;
  2. Render Component with new length;
  3. "value" show wrong length, "same value" show right length.

The difference between "value" and "same value" is css code, i think maybe "will-change" trigger IOS mobile browser optimize render html. The correct length in "value" has been optimized.

So please someone explain this strange issue. Thanks.

import { useState } from "react";
import "./styles.css";

export default function App() {
  const [length, setLength] = useState(0);

  const onClick = () => setLength(length + 1);

  const list = Array.from({ length }).fill("");
  const items = list.map(() => {
    return <div className="item">placeholder</div>;
  });

  return (
    <div className="container">
      { /* has css "will-change" */ }
      <div className="create" onClick={onClick}>
        Click me
      </div>
      {items}
      { /* has css "position: relative", "box-shadow" */ }
      <div className="length"> value: {length}</div>
      <div> same value: {length} </div>
    </div>
  );
}

.length {
  position: relative;
  box-shadow: 0 0 5px red;
}

.create {
  will-change: transform;
}

.container {
  font-size: 28px;
}

Bug Demo, open with iphone browser

Bug video, if don't have iphone

Source code

1

There are 1 best solutions below

1
On

Hope i can provide some help here:

First of all, you say

Css attribute "will-change" make animation performance better.

And that's not true, quate from MDN:

"will-change is intended to be used as a last resort, in order to try to deal with existing performance problems. It should not be used to anticipate performance problems."

"Use sparingly. The normal behavior for optimizations that the browser make is to remove the optimizations as soon as it can and revert back to normal. But adding will-change directly in a stylesheet implies that the targeted elements are always a few moments away from changing and the browser will keep the optimizations for much longer time than it would have otherwise."

A very important part missing from the summary is under the "Remove will-change After the Changes Are Done".

also, remember that will-change cost memory and Browser will need approx. 200ms to apply optimization.

The script runs fine if you

  • Removed the position relative
  • Remove the will-change
  • Zoom in after a click, values updates.
  • Adding a key to your component will force it to update <div key={length} className="length"> value: {length}</div>

You would take a look at this to get more info on how will-change.

How to use and how works CSS' will-change property?