_

Always be tactful

성장 과정/개인 프로젝트

배열 순회 문제와 팝업 진행률 이슈

funczun 2025. 4. 23. 04:23

현재는 savedSites 배열을 순회하며 새로 넘겨받은 url과 일치하는 사이트가 있는지, 인덱스를 통해 중복을 판단한다. 만약 중복이라면 url을 제외한 모든 요소를 갱신하고 있다. (title, lastAccessed, scroll, height)
 
팝업의 경우, Manual Save를 누를 때마다 진행률이 갱신된다.
실제 진행률을 동적으로 반영하지 않아, 사용자가 직접 갱신해 주는 것이나 다름없다.
 
아쉬운 점이 몇 가지 보인다.
일단 첫째, Map으로 관리했다면 어땠을까?


왜 배열로 관리했을까?

Map을 사용할 경우, 직렬화 이슈가 발생한다.
배열은 JSON으로 자동 변환되지만, Map은 그렇지 않기 때문이다.
 
그럼에도 불구하고, 로직상 Map이 훨씬 깔끔하고 빠른 건 명백하다.
적절한 변환 과정만 거치면 충분히 도입 가능한 구조기에, 고려해 볼 만한 개선점이다.

*다만, 정렬 문제도 고려해야 한다.


둘째, 실제 진행률이 자동으로 반영될 순 없을까?
 
스크롤 이벤트를 감지해서 실시간으로 반영한다던가, 팝업이 열릴 때마다 최신 값으로 다시 가져온다던가, 백그라운드에서 주기적으로 스크롤 값을 체크하는 방식으로 말이다.


팝업 진행률, 실시간 반영하려면?

1. 스크롤 이벤트를 감지하자.

현재 페이지의 진행률이 스크롤 이벤트 발생에 따라 계속 갱신되듯, 팝업도 갱신시키는 방식이다. 실시간으로 반영되며, 정확하다는 장점이 있지만, 퍼포먼스 부담이 증가할 것으로 예상된다.

debounce나 throttle을 써서 이벤트 빈도를 조절할 수 있으니 여러 방면에서 고민해 보자.

 

2. 팝업이 열릴 때마다 최신 스크롤 값을 다시 가져오자.

팝업이 열릴 때마다 현재 탭의 scrollY 값을 실시간으로 받아서 scrollData를 덮어쓰는 방식이다. 사용자가 직접 행동할 때만 갱신되어 퍼포먼스 부담이 덜하다. 하지만 비활성 탭의 진행률은 반영할 수 없다는 단점이 있다.


팝업이 열릴 때마다 최신 값을 다시 가져오는 방식은 비활성 탭을 반영하지 못한다는 치명적인 단점이 있다. 따라서 스크롤 이벤트 감지 시 saveCurrentSite()도 같이 호출해서 팝업에 있는 savedSites도 자동 갱신되게 하는 방식을 따르기로 했다.

 

다만, 두 가지 이슈가 따른다.

 

1. 중복 저장 부하

saveCurrentSite()는 chrome.scripting.excuteScript로 탭에서 정보를 가져오고, chrome.storage.local.set()까지 하기 때문에 비용이 큰 편이다. 3초마다 계속 호출된다면 성능에도 영향을 줄 것으로 보인다.

 

2. 팝업 UI 제어 불가

팝업은 열려있을 때만 렌더링 되기 때문에 content 스크립트에서 saveCurrentSite()를 호출한다고 하여 자동으로 갱신되지 않는다. 즉, 의미 없는 시도에 가깝다.

 

결국 두 방식 모두 현재 이슈를 해결할 수 없다.

이 부분에 대해서는 조금 더 고민이 필요할 듯하다.


일단 기존 배열 방식을 Map으로 전환하고, 이참에 저장소 구조도 재설계해야겠다.

 

모든 사이트에 대한 스크롤 정보 저장 및 복원이 sync에서 이루어지다 보니, Quota를 초과할 여지가 충분하기 때문이다. 차라리 매뉴얼 세이브에 대해 sync를 쓰고, 자주 발생하는 스크롤 이벤트에 대해서는 local을 사용하도록 수정해야겠다.

 

체감이 잘 안 돼서, 직접 데이터 날려보고 50KB가 어느 정도인지 확인해야 할 듯..

수정) 확인 결과 실제 저장소 크기는 100KB였고, 한 웹 페이지당 0.24KB 정도 차지한다. 이론상 400개의 웹 페이지에 대해 책갈피 설정을 할 수 있다는 이야기다. 다만 몇 가지 예상되는 이슈나 개선점들이 떠오르는 게 있는데, 딥한 건 일단 v1.0.0 완성 후 최적화 단계일 때 다루어야겠다.