OSSCA Chromium

기여 목록 / 8500386

Replace symbol-keyed caches with WeakMaps in panels/timeline

DevToolsrefactordevtools/devtools-frontendIn Review

DevTools panels/timeline에서 JS Symbol을 동적 프로퍼티 키로 쓰던 캐시 2개를 WeakMap으로 교체해 @ts-expect-error 7건을 제거한 컨트리뷰션입니다.

문제 설명

  • trace 이벤트 객체에 Symbol을 프로퍼티 키로 붙여 캐싱
    • TypeScript가 표현하지 못해 접근마다 @ts-expect-error TODO(crbug.com/1011811)가 필요했음
  • TimelineUIUtils.ts 4곳, components/TimelineRangeSummaryView.ts 3곳

해결 내용

  1. 실제로 쓰이는 심볼 2개를 WeakMap으로 교체
    • previewElementSymbol → WeakMap<Trace.Types.Events.Event, Element|null>
    • categoryBreakdownCacheSymbol(로컬) → WeakMap<Trace.Types.Events.Event[], Record<...>>
    • 두 번째는 심볼이 개별 이벤트가 아니라 events 배열에 붙어 있어 키도 배열
  2. 사용처가 없는 export 심볼 2개 제거 (aggregatedStatsKey, TimelineUIUtils의 categoryBreakdownCacheSymbol)
  3. const obj = (events as Object) 캐스팅도 함께 제거

같은 디렉터리의 TimelineFlameChartDataProvider.ts, utils/EntryNodes.ts가 쓰는 패턴을 따랐습니다. front_end 전체 117개 파일이 WeakMap을 사용 중입니다.

테스트 방법

  1. panels/timeline:timeline, panels/timeline/components:components 빌드
  2. 각 :unittests 타겟 빌드
  3. TimelineUIUtils.test.ts + TimelineRangeSummaryView.test.ts → 108/108 통과

배운 점

  • 캐시 교체 시 조회 의미를 보존해야 함
    • 기존 코드는 typeof === 'undefined'로 "아직 계산 안 함"과 "계산했는데 null"을 구분
    • 캐시 값이 Element|null이라 truthy 검사로 바꾸면 null 캐시를 매번 재계산
    • WeakMap.has()가 같은 구분을 제공
  • Symbol()은 호출마다 다른 값을 반환
    • 두 파일에 같은 이름으로 선언된 심볼이 실제로는 서로 다른 값이었음
    • 이름만 보고 같은 것으로 단정하면 안 됨
  • 제거 전 .ts 외에 .js, .html, web_tests까지 확인해 사용처 0건을 검증

참고 자료