250x250
반응형
Notice
Recent Posts
Recent Comments
Link
관리 메뉴

스윞한 개발자

SNKit 개발 회고 - 2 본문

프로젝트

SNKit 개발 회고 - 2

스윞남 2025. 5. 31. 19:08
728x90
반응형
SMALL

안녕하세요! 이번 포스팅에서는 SNKit 개발 회고 시리즈의 마지막 편입니다. 이번 포스팅에서도 앞으로 SNKit의 개발 방향과 깨달음들을 공유해보려고 합니다 ㅎㅎ

 

#SNKit 한계 개선 방향

1. NSCache 의존성 문제

지난 편에서 언급했던 NSCache의 딜레마,,, 이게 제일 고민인것 같습니다. 현재는 NSCache + 별도 스코어 관리 시스템으로 우회하고 있지만, 근본적인 해결책은 아닌 거 같습니다.

 

iOS 시스템이 메모리 압박을 느끼면 제 스코어 알고리즘과 상관없이 NSCache를 LRU 알고리즘에 따라 비워버립니다. 그럼 제가 기존의 라이브러리와는 차별점을 두었던 가중치 기반 캐시 스코어링이 의미 없어지는 상황이 발생합니다.

 

그래서 제가 생각하고 있는 방법은 NSCache 방법 말고, 완전 커스텀한 메모리 관리 시스템을 구축하려고 계획 중입니다. 

 

1. 빠른 접근이 중요한 경우

이럴때에는 Hash를 통해서 구현해 보면 어떨까 생각해 보았는데요, 기존의 많은 TableView/CollectionView에서 빠른 스크롤이 필요한 경우 적합할 거 같습니다. 하지만  각 이미지가 얼마나 메모리를 사용하는지 별도로 계산해야 하기에 메모리 사용량의 추적이 어렵다는 단점이 있을 것 같습니다.

 

2. 메모리 사용량 정확한 제어가 필요한 경우

이럴 경우에는 Binary Heap + HashMap을 생각해보았습니다. 메모리가 제한적인 환경이나 고해상도 이미지를 많이 다루는 앱에서는 메모리 관리가 핵심이기 때문에, 이때 Binary Heap을 사용해서 O(log n) 시간에 가장 덜 중요한 이미지를 찾아서 제거할 수 있을 거 같습니다. 특히 이미지 편집 앱이나 사진 갤러리 앱에서 혹은 저의 와랄라 앱에서 많은 사진을 보여줄때 메모리 부족으로 인한 크래시 방지를 해야 하는 것이 중요하니까요 ㅎㅎ

 

또 사용자 행동 패턴이 복잡한 앱들은 다른 방법을 생각해 볼 수 있을 거 같습니다. 지금까지 생각해 본 앱들은 단순히 많은 이미지를 보여줄 때, 혹은 셀이 재사용이 되는 경우를 고려해 보았습니다. 하지만, 쇼핑 앱과 같은 단순히 최근 본 상품만이 아니라 위시리스트에 담은 상품, 자주 보는 카테고리, 구매한 상품 등 여러 요소를 고려해야 할 거 같습니다. 

 

3. 모든 자료구조의 통합

제가 최종적인 목표로 하는 건 상황에 맞는 최적의 전략을 갖고 개발자가 선택할 수 있는 시스템입니다. 메모리가 여유로울 때는 속도 우선으로 HashMap을 사용하고, 메모리 압박이 심할 때는 Binary Heap으로 효율적인 정리를 하고, 사용자 패턴이 복잡할 때는 또 다른 알고리즘을 활용해 정교한 스코어링을 하는 것 입니다.

 

결국에 저는 다른 라이브러리와는 차별화된 특별한 캐시 전략을 사용하려 했지만, 모든 자료구조를 통합하려고 하는 이유는 모든 상황에 완벽한 해결책은 없다는 생각이 들었습니다. 대신 각 상황의 특성을 알고 개발자들에게 그 상황에 맞는 옵션을 제공하는 게 좋다고 생각했습니다.

 

또한 참조 지역성의 원리도 고려하려고 했습니다. 시간적/공간적/의미적 지역성을 모두 반영할 수 있으면 더 큰 장점을 가지지 않을까? 생각하고 있습니다. 

 

#개발 방향

1. HasahMap + LinkedList 조합 구현 -> NSCache의 문제점 해결

2. Binary Heap으로 메모리 관리 

3. Red-Black Tree 등과 같은 자료구조로 복잡한 사용의 패턴을 반영

4. 앱 특성에 따라 최적의 전략을 개발자가 선택할 수 있도록 옵션 제공

 

결국에는 제가 앞서 말한 OS의 자의적인 판단에 의존하지 말고 개발자가 원하는 대로 정확히 동작하는 시스템으로 개발시키는 게 필요한 거 같습니다. 

 

##SwiftUI 지원

SNKit의 SwiftUI의 지원은 아직 부족합니다,, 제가 SwiftUI에서 사용할 수 있도록 SNImage 컴포넌트를 만들긴 했지만, SwiftUI의 선언적 특성을 활용하지 못하고 있습니다 ㅠ

 

개발자가 필요한 옵션들에 대해 메서드 파라미터를 통해 받아오고 있지만 이런 부분들도 좀 더 모디파이어와 같이 빌더패턴으로 제공할 수 있을 것 같습니다.

 

##이미지 포맷 최적화

현재는 주로 JPEG/PNG에 최적화되어 있는데, GIF/MP4/WebP/HEIF 같은 포맷들도 많이 사용됩니다.

위와 같은 포맷들을 지원하면서도 기존 포맷과의 호환성을 유지하는 게 저의,, 개발 목표입니다!

 


처음에는 기존의 라이브러리와는 차별화된 완벽한 라이브러리를 만들고 싶었습니다. 모든 상황에서 최적의 성능을 내는,,, 하지만 개발하면서 그리고 초기 완성된 라이브러리를 만들고 나서 깨달았습니다.

 

모든 기술이 그냥,, "트레이드오프"의 관계일 뿐

 

 

  • 메모리 사용량 vs 처리 속도
  • 캐시 히트율 vs 저장 공간
  • 기능의 풍부함 vs API의 단순함

 

모든 것들을 다 고려하고 모든 부분에 장점을 가질 수는 없었습니다. 그래서 저는 대신 사용자가 자신의 상황에 맞게 선택할 수 있는 옵션을 제공하는 게 더 중요한 거 같았습니다.

 

또 제가 기술적인 구현에만 몰두하다 문득 리드미를 쓰려고 할 때 힘들었던 기억이 있습니다. 결국 문서화를 소홀히 하면 안 되겠다,,라고 생각했습니다. 

 

지금 제 라이브러리에서의 코드 커버리는 37% 정도입니다. 작은 수치이지만 제 나름대로 우선순위를 정하고 필요한 비즈니스로직에 대해서 먼저 테스트 코드를 작성했습니다. 처음에는 테스트 코드를 대충 넘어가고 그냥 로그를 통해 동작만 제대로 되면 되는 거 아닌가 생각했습니다. 특히 네트워크 에러 상황 테스트, 메모리 압박 상황 시뮬레이션, 동시성 문제 재현  등에 대한 상황을 테스트하는 것은 쉽지 않은 거 같습니다. 

 

지금의 테스트 코드에는 네트워크 상황에 대한 테스트는 있지만, 메모리 압박/동시성 문제 재현과 같은 테스트는 더 고민을 해보고 테스트 코드로 추가해 봐야 할 거 같습니다.

 

오픈소스로 배포하면서 주변에 개발자분들에게 여러 도움과 피드백을 많이 받았습니다. 이전에는 사용법만 충분히 알고 완성만 되면 끝이라고 생각해 왔습니다. 하지만 이번 프로젝트를 만들어보면서 처음부터 여러 부분을 고려한 설계의 필요성, 오픈 소스들의 내부 동작/원리 이해의 필요성, 지속적인 개선과 유지보수가 더 중요하다는 것을 깨달았습니다.

 

예전에는 "내가 만들고 싶은 것"을 만들었다면, 이제는 "사용자가 필요로 하는 것"을 만들어보려고 합니다. 

 

Kingfisher, SDWebImage와 어깨를 나란히 할 수 있는 라이브러리로 성장할 수 있겠죠 ㅎㅎ.  SNKit을 개발하면서 기술적으로, 개인적으로 많이 성장한 거 같습니다. 아직 부족한 점들이 많은 주니어 개발자이지만, 하나씩 개선해 나가면서 더 나은 라이브러리로 만들어 가고 싶습니다!!

 

이번 포스팅은 여기서 마무리하겠습니다! 긴 글 읽어주셔서 감사합니다. 잘못된 부분에 대한 피드백은 언제든지 환영입니다. 감사합니다!!

 

 

 

https://github.com/jeoungsung12/SNKit

 

GitHub - jeoungsung12/SNKit

Contribute to jeoungsung12/SNKit development by creating an account on GitHub.

github.com

 

728x90
반응형
LIST