🔥 문제 상황
썸네일이 바뀌지 않는다!!!
- 새로고침을 해도 썸네일이 바뀌지 않는 상황이 발생했습니다.
🤔 원인
- 콜렉션뷰의
DataSource
에 전달해주는 값은urlString
으로 일정하기 때문입니다. - 라이브 스테이션은 동일한
urlString
으로 이미지만 바꿔주는 형식으로 작동하기 때문입니다.
💡 해결 과정
🧑🏻💻 모든것을 Fetch 해오자!
- PR 링크
- Fetch 할때 이미지를 내려받아
dataSource
에 넣어준다면image
자체가 바뀌었기 때문에dataSource
를 업데이트 해줄 수 있었습니다.
채널 정보 및 URL 가져오기 → 가져온 URL로 이미지 로드하기 → apply snapshot
👀 새로 생긴 문제 상황
- 모든 이미지를 그때그때 받아보다보니 속도 저하 문제가 생겼습니다.
Channel
모델에 불필요해보이는URLString
,UIImage
속성이 둘다 포함되는 상황
public struct Channel: Hashable {
let id: String
let name: String
var thumbnailImageURLString: String
var thumbnailImage: UIImage?
let owner: String
let description: String
}
🧑🏻💻 URLString
만 받아와서 셀 업데이트를 무조건 하게 하자!
- 데이터를 받아온다면 무조건
reload
하는 방식을 채택해보았습니다.Channel
의image
속성도 지웠습니다.
썸네일 바꾸기 성공! |
---|
// 변경 전
dataSource.?.apply(snapshot, animatingDifferences: true)
// 변경 후
dataSource?.applySnapshotUsingReloadData(snapshot)
- 기존에
Cell
이 이미지를 로드하는 방식을 다시 가져오기로 했습니다. 관련 PR URLString
을 받아오면 각Cell
이 이미지를 로드하는 방식이 합리적인 방법이라고 느껴졌습니다.
// 각 셀에서 일어나는 일들
func configure(channel: Channel) {
loadAsyncImage(with: channel.thumbnailImageURLString)
self.titleLabel.text = channel.name
self.descriptionLabel.text = channel.owner + (channel.description.isEmpty ? "" : " • \(channel.description)")
}
private func loadAsyncImage(with imageURLString: String) {
guard let url = URL(string: imageURLString) else { return }
URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
guard error == nil,
let data else { return }
DispatchQueue.main.async {
self?.thumbnailView.configure(with: UIImage(data: data))
}
}.resume()
}
👀 새로 생긴 고민 상황
applySnapshotUsingReloadData
를 살펴보면 당연하게도without computing a diff or animating the changes
라는 말이 있었습니다.reloadData()
와 똑같이 작동하는 듯 보였습니다...
🤔 잠깐만... apply
와 차이를 보면 성능에 큰 영향이 있을까?
- 가장 궁금했던건 얼마나 성능 차이가 날까? 라는 궁금증이었습니다. 왜냐하면 applySnapshotUsingReloadData의 경우
Reset UI
를 한다는 이야기가 있어 콜렉션뷰를 다시 그린다고 이해했기 때문에 리소스 차이가 얼마나 클까 하는 궁금증 이었습니다. - 방송을 2개 띄운 후 테스트를 진행해봤습니다.
- CPU: 아무래도 image를 다시 받아오니까 CPU 사용량이 많을 수 밖에 없습니다. 51% → 58%
apply | applySnapshotUsingReloadData |
---|---|
- 메모리: 약 1.50% 증가했습니다. 이미지를 받아오고 새로 로드하는 과정 + UI를 다시 그리는 과정에서 차이가 있는 것 같습니다.
apply | applySnapshotUsingReloadData |
---|---|
- 네트워크: 당연히 바뀐 썸네일 이미지를 받아와야 하니까 네트워크가 주기적으로 쓰이네요.
apply | applySnapshotUsingReloadData |
---|---|
- 결론: 이미지를 새로 로드하는 것 정도 차이가 난다...? 어메이징하게 크게 차이는 나지 않는다...?
🥹 DiffableDataSource
의 의미가 퇴색되었다.
- 부드러운 애니메이션... 은 고사하고,
DiffableDataSource
를 활용하여 이미 만들어진 셀을 재사용하면서 변경된 데이터만 업데이트하고 싶었는데... 이미지를 변경해야 하기 때문에 모든 셀을 다시 그려야하는 방식인applySnapshotUsingReloadData
를 사용한 순간DiffableDataSource
왜 쓰지? 라는 생각이 들었습니다. - 제가 원하는 방향은 이미지가 바뀔 때에만
apply snapshot
을 하고 싶었습니다. 그렇게 된다면 셀을 업데이트 할때 바뀐 썸네일만 다시 그리니까 이미지를 다시 그리는 리소스도 줄어들 것이라고 생각했습니다. Building High-Performance Lists and Collection Views
...라는 멋진 것을 발견했지만... 딥다이브하다가 실패했습니다 🥹 우선 중복 코드만 개선했습니다...
'→ Shook' 카테고리의 다른 글
[Project-Shook] Hero Animation 도입기 (0) | 2024.12.04 |
---|