wiki:QtWebKitGraphics

Version 6 (modified by simon.fraser@apple.com, 4 years ago) (diff)

--

QtWebkit and Graphics

This page holds tips for web developers on how to optimize their web-code for QtWebkit's rendering pipeline. The philosophy behind those performance tips is that web technologies in general are meant for dynamic content and not for dynamic UI. Therefore, most of the HTML and CSS features are optimized for exactly that. When something is slow, ask yourself: am I trying to solve a dynamic-UI problem with a tool meant for dynamic-content? The good news is that CSS has enough capabilities for dynamic UI, even if they're not as smooth to use as solutions originally optimized for GUI.

General graphics performance guidelines

Don't mess with the DOM

DOM manipulation is generally slow. The DOM is optimized for content changes, not for UI changes. If your web app moves between a list screen and a details screen, for example, it's better to have both of them ready in the DOM, hide the first one and show the second one, changing just the parts of the dialog that need changing due to the content being different. If moving between screens is slow, look for the DOM manipulations.

The CSS box model

The CSS box model is a concept from the world of content and not from the world of GUI. All the concepts from the CSS box model (margin, padding, background, outline, border) should not be modified, for example, inside an animation, or in a performance-heavy task. If you need a dynamic image to be behind a static image, for example, a common pitfall is to have one image and change its background's URL or position using CSS. There are about 3 ways that are faster than that:

  • two different images
  • :after {content} or :before {content}
  • use negative z-index

So, CSS box model to decorate dynamic content - transforms and regular images for dynamic UI.

Use static images

Sometimes it's tempting to use webkit's drawing features, like -webkit-gradient, when it's not actually necessary - maintaining images and dealing with Photoshop and drawing tools can be a hassle. However, using CSS for those tasks moves that hassle from the designer's computer to the target's CPU. Gradients, shadows, and other decorations in CSS should be used only when necessary (e.g. when the shape is dynamic based on the content) - otherwise, static images are always faster.

Plan your scene-graph

Imagine a list with 10 or more elements, and a semi-transparent image that represents a focus marker. A common way to do this in HTML is to have a content: after or an outline for some "focused" class, and simply change the class for an item when it receives / loses focus. Though this is very convenient, it requires webkit to regenerate the image and perform expensive CSS box-model calculations. A more efficient way to achieve the same effect is to have an absolute-positioned image, and calculate where it should move to when the focus changes. Moving the image is best done with the -webkit-transform: translate approach.

This is one of the trickier parts of web development - there are numerous ways to achieve almost any desired effect. In general, being smart about the scene-graph and planning the elements on it is usually better than relying on CSS to do the job.

Value of the $

Be careful of high-level object-oriented nicely-designed Javascript libraries on top of the core Webkit (like Dojo or jQuery, hence the $). They make the application code look nicer, but make it hard to find the source of a performance problem, as it adds layers of complexity.

If you think about what those libraries really give you, it's browser compatibility, rapid DOM element selection, and effects. If browser compatibility is what you need - those libraries are great and are definitely worth it but you might have to incur the performance compromise. rapid DOM selection can be done with document.querySelector or document.querySelectorAll, which are much faster than the browser-compatible functions. effects, if can't be expressed with CSS animations, would probably end up being slow anyway.

Accelerated compositing

Accelerated compositing enables hardware acceleration of CSS animations, using QGraphicsView. To make use of it, the web developer has to use CSS3 animations (-webkit-transition / -webkit-animation), and only animate the -webkit-transform or opacity attributes. Animating left, margin, width or any other attribute (mainly the ones related to the CSS box model) will not be accelerated: because the box model would have to make expensive calculations for each frame. Note that animating -webkit-transform and opacity should be very good for plenty of use cases - scrolling, for example, can be made very fast like this:

<div id="viewport" style="overflow: hidden">
  <div id="content" style="-webkit-transition-property: -webkit-transform">
    ... whatever ...
  </div>
</div>
<script>
  function scrollMe(dy)
  {
    content.style.webkitTransform = "translate(0, " + dy + "px)";
  }
</script>

It's also important to use the same sequence of transform operations when animating. For example, use:

from {-webkit-transform: scale(1) translate(100) } to { -webkit-transform: scale(2) translate(0) }

instead of

from {-webkit-transform: translate(100) } to {-webkit-transform: scale(2) }

Benchmarking CSS animations

I've attached a comprehensive CSS animation test suite to this document: https://trac.webkit.org/raw-attachment/wiki/QtWebKitGraphics/cssAnimTestSuite.html Good luck!

Attachments