CPU load on https://markojs.com
When I go to https://markojs.com in Safari (14.1.2), the CPU load on my MacBook Air goes up above 100%. If I use the Brave browser, the CPU load is closer to 25%. Still too much.
Hm, this sounds eerily familiar to #1715. Do your performance devtools show if it’s running a lot of style recalculation?
I haven't yet been able to detect anything like "style recalculation". However, when I viewed markojs.com in Safari with devtools open, it climbed from ca. 90% up to 100% CPU. As soon as I closed the devtools (indicated by the vertical arrow in the included screen dump from Activity Monitor), however, the CPU load started climbing to over 120%.

Yep, can confirm:

I uploaded the trace here for the Marko maintainers: markojs.com-recording.json.gz
Still an issue in Safari 15.5. Its DevTools report:
Main thread
JavaScript: 0.0% (0) Layout: 1.3% (9) Paint: 98.7% (697) Styles: 0.0% (0)
Energy Impact
Very High Average CPU: 204.1%
After investigating, it looks like these are the culprits. When I turned off all of them in the Safari DevTools, the Average CPU dropped to 3.8%.
Code Elimination animation
@keyframes pulse-red {
0% {
box-shadow: 0 0 0 0 rgba(255, 50, 82, 0.9);
}
100% {
box-shadow: 0 0 0px 90px rgba(255, 50, 82, 0);
}
}
box-shadow is a notorious career performance criminal, especially when animated or transitioned. Animating transform and opacity on some pseudo-elements would probably be a good replacement.
Image placeholder popping in
.demo-page-lowres {
filter: blur(1em) grayscale(0.6);
opacity: 0.3;
}
Maybe we should have two .demo-page-image elements, and toggle their opacity on and off instead, so Safari only needs to rasterize the filter once.
Demo progress bar
<div.demo-page-progress style={ transform: `scaleX(${Math.min(1, input.progress * (input.buffered ? 1 : 1/0.9))})` }/>
The worst part is this progress bar doesn’t even display right now — it’s missing either right: 0 or width: 100%. (I checked — not my fault in https://github.com/marko-js/website/pull/63!)
It looks like doing the scaleX() dynamically in JS is flummoxing Safari. Slapping will-change: transform on .demo-page-progress made it much happier.