rich

Myth busting the HTML5 performance of transform:translate vs. top/left

Recommended Posts

I recently came across Christian Heilmann’s Five things you can do to make HTML5 perform better article, where point number three is to use CSS Transforms instead of position and top/left when moving elements across a page. It is a practice increasingly championed, such as in the noted Paul Irish video, Why Moving Elements With Translate() Is Better Than Pos:abs Top/left. The central point is when animating you’ll achieve higher frame rates using this transform code:

 

http://blog.tumult.com/2013/02/28/transform-translate-vs-top-left/

Share this post


Link to post
Share on other sites

Actually, this is only partly true.

 

The 3d translation layers offer a way of pre-blitting all the stuff inside the DOM element into a layer, which is therefore available for direct blitting operations inside the render tree. Well, at least that's the conceptual idea behind.

 

The problem is that it also is dependent of the relayout events that are required, like with shadows, opacity, border and border-radius or rgba backgrounds. Also, a relative z-index is influencing their real positions inside the final linked list / array of layers, so the z-index is also influencing the performance here.

 

If you ignore that kind of performance issues, the conceptual problem that still exists is that "accelerated rendering" is only "valuable" if the game and game engine behind doesn't depend on CPU calculations. And in DOM operations, that is the case - meaning it will still have CPU/GPU context switches while processing the relayout (or the reflow in worse cases).

 

Try benchmarking opacity + translate and compare it with opacity + top/left (with relative stacking context, so z-index and/or containing DOM element with same position method is required) on mobile GPUs, then you will find weird issues with asynchronous FPS and crashing OSes due to the shared memory, WebKit has several leaks there.

 

The DOM is a lazy rendering concept which isn't actually what you want for games. Take a look at DirectX, OpenGL, WebGL - those are all technologies that offer a diversification between rendering logic (only drawing, no calculation) and game logic (updating data structures). That's why I think canvas will be overall still faster for games for bigger n entities - as the implementation behind is made for that kind of optimizations.

 

 

 

The only kind of game that comes to my mind where DOM makes sense is an isometric game where you can abstract dirty rectangle algorithms directly to the node structures. All other types of games will mostly be faster by concept using canvas.

 

Sure, there are crappy systems out there (Android 2.3.x for example), where canvas is slow. But there's also no push rendering architecture available - meaning that translate2d + translate3d is slower than top/left anyways due to the CPU/GPU context switches - as you probably don't want to implement your own GPU drivers there you won't be able to target these systems in a "real" performant way anyways (speaking of a minimum of 1000 sprites at 60FPS)  :)

Share this post


Link to post
Share on other sites

And to add to martensms's extremely eloquent response, to which I fully agree with, there are other things to consider when using translate() that doesn't apply when using top/left, such as the limit of parallel transformations/translations you can perform on a single DOM element. To make the problem worse, that limit is extremely inconsistent, some platforms allows you to simultaneously change just 2 parameters (such as in android 2.2), others allow you to change 3 (iOS 4.3), others 5 and so on. The most common way to deal with this problem and 'standardise' things among all browsers is to wrap the element with several other elements, simultaneously increasing the size of the DOM tree as well as the complexity of your codebase.

 

You can probably tell that this solution doesn't scale well. 

 

My point is that all depends on what you're trying to do and how many objects you're trying to move simultaneously. If you need to move just one object among 1000 other objects that will remain static, you're better off with canvas (dirty recs/atr). If you need to move 1000 objects simultaneously in the X and Y axis I'd use DOM. But if I had to move AND rotate 1000 objects simultaneously, I'd use either SVG, canvas, or something else and would try to avoid using the DOM altogether.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.