Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What triggers offscreen rendering, blending and layoutSubviews in iOS?

Exactly what performance-critical things should I have an eye out for?

I want a list with as many examples as possible. Or a list of best practices.

like image 273
hfossli Avatar asked Oct 31 '12 13:10

hfossli


1 Answers

Offscreen rendering / Rendering on the CPU

The biggest bottlenecks to graphics performance are offscreen rendering and blending – they can happen for every frame of the animation and can cause choppy scrolling.

Offscreen rendering (software rendering) happens when it is necessary to do the drawing in software (offscreen) before it can be handed over to the GPU. Hardware does not handle text rendering and advanced compositions with masks and shadows.

The following will trigger offscreen rendering:

  • Any layer with a mask (layer.mask)

  • Any layer with layer.masksToBounds / view.clipsToBounds being true

  • Any layer with layer.allowsGroupOpacity set to YES and layer.opacity is less than 1.0
    When does a view (or layer) require offscreen rendering?

  • Any layer with a drop shadow (layer.shadow*).
    Tips on how to fix: https://markpospesel.wordpress.com/tag/performance/

  • Any layer with layer.shouldRasterize being true

  • Any layer with layer.cornerRadius, layer.edgeAntialiasingMask, layer.allowsEdgeAntialiasing

  • Any layer with layer.borderWith and layer.borderColor?
    Missing reference / proof

  • Text (any kind, including UILabel, CATextLayer, Core Text, etc).

  • Most of the drawings you do with CGContext in drawRect:. Even an empty implementation will be rendered offscreen.


Blending

  • resizableImage can cause blending.
    Avoiding blended layers when using resizableImages on iOS

  • Any layer which is not opaque and has a backgroundColor with alpha less than 1.0

  • Any layer with alpha less than 1.0

  • Any layer with layer.content or any UIImageView with a UIImage having an alpha channel


Layout

The following things will trigger layoutSubviews to be called on a UIView:

  • Changing bounds triggers on the same view and superview

  • Changing frame triggers on the same view and superview

  • Changing transform or layer.transform triggers on superview

Note: I'm referring to real changes where values actually are changing

Contradictory these changes does not trigger layoutSubviews to be called: center, layer.position, layer.zPosition, layer.anchorPoint, layer.anchorPointZ.

Reference: https://github.com/hfossli/LayoutSubviewsInconsistency


General tips for improving performance

  • Oftentimes it is better to blend than to render offscreen.

  • Consider using drawRect: instead of having a view with multiple labels and subviews.

  • Draw on a background queue to a UIImage or CGImageRef.

  • Draw to a CGLayer (which is cached better on GPU compared to UIImage), and draw whatever you want into it.
    Update, don't: http://iosptl.com/posts/cglayer-no-longer-recommended/

  • Flatten your hierarchy

  • Reuse views – don't create and add new ones while scrolling

  • Have opaque views with solid background color

  • Avoid setting alpha and layer.opacity to less than 1.0

  • Enable layer.shouldRasterize (use with care). I like to avoid this personally, but it performs faster in some occasions since rasters of the layer will be cached and reused. Remember if you enable shouldRasterize on layers that changing their content or sublayers contents frequently will cause the performance to drop, since iOS will keep rasterizing the layer on each change.


Links

  • http://iosinjordan.tumblr.com/post/56778173518/help-my-tables-dont-scroll-smoothly

  • https://developer.apple.com/library/IOS/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/DrawingTips/DrawingTips.html

like image 154
hfossli Avatar answered Nov 15 '22 19:11

hfossli