Can I use CSS 3D Transforms (instead of built-in positioning) in order to boost performance?

Hello Hype friends!

I am a few weeks away from publishing a new book series on Apple Books (an interactive music sight reading series). I'm trying to tune the performance of the app because (despite tons of optimizations) the animation is fairly heavy and it's affecting the performance on some devices.

In the Apple Books support docs "Tips for Performance in Books with JavaScript" article (attached), it states "Use CSS 3D transforms instead of setting top/bottom/left/right position. This creates smoother transitions because they are hardware accelerated, but should be reserved for high-priority elements."

So, I'm wondering if anyone knows more about this? Can I trigger CSS 3D transforms from a custom javascript function instead of from built-in Hype positioning? Does this sound right that doing so might give me a hardware accelerated performance boost? Or is there another way to achieve hardware accelerated animations?

For context: I'm dragging a group of layered svg's horizontally across the screen in order to simulate scrolling sheet music. I'm trying to make the sheet music scroll as smoothly as possible. On iPhone (in particular), the scrolling is choppy and chugging. I'm looking for any tips on how to increase animation smoothness and performance, and in particular I'm wondering if CSS 3D transforms is a way to do it?

I'd be happy to share the project if that would be helpful. Any information would be greatly appreciated! Thanks so much :slight_smile:

as long as 'position with css left/top' is unchecked Hype will use css 3d.

example for output on a rectangle:

transform: translateX(

249px

) translateY(

149px

) rotate(

79deg

) rotateY(

-111deg

) rotateX(

69deg

) skew(

25deg

,

-18deg

);

i'd guess the best tipp is point five: reduce page complexity

1 Like

Hype's default is to use 3D accelerated transforms, but there are options to configure this in the Document Inspector:

  • Position with CSS left/top: if unchecked (default), it will position elements at a CSS top/left of 0/0 and instead use the transform:translate() property. If checked, it uses the CSS left/top values instead.
  • Use WebKit graphics acceleration: if checked (default) it will add a rotateY(0deg) value to the transform property, hinting to the browser it should use 3D acceleration.

However, there are some specific times when using 3D acceleration is inappropriate and causes blurring due to scaling contents more like an image than re-rendering, or it may lead to browser-specific bugs. In these cases Hype will override your settings to do what is more commonly appropriate.

I would probably recommend converting the SVG to a bitmap format. It is likely that you're triggering a path where the browser needs to do expensive calculations to re-render the SVG. You can also try toggling the above settings, sometimes the advice on what to do is opposite of what needs to be done. If that doesn't work, feel free to post the document, I'd be curious to see if there are other ways to improve performance.

Also note that while it is a general recommendation to use 3D transforms as a performance tip, this is not a silver bullet. There are definitely tradeoffs made with having the graphics card do more work, and sometimes it is faster to keep things in CPU land. (I wrote this article a while ago when computers were not as fast as they are today that shows there's plenty of unmeasured advice out there...)

1 Like

Thanks very much @h_classen and @jonathan!
This is all a big help and confirms my original question:
That CSS 3D is Hype's default.

I'm now in a testing phase trying different optimizations.
Today, in a test file, I ran all of my SVG's through a 'simplify' command in Adobe Illustrator. I went from around 85,000 points to 25,000 points without sacrificing much detail. I figured this test had great potential to increase the performance since I was working with SVGs with drastically fewer points. I exported the test and ran it in both Apple Books and running directly on a web browser to see if there was a performance difference. Testing on an iPhone 13 Pro, disappointingly, it still seemed just as choppy with 25,000 points as it was with 85,000 points.

I did some testing a long time ago with bitmap images, which also seemed fairly choppy from what I remember. However, my test back then was not very thorough. Tomorrow I hope to do some better testing, converting my SVGs to png's at a variety of resolutions (they would have to be png's since the animated layers need transparency).

I will be sure to report back with any findings as to whether or not the performance was boosted with png's. In the meantime, I would be happy to provide an example widget in case you or anyone else would like to take a look. I welcome any and all ideas as to how to eek out some smoother performance, especially on iPhone. Click here to download a demo Hype file.

Thanks so much and happy holidays! All the best :slight_smile:

howlers actual version is 2.2.3 https://howlerjs.com/

just saw that your brahms-file uses an older version ...

////////////

you'll find a couple of hints in this forum on how to change fill and stroke of svg-elements. this'd require a rework of your svgs, but will enable loading each only once and not several versions ...

////////

that said : plays really well on the desktopdevice :slight_smile:

Thanks so much for the heads up on the Howler version.
I'll be sure to update the version!

Can you be more specific on what you mean regarding the fill and stroke of the svg's? I'm totally fine reworking my svg's and I am adept at Adobe Illustrator. I've already expanded and filled all of my vector images and yesterday I tried simplifying the points in order to make the svg's lighter. Was there another process you were suggesting? I'm not sure what you meant regarding loading several versions. Each scene currently uses the same layers of svg's.

Thanks again for your helpful input and happy holidays!

Which iPhone? It is smooth on my iPhone 12 and 2018 iPad Pro. I'm just pressing "120" and then the play button to test.

The issue may stem from the image being a whopping 18,000 x 1,000 pixels. In cases where the texture size is going to be very large, I highly recommend unchecking "Use WebKit graphics acceleration."

I decided to install a new version and it turned out to be with bugs when playing the radio station. I returned the old one on which no errors were noticed

Hi Jonathan,

Here is a short video of my iPhone 13 Pro running the Brahms widget directly on Apple Books. This video demonstrates the 3 main issues I'm running into: 1) choppy playback, 2) The tempo button in the upper right hand corner of the screen disappears and reappears, 3) the widget sometimes crashes and restarts.

The widget seems to run smoother on my iPhone 13 Pro when previewing with Hype reflect or when previewing on a browser. This seems to point to the notion that it runs worse on Apple Books. Any thought on why this would be?

I haven't yet had a chance to do testing with png's due to holiday / family obligations the last 2 days. However, I plan on doing testing asap this week. I'll be sure to report back with any info learned.

Ah, I did not try in iBooks itself and so it sounds like you were seeing performance like what I saw.

We've definitely encountered some performance issues in iBooks before, though I don't think there were any particular solutions for it. I'm not sure the cause; it might be scaling or potentially iBooks using an older embedded WebView class that can't take advantage of some particular performance improvements.

The crashes are likely due to the result of memory usage in the overhead of the iBook + your web content.

I definitely recommend trying unchecking "Use WebKit graphics acceleration" since that usually has lower memory requirements. Converting to PNGs or JPGs is what I'd try next if that does not help, since it is a bit more time consuming. (I'd also run them through ImageOptim just to reduce file size).

Another strategy might be to render your playback as a mp4 video. Then you could use the html5 video's playbackRate property to achieve the desired rate. Videos are highly optimized in browsers.

Hi Jonathan,

Just wanted to touch base with a quick followup.
I exported a test widget with 'Use WebKit graphics acceleration' unchecked.
This made all the difference!

I added the newly exported widget to iBooks Author, and published a test version with iTunes Producer. I downloaded the new version from Apple Books and previewed it on my iPhone.

I'm so happy to report that it is working much, much better! I wouldn't say it was as smooth as butter, but it is now working passably well on iPhone, and that is totally ok with me. With no major stutters, no disappearing tempo button, and no crashing. As far as I'm concerned this is now working! So thanks so much for pointing me to that important setting change, it was a huge help! I also tested on my iPad and it is working absolutely flawless (which is to say, even better than it was!).

I did have one question though:
This new widget, despite running much better now, is flashing a white screen when it loads the widget while viewing in Apple Books.

I did some searching in the Hype Forums and I found this article from December 2014 posted by Daniel on the white flash issue. And I also found mention of the white flash issue in this article that states that Hype has built in support for suppressing this white flash.

Do you have any ideas on what I might have done to trigger this white flash (as far as I know I didn't make any other changes other than unchecking that WebKit setting, so it seems pretty random that I'm getting the white flash now). Or do you have any advice on the best way to manually suppress the white flash now that it has surfaced?

Thanks again and all the best!

Great, I'm glad that did the trick!

As for the white flash... it has been a while since we looked into it. My recollection is that we wait until DOM content is ready to tell iBooks to switch over from the thumbnail image correctly, but the way Safari renders means that if there's a lot to actually draw to render it will cause a white flash if it takes longer than one frame. Basically the only way to reduce it was to do less work in the first display of the first scene.

Maybe it is the case that noticing it now means that turning off the webkit graphics acceleration does a bit more upfront work in rendering, and that causes the delay. Perhaps you could do something like try fading in from 0% opacity big images and see if that helps.