이 둘의 성능이 몸으로 체감된 경험으로 이 글을 시작하려고한다.
화면에 선을 표시하고 UIView가 그 선을 따라서 이동한다. 이동시에는 지나간 부분의 선을 지워야한다. 이 진행은 slider로 움직이면 앞뒤로 자유자재로 움직이며 선이 그려졌다 지워졌다 해야한다.
이 문제를 어떻게 해결해야될까가 첫번째 과제였다.
아래와 같은 질문들을 해결해야했다.
Q) 선이니까 path를 그릴까?
A) path를 UIView가 지나가면 그 부분만 선을 지울 수 있을끼?
-> path는 부분적으로 색을 바꾸기 어렵다.
그래서 아래와 같이 해결하기로 했다.
매우 작은 원들을 나열하여 선처럼 보이게해야겠다. 그리고 view가 지나가면 그 원들의 색을 clear로 바꿔야겠다.
하지만 이러한 생각에는 큰 문제가 있었는데, 작은 원들을 선처럼 보이려면 화면에 많은 수의 원들이 그려져야했다.
초기에는 이 점들에 gesture가 붙어야해서 UIView로 약 30만개의 원들을 통해 선을 만들었다.
이는 view를 그리는 시간만 30초가 걸리는 기적의 앱을 만들게 되었다.
그러던중 기획의 변경으로 인해 각 원들의 gesture가 필요없어졌다.
30초라는 어마어마한 시간을 줄여야했다.
아! 눈에 보이기만 하는 거라면 UIView가 아니라 CALayer로 바꾸자!
기존에 원들을 CALayer로 바꾸었고 이는 1초가 미만의 수행시간이 소요됬다.
여기서 질문이 들었다.
앱에서 벗어나 독립된 프로젝트로 위 결과를 보여주겠다.
for _ in 0...400000 {
let layer = CALayer()
layers.append(layer)
layer.frame = CGRect(x: 200, y: 200, width: 100, height: 100)
layer.backgroundColor = UIColor.cyan.cgColor
view.layer.addSublayer(layer)
}
위와 같이 400000개의 layer를 view에 추가했다.
[초기화시 걸리는 cpu time]
보시는 것처럼 다양한 작업이 실행되지만 역시 가장 큰 비중은 addSublayer에 있다.
[background color change시 cpu time]
실제로 색을 변경할때는 setBackgroundColor가 거의 대부분의 시간을 차지한다.
for _ in 0...400000 {
let reactangleView = UIView()
views.append(reactangleView)
reactangleView.frame = CGRect(x: 200, y: 200, width: 100, height: 100)
reactangleView.backgroundColor = UIColor.cyan
view.addSubview(reactangleView)
}
[초기화시 걸리는 cpu time]
보시다 시피 add하는 건 큰 차이가 나지 않는다. 역시 마찬가지로 UIView에 큰 초기화를 하지 않았고, UIView의 모양만 초기화했기때문에 CALyer를 사용하는 UIView와 큰차이가 나지 않는 모습이보이지만...
하지만 add하는 부분을 제외하고도 다양하게 많은 것들을 초기화하기 때문에 시간차이가 생기게 된다.
[background color change시 cpu time]
실제로 CALayer의 색변화시키는 부분은 큰차이가 없는것을 볼 수 있다.
실제로 UIView를 CALayer로 바꿨더니 앱에서 더 큰 차이를 느낄 수 있었다.
UIView는 Graphic을 위한 가장 high level이기 때문에 많은 기능과 비교적 적은 자유성을 가지고 있다.
당연히 초기화시에도 많은 절차과 과정이 있고 그 때문에 실제로 UI에서의 성능차이를 느낄 수 있었다.