-
Notifications
You must be signed in to change notification settings - Fork 0
[#317] Canvas에서 메인스레드가 아닌 스레드에서 이미지를 비동기적으로 가져오도록 개선한다 #318
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
21f3275
refactor: PhotoImageLoader을 통해 비동기로 이미지를 불러오도록 개선
opficdev 6a2084b
refactor: UIImage 데이터를 한 곳에서만 관리하기
opficdev 4c96419
fix: CI와 Xcode 환경이 달라 CI 환경에 맞는 형태로 수정
opficdev 20b1b1f
Merge branch 'develop' into refactor/#317-async-image-fetch
opficdev d963404
refactor: 이미지 요청을 비동기로 요청하고 요청 순서를 보장을 유지하는 형태로 개선
opficdev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
mirroringBooth/mirroringBooth/Device/Mirroring/PhotoComposition/PhotoImageLoader.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| // | ||
| // PhotoImageLoader.swift | ||
| // mirroringBooth | ||
| // | ||
| // Created by 최윤진 on 2026-03-09. | ||
| // | ||
|
|
||
| import UIKit | ||
|
|
||
| enum PhotoImageLoader { | ||
| static func loadImages(from photos: [Photo]) async -> [UIImage?] { | ||
| var loadedPhotoImages = [UIImage?](repeating: nil, count: photos.count) | ||
|
|
||
| await withTaskGroup(of: (Int, UIImage?).self) { taskGroup in | ||
| for (index, photo) in photos.enumerated() { | ||
| taskGroup.addTask { | ||
| let loadedPhotoImage = await loadImage(from: photo.url) | ||
| return (index, loadedPhotoImage) | ||
| } | ||
| } | ||
|
|
||
| for await (index, loadedPhotoImage) in taskGroup { | ||
| loadedPhotoImages[index] = loadedPhotoImage | ||
| } | ||
| } | ||
|
|
||
| return loadedPhotoImages | ||
| } | ||
|
|
||
| static func loadImage(from photoUrl: URL) async -> UIImage? { | ||
| await Task.detached(priority: .userInitiated) { | ||
| UIImage(contentsOfFile: photoUrl.path(percentEncoded: false)) | ||
| }.value | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PhotoCompositionView에서PhotoFramePreview가 만들어지는 형태를 보면, 사진이 선택될 때마다 (상태가 변할 때마다) 새로운PhotoFramePreview가 만들어지고 있습니다.그래서 시도하신 캐싱 로직은 수행되지 않는 상태인 듯 합니다...!
해당 흐름 다시 한 번 확인부탁드립니다!
더해서 캐싱을 적용한다면, 이미지를 렌더링하는 CPU 사용률은 줄어들겠지만
UIImage저장으로 인해 메모리 사용량은 늘어날 듯 한데요,개선 이전에도, 개선 후에도 사용 측면에서는 버벅임이 없지만 이런 사용량 변화에 대한 분석도 같이 공유해주시면 좋을 듯 합니다.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sangYuLv
피드백 감사합니다!
아시겠지만 SwiftUI는 상태가 변경되면 그 뷰를 완전히 새로 그리지 않고 재계산을 통해 알아서 뷰를 재사용하는 형태입니다. 특히 PhotoFramePreview에서 자주 변경이 되는 selectedPhotos 가 채택한 Photo 타입은 Identifiable을 채택함으로서 뷰 계산에 영향을 주고 있어서 selectedPhotos가 변경된다고 PhotoFramePreview가 완전히 다시 그려진다고 보기엔 좀 어려울것 같습니다. 아래 영상은 selectedPhotos가 변경되는 것과 별개로 PhotoFramePreview의 onAppear가 최초 한번만 뜨는 것을 확인할 수 있는 영상입니다
2026-03-13.3.54.12.mov
UIImage를 저장하는 딕셔너리(
photoImagesByURL) 가 실제로 PhotoFramePreview에서의 메모리 캐싱 역할을 하고 있습니다. PhotoFramePreview를 설명한 대로, 뷰가 재계산되는 것이니 캐싱도 정상적으로 되는것을 확인할 수 있습니다. (아래 이미지 참고)다만 변경 전과 변경 후에 대해 명확하게 설명하지 않는 것은 PR 영상과 기존 리팩토링 문서 아래쪽의 첫번째 영상과 비교가 가능하다고 생각하여 작성하지 않았는데 작성하는게 오히려 나았을 것 같네요. 요약 정리만 하자면, 개선 전은 최대 410MB, 개선 후는 최대 390MB 사용량을 보여 메모리 사용 개선이 조금 있었다고 말씀드릴 수 있겠습니다!