simekadam
simekadam

Reputation: 7384

iOS6 UIwebView CSS3D transforms are not HW accelerated

I have problems with poor scrolling performance in iOS6 UIWebView component..In iOS5 scrolling was really fluid, though. So I have searched the web little bit and found this (part of iOS6 beta changelog).

WebKit no longer always creates hardware-accelerated layers for elements with the -webkit-transform: preserve-3d option. Authors should stop using this option as a way to get hardware acceleration.

That could be the reason, since the html site my app displays uses lots of css3 transformations.. Please have anyone a solution or advice how to force webview switch back to accelerated rendering model?

Upvotes: 14

Views: 6550

Answers (8)

Anand
Anand

Reputation: 39

Try replacing all instances of -webkit-transform: translate3d(0,0,0);

With

-webkit-transform: translate3d(0,0,0) scale3d(1,1,1);

It did work for me

Upvotes: 2

Olaf Horstmann
Olaf Horstmann

Reputation: 16892

Besides the already mentioned change of the CSS-properties that are(or are not) triggering hardware acceleration I have noticed another change on iOS6 that did not persist as heavily on iOS5 (or at least I did not really notice it before): Overlapping between hardware-accelerated elements and non-accelerated elements will slow down rendering and the app A LOT.

If you have any overlappings between accelerated and non-accelerated elements, make sure that you add hardware-acceleration to those other elements even if they are not animated or so, because they will be re-rendered as well which will completely supress or in some cases revert the acceleration-effect.

I have also written an short article about this if you want to check it out: http://indiegamr.com/ios6-html-hardware-acceleration-changes-and-how-to-fix-them/

Upvotes: 8

Ricardo Freitas
Ricardo Freitas

Reputation: 533

Just to let some know, that -webkit-transform-origin was previously hardware accelerated if used together with hardware accelerated transformations, like translateZ(0), but it no longer is.

Upvotes: 0

eplawless
eplawless

Reputation: 4323

I've attached a simple test case which reproduces this bug in iOS6, and which runs perfectly fine on iOS5.1 (on both iPhone 4 and 4S). The iOS Chrome app is a good place to run this test, since it embeds a UIWebView. I have a video which I'll attach once it uploads of two iPhone 4's (the top one running iOS 5.1, the other running iOS 6) running this example script inside a PhoneGap 2.0 UIWebView.

Right now, it seems like these elements ARE being hardware accelerated, but that there's a bug in Apple's low-level pipeline which kills performance. We've tried a number of workarounds for hardware acceleration, and it certainly seems that anything which invokes the GPU on iOS5.1 causes a massive slowdown on iOS6.

I would love to find a fix, since the app we're building relies pretty heavily on this working properly. If someone can point out an error in this example, that would also be extremely appreciated.

EDIT: The bug persists even if you modify the animate function as follows.

function animate(node) {
    node.style.webkitAnimation = 'sample 5s infinite';
    node.style.webkitPerspective = 1000;
    node.style.webkitBackfaceVisibility = 'hidden';
}

This seems to reinforce that invoking the GPU causes this slowdown.

EDIT 2: There's an additional example hosted at http://bvgam.es/apple/ which runs smoothly on iOS 5.1, and gets 1-2 FPS on iOS 6.

<!DOCTYPE html>
<html>
    <head>
        <title>Animation Playground</title>
        <style>
            @-webkit-keyframes sample {
                0% { -webkit-transform: translate3d(0px, 0px, 0px); opacity: 1; }
                10% { -webkit-transform: translate3d(0px, 0px, 0px); opacity: 0; }
                20% { -webkit-transform: translate3d(10px, 0px, 0px); opacity: 1; }
                40% { -webkit-transform: translate3d(10px, 10px, 0px); opacity: 0; }
                50% { -webkit-transform: translate3d(10px, 20px, 0px); opacity: 1; }
                80% { -webkit-transform: translate3d(20px, 20px, 0px); opacity: 0; }
                100% { -webkit-transform: translate3d(0px, 0px, 0px); opacity: 1; }
            }
        </style>
        <script type="text/javascript">
            function fib(node, a, b) {
                node.innerHTML = a;
                setTimeout(function() {
                    fib(node, a + b, b);
                }, 0);
            }

            function animate(node) {
                node.style.webkitAnimation = 'sample 5s infinite';
            }

            function createNode(row, column) {
                var node = document.createElement('div');
                node.style.width = '7px';
                node.style.height = '7px';
                node.style.position = 'absolute';
                node.style.top = 30 + (row * 9) + 'px';
                node.style.left = (column * 9) + 'px';
                node.style.background = 'green';
                return node;
            }

            function run() {
                for (var row = 0; row < 20; ++row) {
                    for (var column = 0; column < 20; ++column) {
                        var node = createNode(row, column);
                        document.body.appendChild(node);
                        animate(node);
                    }
                }

                var output = document.getElementById('output');
                fib(output, 0, 1);
            }
        </script>
    </head>
    <body onload="run()">
        <div id="output" style="font-size: 40px; position: absolute; left: 220px;"></div>
    </body>
</html>

Upvotes: 3

user1690215
user1690215

Reputation: 74

Could those reporting that -webkit-transform: translate3d(0,0,0); is slower in iOS 6, please provide a URL to some sample content that shows this.

Upvotes: 0

user1491646
user1491646

Reputation: 83

Try replacing all instances of -webkit-transform: translate3d(0,0,0); with -webkit-perspective: 1000; -webkit-backface-visibility: hidden;. This worked for me. It's seems that -webkit-transform: translate3d(0,0,0); no longer invokes hardware acceleration.

Upvotes: 0

kuvik
kuvik

Reputation: 183

CSS Transforms are indeed a lot slower in iOS 6, at least in my application on iPhone 4.

I set basic translate() to element, instead of translate3d(), and performance stayed the same, so I think even translate3d() no longer triggers GPU acceleration. That sounds like a bug.

As a workaround, I tried setting a different CSS properties (like rotate3d(), scale3d(), perspective, ...) on element, but neither of them seems to trigger hardware acceleration.

Upvotes: 1

user1690215
user1690215

Reputation: 74

UIWebView still does hardware acceleration if you use a 3D transform (e.g. -webkit-transform: translateZ(0)). It just no longer does if you only use -webkit-transform-style: preserve-3d.

If you have an example that is doing 3D transforms, but got slower with iOS 6, you should report it at Apple's Bug Reporter.

Upvotes: 5

Related Questions