Four actions can trigger offscreen render:
- RoundedCorener
- Shadow
- Mask
- GroupOpacity(almost no impact to graphics performance in my demo)
Core Graphics API don't trigger offscreen render. You should check it with Core Animation Instruments with debug option 'Color Offscreen-Renderd Yellow'.
Another proof: Andy Matuschak's comments on this, who was a member of the UIKit team and a speaker of WWDC 2011: Understanding UIKit Rendering. Andy Matuschak said edge antialiasing also tirgger offscreen render, I test on iOS 8 and iOS 9, it doesn't, maybe things have change.
##Basics
The relationship between UIView and CALayer, and CALayer's visual structure.
##Trigger Condition:
1.Rounder Corener:
view.layer.cornerRadius > 0
view.layer.masksToBounds = true
cornerRadius
's description:
Setting the radius to a value greater than 0.0 causes the layer to begin drawing rounded corners on its background. By default, the corner radius does not apply to the image in the layer’s contents property; it applies only to the background color and border of the layer. However, setting the masksToBounds property to YES causes the content to be clipped to the rounded corners.
So, if layer's contents
is nil or contents
has transparent background, you don't need to set masksToBounds = true
to trigger offscreen render.
2.Shadow:view.layer.shadowPath = nil
. A shadow with shadowPath won't trigger offcreen render.
3.Mask: always tirgger offscreen render.
4.GroupOpacity: view.alpha != 1.0
and layer has nontrivial content. Note: in UITableView, only set tableView.alpha != 1.0
can trigger offscreen render, and this has no impact to scroll performance in my demo.
##Optimization Solution:
###Avoid offscreen render if you can
1.RounedCorner:
if layer's contents
is nil or this contents
has a transparent background, you just need to set cornerRadius
. For UILabel, UITextView and UIButton, you can just set layer's backgroundColor
and cornerRadius
to get a rounded corner. Note: UILabel's backgroundColor
is not its layer's backgroundColor
.
//Set backgroundColor to get corner can be see
textView.backgroundColor = aColor
textView.layer.cornerRadius = 5
//Don't set label.backgroundColor = aColor
label.layer.backgroundColor = aCGColor
label.layer.cornerRadius = 5
2.Shadow: specify a shadow path for a shadow.
###Rasterization
Rasterization works for all effects and has very good performance. This is fit for views which have static contents.
view.layer.shouldRasterize = true
view.layer.rasterizationScale = view.layer.contentsScale
About shadow, shadowPath is better: lower GPU utilization.
###Fake effect
1.Blend with a transparent view like:
The best performance! Only problem is how get these image. Paint or draw. With a image, blend and mask get opposite effect. This solution is fit for rounded corner and mask.
2.For RoundedCorener: redraw a rouned corner image with Core Graphics API.