💭 TMI
추첨운이 하나도 없는 내가 운좋게 당첨이 되어 토스 slash 24 컨퍼런스를 다녀왔다. 몰랐는데 오프라인으로 컨퍼런스를 진행한 게 이번에 처음이라고 한다. 첫 번째 오프라인 행사에 초청을 받다니 영광이였다. 오프닝 소개를 들어보니 대략 5:1 의 경쟁률이였다고 한다. 생각보다 경쟁률이 낮아서 놀랐는데, 생각보다 뽑은 인원이 많았다 ㅋㅋㅋㅋㅋㅋㅌ 아무튼 이렇게 코엑스 홀을 빌려 무료로 컨퍼런스를 진행한다는 것 자체가 개발 지식 공유에 진심인 것 같아서 이런 회사에서 일하고 싶다는 마음이 커졌다.
📘 프론트엔드 세션 정리
프론트엔드 세션은 총 4개로 오전에 모두 진행되었다. 들으면서 중요하다고 생각이 드는 부분들을 적으면서 들었지만, 현장이다보니 직접 보고 들으려고 노력했다. 모든 내용을 이해하지는 못했지만 어떤 문제를 해결했는지, 어떻게 문제를 해결했는지에 집중했다. 새롭게 알게 된 내용이 많아 딥한 내용 정리는 나중에 하고, 핵심적인 부분들과 느낀점을 간략하게 남기려고 한다.
✅ 토스가 오프라인 결제를 빠르고 안정적으로 혁신하는 방법 : 유건님, 나석주님
- 오프라인 결제 시장 진출 : 토스 포스(포스기), 토스 프론트(결제 단말기)
- 단순한 UI 수정에도 Electron 을 활용한 데스크톱 앱을 빌드할 시 많은 시간 소요
- 앱을 부분 빌드할 순 없을까?
- UI만 변경될 경우 renderer process, main process 부분은 새로 빌드하지 않음
- HTML, CSS, JS 를 별도의 webview bundle로 분리 및 CDN 적용
- 대부분의 비즈니스 로직이 webview bundle에 있어 android/ios 배포도 수월하게 진행
- 안정적으로 수십만건의 결제 만들어내기 : 토스포스와 토스 프론트 간의 양방향 통신
- 연결 안정성
- 유선 연결 : 물리적 간섭으로 인한 데이터 유실로 인해 토스 자체적으로 프로토콜 개발
- 무선 연결 : 불안정한 와이파이로 인해 DNS-SD를 활용하여 브로드캐스팅으로 변경되는 IP 찾기
- 결제 안정성
- 다양한 요구사항에 의해 복잡해진 결제 코드가 버그 위험성 높아짐
- 시점에 따라 동일 관심사별로 분리 → 라이프사이클 정의 (주문 전, 주문 후, 결제 전, 결제 후 등)
✅ 잃어버린 생산성을 찾아서, react-native로 알아보는 디버깅 : 이근혁님
- react-native로 개발 시 디버깅이 어려움 → Flipper
- Chrome Devtools Protocol(CDP) 를 활용하여 웹과 동일한 디버깅 경험을 제공하는 도구 필요
- 0.73 버전에 나온 새로운 디버깅 도구는 좀더 개선되었지만, 네트워크 인스펙터 지원 ❌
- 네트워크 인터셉터를 활용하여 네트워크 인스펙터 구현
- 네이티브(Android, iOS)에서 네트워크 작업을 가로채고 직접 CDP 메시지를 전송하는 인터셉터
✅ Yarn Plugin으로 우아하게 자동 로깅하기 : 전성님
- 로그를 많이 남김
- screen : 화면이 열림 - useEffect
- impression : 요소가 보여짐 - IntersectionObserver
- click : 요소를 누름 - onClick
- 프로덕션 코드 변경 없이, TDS와 로깅 간 독립적 배포가 가능하면서, 디자인 시스템 위에 로깅을 얻는 방법?
- TDS 대신 로깅 라이브러리를 바라보도록 할 수 있을까? → yarn berry 플러그인
- yarn의 설치 과정 : resolution → fetch → link
- resolution 단계에서 TDS 패키지를 바로 찾는 게 아니라, 로깅 패키지를 거치도록 하고 해당 패키지가 TDS 패키지를 의존성으로 가지도록 구현
✅ N개의 탭, 단 하나의 웹소켓 : SharedWorker : 박건영님
- 모바일에서만 사용했던 토스 증권 앱이 PC 버전을 출시하면서 문제 발생
- 실시간 데이터를 가져오는 방법으로 웹소켓을 사용하고 있는데, 기존에 유저 한명 당 웹소켓 객체를 1개씩 할당하면 문제 없었음
- 데스크톱 환경에서 탭이 여러 개일 경우, 탭의 개수만큼 웹소켓 객체 생성
- 서로 다른 탭은 서로 다른 스레드에서 동작하므로 변수 공유 ❌
- 사용하지 않는 탭의 연결을 끊어줄 수 없을까?
- Focus & Blour Event : 화면에 보이는데 focus가 안되어 있을 경우 통신 ❌ → UX 악영향
- visibilityChange : 사용하지 않더라도 화면에 보이는 탭의 개수만큼 연결 존재
- 모든 탭을 하나의 연결로 받을 수 없을까?
- web worker API
- Dedicated Worker : worker를 생성한 탭에서만 접근 가능
- Shared Worker : 탭끼리 worker 공유 가능
- 같은 origin인가?
- 불러온 JS 파일이 같은가?
- 연결된 모든 port로 데이터 통신(message event)
- Shared Worker를 지원하지 않는 브라우저의 경우 Dedicated Worker로 fallback
- 번들링
- worker를 생성할 때 로컬과 경로가 다름
- webpack에서는 URL 객체와 import.meta 를 활용하여 경로 추적 가능
- 메모리 누수
- 사용하지 않는 탭의 리소스 정리 필요
- beforeUnload Event : 확실히 동작한다는 보장 ❌
- 탭이 닫히면 MessagePort 가 가비지 컬렉션되는 것을 감지할 수 있을까?
- 배열에 갖고 있으면 참조하고 있으므로 가비지 컬렉션 ❌
WeakRef
로 가비지 컬렉션 감지