일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 프로세스 스케줄링
- 오브젝트
- struct
- @state
- 데드락
- Algorithm
- 상호배제
- Linked List
- IOS
- 운영체제
- core data
- 동기화
- Apple Developer Academy
- Codable
- 100 days of SwiftUI
- 알고리즘
- COLOR
- async
- deadlock
- 비동기
- UserDefaults
- SwiftUI
- 앨런
- Swift
- scrollview
- decode
- 인프런
- forEach
- 가상 메모리
- 동시성
Archives
- Today
- Total
기어가더라도 제대로
[SwiftUI-기초] drawingGroup() - Image 성능 높이기 본문
- 다소 자극적인 제목을 달아놨는데, 성능을 높이는 원리를 말씀드림
- 기본적으로 뷰 렌더링 작업은 Core Animation 을 사용
- 다만 그리기 작업이 좀 복잡해지면 화면이 일정 FPS 아래로 내려가는 것을 볼 수 있음
- iOS 최대 주사율은 120 fps 인데 복잡한 그리기 작업이 들어가면 그 이하로도 내려갈 수 있음
- 예제 코드를 통해서 알아보겠음
struct ContentView: View {
@State private var colorCycle = 0.0
var body: some View {
VStack {
ColorCyclingCircle(amount: colorCycle)
.frame(width: 300, height: 300)
Slider(value: $colorCycle)
}
}
}
struct ColorCyclingCircle: View {
var amount = 0.0
var steps = 100
var body: some View {
ZStack {
ForEach(0..<steps) { value in
Circle()
.inset(by: Double(value))
.strokeBorder(color(for: value, brightness: 1), lineWidth: 2)
}
}
}
func color(for value: Int, brightness: Double) -> Color {
var targetHue = Double(value) / Double(steps) + amount
if targetHue > 1 {
targetHue -= 1
}
return Color(hue: targetHue, saturation: 1, brightness: brightness)
}
}
- 코드가 어렵긴한데 100개의 원을 그리는 뷰
- 100개의 원을 각각 100개의 뷰로 그려냄
- 이미 복잡한데 아직 그렇게 느리지는 않음
- 의도적으로 복잡도를 높이기 위해 기존에 컬러 대신 선형 그라디언트를 추가
.strokeBorder(
LinearGradient(
gradient: Gradient(colors: [
color(for: value, brightness: 1),
color(for: value, brightness: 0.5)
]),
startPoint: .top,
endPoint: .bottom
),
lineWidth: 2
)
- 위에서 아래로 갈수록 밝기를 절반정도 줄인 선형 그라데이션을 추가했는데 극적으로 느려짐
- 슬라이더를 움직이기 어려운 정도
.drawingGroup
- 위의 코드는 복잡하지만 100의 원을 그리기 위해 100개의 View를 그려냈다고 하면..
- drawingGroup() 을 통해서 하나의 통합된 뷰로 나타낼 수 있다면 많은 계산 과정이 줄어듦
- 일반적인 뷰렌더링은 Core Animation 이지만 .drawingGroup()은 Metal 을 사용
- Metal: GPU를 이용하여 그리기에 더 전문적인 프레임워크
- 결과적으로 100개의 view 가 아닌 통합으로 렌더링된 하나의 view 가 나옴
- 컨텐츠를 렌더링해서 하나 하나의 뷰를 내는 것이 아니라 화면에서 뷰로 나오기 전에 스크린의 이미지로 뷰를 합쳐서 하나의 뷰로 나옴
- 결과적으로 화면 그리기 작업이 빨라짐
// ColorCyclingCircle
var body: some View {
ZStack {
// existing code…
}
.drawingGroup()
}
- Metal은 꼭 필요한 때에만 사용해야함
- 닭 잡는데 소잡는 칼 필요 없듯이 간단한 뷰를 그릴 때조차 GPU를 사용하기에 과도한 자원 소모가 될 수 있음
'SwiftUI - 기초' 카테고리의 다른 글
[SwiftUI-기초] BlendMode - 색상 혼합 (0) | 2022.11.20 |
---|---|
[SwiftUI-기초] CGAffineTransform - 약간의 기하학을 곁들인.. (0) | 2022.11.19 |
[SwiftUI-기초] ImagePaint - 이미지를 배경색처럼 사용하기 (0) | 2022.11.17 |
[SwiftUI-기초] strokeBorder() - 도형을 프레임에 딱맞게 (0) | 2022.11.16 |
[SwiftUI-기초] Shape, 도형 (0) | 2022.11.15 |
Comments