Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

High CPU usage #125

Open
vylan opened this issue Dec 26, 2018 · 17 comments
Open

High CPU usage #125

vylan opened this issue Dec 26, 2018 · 17 comments

Comments

@vylan
Copy link

vylan commented Dec 26, 2018

image
As shown in the above image the home page's cpu usage is always more than 40% and also more 20% in my app. I think this is abnormal, please confirm whether it is a bug or the normal phenomenon?

@AjayPoshak
Copy link
Contributor

AjayPoshak commented Dec 28, 2018

That's interesting. How did you benchmark that?

@vylan
Copy link
Author

vylan commented Dec 28, 2018

You can simply open the home page of this library (http://danilowoz.com/create-content-loader), then check the chrome's Task Manager., you'll see the cpu usage monitor.

Now I am pretty sure it's caused by the svg animation ( if I set {animate: false} , the cpu usage will stay at almost 0. )

@AjayPoshak
Copy link
Contributor

Thanks, I got your point. I can see that animations are taking significant CPU time (34-38%) at my system. I think that this is the issue with animations in general, as this chromium bug. However, we'll look into it and try to figure out a way to reduce CPU usage.

@vylan
Copy link
Author

vylan commented Dec 29, 2018

Thanks, it's not a big problem cause the content loader won't last for a long time, but fix it will be perfect.

@danilowoz
Copy link
Owner

I've tried some alternatives approaches and I reached these results, but I'm not sure if I should forward in one of these or wait for a chrome fix:

  1. Current: ~40%
  2. With one <animate />: ~53%
        <linearGradient id={idGradient} x1="-100%">
          <stop
            offset="0%"
            stopColor={primaryColor}
            stopOpacity={primaryOpacity}
          />

          <stop
            offset="50%"
            stopColor={secondaryColor}
            stopOpacity={secondaryOpacity}
          />

          <stop
            offset="100%"
            stopColor={primaryColor}
            stopOpacity={primaryOpacity}
          />

          <animate
            attributeName="x1"
            from="-100%"
            to="100%"
            dur={`${speed}s`}
            repeatCount="indefinite"
          />
        </linearGradient>
  1. With backfaceVisibility: 'hidden', willChange: 'auto',; in the <svg />: >40%

@josh-stevens
Copy link

Is there a way to push SVG animations to the GPU?

@dmkmedina
Copy link

We're seeing similarly high CPU usage when animate=true for React Native as well.

@Cellule
Copy link

Cellule commented Mar 5, 2020

I was using react-content-loader as a placeholder while during development and I couldn't figure out why my computer was soooo slow all the time.
Then I checked the task manager and finally blamed it on the animation. Without animation everything is fine.

image

@pedrommenezes
Copy link

I'm seeing similar results regarding my CPU usage as well. I'm using React (for the web) on development mode and for comparison, those are the CPU usage without and with animate={false} on my page:

With animate={false}
Screenshot 2020-05-24 at 03 02 43

Without animate={false}
Screenshot 2020-05-24 at 03 02 54

FIY: I'm using react-content-loader version 5.0.4 in here.

tkalmi pushed a commit to tkalmi/hacker-news that referenced this issue May 26, 2020
@bertho-zero
Copy link

I actually have a huge CPU usage on this page https://danilowoz.com/create-content-loader/ but it's still close to 0 on this codesandbox https://codesandbox.io/s/6x2414oqln.

@steffen-harbich-cognitum

See the following proposal @danilowoz. The essence is to use SVG mask instead of clippath. Fill the rectangle in white and mask the content placeholder shapes black. That way, the SVG's element background becomes visible where the mask is black. Now you can use CSS linear-gradient for the background which is animated by changing the background position.

Tested in latest firefox, low CPU usage. Didn't check for compatibility with other browsers.

SVG:

<svg width="100%" viewBox="0 0 800 350" className='loader-animated-bgr'>
    <rect x="0" y="0" width="100%" height="100%" fill='white' mask="url(#mymask)">
    </rect>
    <defs>
        <mask id="mymask">
            <rect id="bg" x="0" y="0" width="100%" height="100%" fill="white" />
            <!-- TODO: insert any shapes filled black -->
        </mask>
    </defs>
</svg>

CSS:

$col-bgr: #ecebeb;
$col-accent: #e0e0e0;

.loader-animated-bgr {
    background: linear-gradient(90deg, $col-bgr, $col-bgr 25%, $col-accent 45%, $col-accent 55%, $col-bgr 75%, $col-bgr);
    background-size: 400% 100%;
    animation: loader-animation 3s ease infinite;
}

@keyframes loader-animation {
    0% { background-position: 100% 0% }
    100% { background-position: 0% 0% }
}

Have a nice day!

@danilowoz danilowoz changed the title Cpu usage is really high? High CPU usage Nov 2, 2020
@danilowoz
Copy link
Owner

This reporting in Chromium might help: https://bugs.chromium.org/p/chromium/issues/detail?id=1141881

@dasaco
Copy link

dasaco commented Feb 14, 2021

Also most likely related to this - when using Detox (React Native) to test, tests just hang whenever the content loader is present. Might be something to do with how Animate lib is interacted with, maybe some unresolved promise.

If I set animate={false} it works well.

@AND-GORNIY
Copy link

AND-GORNIY commented Feb 19, 2021

I did`t research much this topic, but can add when I trying to run tests - every time snapshot are updated, without any changes in spec file, and every time updates below property of ( symbols in **). Test passes very long time, and seems like an infinity loop, one time I even got error with full memory.

clipPath=" **zrpmk0p** -animated-diff"

@danilowoz
Copy link
Owner

@AND-GORNIY regarding the id issue, I'd recommend the following issue #78, it introduces the prop uniqueId in order to manage this kind of situation. Unfortunately, it needs somehow a unique value, and in case the user doesn't provide any one, the library needs to generate a random one.

Make sense?

antoinewg added a commit to pass-culture/pass-culture-app-native that referenced this issue Jun 11, 2021
Ref: high CPU usage that may be responsible for the crash on Android: danilowoz/react-content-loader#125
antoinewg added a commit to pass-culture/pass-culture-app-native that referenced this issue Jun 11, 2021
Ref: high CPU usage that may be responsible for the crash on Android: danilowoz/react-content-loader#125
antoinewg added a commit to pass-culture/pass-culture-app-native that referenced this issue Jun 11, 2021
Ref: high CPU usage that may be responsible for the crash on Android: danilowoz/react-content-loader#125
antoinewg added a commit to pass-culture/pass-culture-app-native that referenced this issue Jun 11, 2021
Ref: high CPU usage that may be responsible for the crash on Android: danilowoz/react-content-loader#125
@MadsFrost
Copy link

Found an interesting sort of solution to this problem:

"As with the hero of any story, however, there must be a fall from grace. For animated SVGs, this fall occurs in CPU usage. The inclusion of just a few on a webpage can cause the CPU usage of a browser to jump by several tens of percentage points. Viewing such a page on even modern laptops will cause the machine to whirr like it’s trying to take flight and heat up like a bacon griddle.

Fortunately, redemption for our hero comes easily and quickly in the form of CSS hardware acceleration.

If you’re unfamiliar with the concept, the idea is to give a troublesome element the style transform: translateZ(0);. This gives the element its own render layer, and lets the GPU (who’s better at this kind of work anyway) take the hard number crunching away from the overloaded CPU."

Worked well for me, reduced the max workload experienced from 40-50% to an average of 20-30% (still a lot, but an improvement).

@meronogbai
Copy link

I fixed this by re-implementing the loader to clip a div instead of a rect. I also had to rely on animating opacity instead of backgroundColor/fill.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests