layer的光柵化能夠將繪製完的位圖緩存下來以減小GPU壓力,在合適的時機使用效果十分顯著
layer.shouldRasterize = true
關於光柵化的基礎知識不瞭解的同窗能夠搜一下 百度傳送門緩存
UIView
,設置了陰影屬性。 代碼在文章尾部
從圖中第二列幀率來看開啓了光柵化後幀率比較穩定地處於59/60,而使用前的幀率在56/57左右 第三列的GPU使用率就更明顯了,使用後穩定在25%左右,而使用前是83%左右性能優化
看起來光柵化效果很是好,可是若是錯誤地使用可能會致使更大地消耗。
具體某個視圖應不該該開啓,準確的實際測驗最具備說服力,好比用Instruments裏的Core Animatin跑一跑光柵化以後性能是否有提高。
此外,光柵化會緩存,也就意味着它要佔據一些額外的內存,大量的光柵化也會對運行時內存形成必定壓力bash
重要的一點是隻在不頻繁更新 每幀結果 的Layer上開啓,不然會觸發頻繁的緩存刷新。dom
下圖在cellForRowAt
方法中動態將上面例子中的陰影顏色設置爲一個隨機值 ide
對比上面例子中開啓光柵化,這裏GPU使用率只提高了2%-3%變可是幀率相比仍是下降了很多。由於雖然避免了每幀都去從新渲染,可是快速滑動的時候,頻繁的觸發了Cell的刷新所帶來的陰影從新繪製以及緩存操做性能
對於性能優化方面來講,若是不知道光柵化好很差用,最簡便的方法是用一張png來顯示(若是這個圖沒有很大的話)
下圖是把動態繪製的陰影背景用一張png代替以後,測試的結果 測試
import UIKit
let cellHeight = CGFloat(90)
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
class TestViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let contentView = UITableView(frame: UIScreen.main.bounds, style: .grouped)
contentView.delegate = self
contentView.dataSource = self
contentView.register(TestTableCell.self, forCellReuseIdentifier: "Cell")
view.addSubview(contentView)
}
}
extension TestViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return cellHeight
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TestTableCell
cell.update(title: "Cell \(indexPath.row)")
return cell
}
}
class TestTableCell: UITableViewCell {
lazy var blockView: UIView = {
let view = UIView(frame: CGRect(x: 12, y: 6, width: screenWidth-24, height: cellHeight-12))
view.layer.shadowColor = UIColor.black.cgColor
view.layer.shadowOffset = CGSize(width: 10, height: 10)
view.layer.shadowRadius = 10
view.layer.shadowOpacity = 1
view.layer.shouldRasterize = true
view.backgroundColor = .orange
return view
}()
lazy var backgroundImageView: UIImageView = {
let view = UIImageView(image: UIImage(named: "fit"))
return view
}()
lazy var titleLabel: UILabel = {
let label = UILabel(frame: CGRect.init(x: 12, y: 20, width: 300, height: 20))
return label
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(blockView)
contentView.addSubview(titleLabel)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func update(title: String) {
blockView.layer.shadowColor = Int.random(in: 0...1) == 0 ? UIColor.blue.cgColor : UIColor.orange.cgColor
titleLabel.text = title
}
}
複製代碼