Reputation: 7384
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
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
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
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
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
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
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
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
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