가장 어려웠던 것들(?)

 
  • 2022년 11월에 Next.js page router를 도입하였는데, 시니어 devOps분께서 ISR로 구현하는게 비용이 저렴하니까 모든 페이지를 ISR로 구현하였을 때, 페이지의 속도는 빨랐지만 데이터가 불일치하는 문제가 발생하였다. ISR의 경우 revalidate 할 수 있는 시간을 받는데, 그 시간이 유저가 접근한 뒤에 그 시간동안 페이지를 재생성하지 않고 캐쉬를 잡아서 보여주는 형식이었다. 목차 페이지와 디테일 페이지의 데이터가 불일치하는 문제가 발생하였고, 회의가 필요하다 싶어서
  • 2023년 11월 Next.js app router 도입
 
 

유튜브 영상과 시계열 데이터를 조합한 실시간 분석 사이트

 
회사에 있는 여러가지 시계열 데이터 셋들을 이용하여 경기 영상과 함께 경기 정보를 분석할 수 있는 프로젝트를 진행하였습니다.
하나의 영상에서 가진 시계열 데이터 셋이 7개였다. 영상 플레이 시간에 따른 현재 index를 매 초마다 찾아야 했습니다.
재밌는 점은 [0]배열이 0초이면 [1]배열이 1초가 아니었습니다. 몇 초인지는 AI가 기록한 시간으로 랜덤이어서 각 배열에 초를 넣는게 아니라 해당 인덱스가 가진 realCount 속성을 가지고 있었습니다.
realCount에서 일부는 0.5초가 realCount 가 1이고, 일부는 1초가 realCount가 1 이었습니다. 그래서 0.5초 기준의 배열과 1초의 배열을 따로 구분지었습니다. 기준은 1초 기준입니다.
 
처음에는 시작부터 원하는 값이 나올 때까지 전체를 순회하여 각 원하는 데이터를 추출하는 로직으로 구성하였습니다. 매 초마다 7개의 배열을 순회하면서 컴포넌트를 업데이트 하는 것은 브라우저 입장에서도 쉬운 일이 아니었습니다.
동영상 플레이어가 1초마다 움직일 때마다 배열을 순회하고 페이지를 리렌더링 했었습니다. 해당 작업은 연산도 오래 걸리고, 동영상 play time이 오래되면 오래될수록 연산이 길어지고 지연되는 문제가 발생하여 로직을 재구성하였습니다.
 
recoil을 이용하여 각 배열의 Index를 상태 관리하였습니다. 변경이 되지 않으면 해당 인덱스를 사용하는 컴포넌트는 리렌더링이 되지 않게 하였습니다.
 
각 인덱스를 저장한 이유는 자바스크립트의 배열은 객체이고 index로 접근 하는 것은 O(1)이기 때문에 순회하지 않는다면 빠르게 데이터를 접근할 수 있기 때문입니다.
 
각 초마다 각 시계열 배열의 currentIndexrealCount와 다음 index의 realCount 사이에 있는지 확인하여 초과하거나 미만이 되면 각 시계열 배열 인덱스에 맞는 realCount를 찾아서 Index를 업데이트 하는 방식으로 하였습니다.
 
업데이트 하는 방식은 다음과 같습니다.
첫번째로 currentIndex가 배열의 마지막 index와 값이 같은지 확인하고, 아닌 경우 1초 단위 배열인지 확인합니다.
0.5초 단위 배열은 realCount 2가 1초이기 때문에 realCount를 2로 나누어 playTime과 비교할 수 있도록 조정합니다.
 
시계열 데이터 배열에서 currentIndex + 1에서 마지막의 요소까지만 비교하기 위해 slice 내장 함수를 사용하여 배열을 두 개로 분리합니다. 그리하여 현재 배열이 순회해야할 배열의 양을 제한시켜서 순회를 하도록 하였습니다.
 
playTimecurrentIndexrealCount 보다 초과하면 분할한 배열의 다음 인덱스의 realCount와 비교하여 초과하면 currentIndex를 업데이트 하였습니다.
 
currentIndexrealCount가 현재 시간보다 작을 경우, currentIndex에서부터 realCount의 조건에 맞는 index를 찾기 위해 -1을 하면서 조건에 맞는 realCount를 찾고 currentIndex를 업데이트 하였습니다.
 
그리고 index를 알맞는 시계열 데이터 인덱스에 상태를 업데이트 합니다.
업데이트 된 인덱스는 분리된 컴포넌트를 찾아서 해당 컴포넌트를 찾아서 해당 컴포넌트에 사용할 시계열 데이터를 index 값으로 접근하여 O(1)로 찾아 상태를 업데이트하여 사용자가 임의로 시간을 조작하더라도 그에 맞는 값을 빠르게 찾아 컴포넌트를 모두 업데이트 합니다.
 
notion image
 
 
프로젝트 초기, 여러 시계열 데이터셋을 이용하여 경기 영상과 정보를 분석하는 작업을 진행했습니다. 각 데이터셋은 7개의 배열을 포함하며, 영상 플레이 시간과 실제 인덱스 간의 랜덤한 매핑이 이뤄졌습니다.
 
초기에는 전체 데이터를 순회하여 원하는 값을 찾는 로직을 사용했으나, 브라우저 성능 및 지연 문제로 인해 로직을 개선해야 했습니다.
 
그리하여, recoil을 활용하여 각 배열의 Index를 상태 관리하여 리렌더링 최적화를 하였고, 각 초마다 배열을 순회하지 않고, 현재 Index와 다음 Index 사이에 있는지 확인하여 효율적으로 Index를 업데이트 하였습니다.
 
  • slice 함수로 배열을 분리하여 순회 범위 제한.
  • 동영상 플레이 시간과 비교하면서 Index 업데이트
  • 업데이트된 인덱스를 찾아 컴포넌트에 빠르게 반영하여 사용자 경험 향상.
 
그 결과 브라우저 성능 최적화 및 지연 문제 해결하고, 초 단위 배열과 1초 단위 배열을 구분하여 효율적으로 처리하였습니다.
 
 
피드백
  • 프로젝트 성능 향상과 브라우저 부하 감소로 사용자에게 원활한 경기 정보 제공.
  • 효율적인 데이터 업데이트 및 상태 관리로 코드 유지보수성 향상.
  • 복잡한 연산을 최적화하여 효율적인 알고리즘 도입으로 개발 경험 및 기술 역량 강화.