디자인 시스템 도입률 측정: 컴포넌트 사용 추적과 KPI 설계

디자인

디자인 시스템메트릭컴포넌트 추적KPI거버넌스

이 글은 누구를 위한 것인가

  • 디자인 시스템 팀이 도입 현황을 정량화하려는 경우
  • 경영진에게 디자인 시스템 ROI를 보고해야 하는 팀
  • 미사용 컴포넌트를 식별해 리소스를 최적화하려는 팀

들어가며

"디자인 시스템이 잘 사용되고 있나요?" 이 질문에 데이터로 답하지 못하면 투자 지속성이 흔들린다. 컴포넌트 사용률, 커버리지 스코어, 팀별 도입 현황을 측정해야 한다.

이 글은 bluefoxdev.kr의 디자인 시스템 도입률 측정 가이드 를 참고하여 작성했습니다.


1. 측정 지표 설계

[핵심 KPI]

1. 컴포넌트 커버리지 스코어
   = 디자인 시스템 컴포넌트 사용 수 / 전체 UI 컴포넌트 수
   목표: 80% 이상

2. 도입 팀 비율
   = 디자인 시스템을 사용하는 팀 수 / 전체 팀 수
   목표: 90% 이상

3. 컴포넌트 별 사용 빈도
   많이 사용: 안정적으로 유지
   거의 미사용: 개선 또는 deprecation

4. 디자인-개발 일치율
   Figma 컴포넌트 사용 수 vs 코드 컴포넌트 사용 수
   불일치: 핸드오프 프로세스 개선 필요

[측정 방법]

정적 분석 (코드):
  AST 파싱으로 import 추적
  grep으로 컴포넌트명 사용 빈도 집계
  
런타임 추적:
  컴포넌트 렌더링 시 analytics 이벤트
  단, 프로덕션 성능 영향 주의

Figma API:
  파일별 컴포넌트 사용 인스턴스 수집

2. 컴포넌트 사용 추적 구현

// 정적 분석 스크립트: 코드베이스에서 DS 컴포넌트 사용 집계
import { Project } from 'ts-morph';
import * as path from 'path';

const DS_COMPONENTS = ['Button', 'Input', 'Modal', 'Card', 'Badge', 'Toast', 'Table', 'Dropdown'];
const DS_PACKAGE = '@company/design-system';

async function analyzeComponentUsage(rootDir: string) {
  const project = new Project({ tsConfigFilePath: path.join(rootDir, 'tsconfig.json') });
  const usage: Record<string, { count: number; files: string[] }> = {};

  DS_COMPONENTS.forEach(c => { usage[c] = { count: 0, files: [] }; });

  const files = project.getSourceFiles('**/*.tsx');

  for (const file of files) {
    const imports = file.getImportDeclarations();

    for (const imp of imports) {
      if (!imp.getModuleSpecifierValue().includes(DS_PACKAGE)) continue;

      const named = imp.getNamedImports().map(n => n.getName());
      for (const name of named) {
        if (usage[name]) {
          usage[name].count++;
          usage[name].files.push(file.getFilePath());
        }
      }
    }
  }

  // 전체 UI 컴포넌트 수 (*.tsx 파일 내 함수 컴포넌트)
  let totalComponents = 0;
  for (const file of files) {
    const funcs = file.getFunctions().filter(f => /^[A-Z]/.test(f.getName() ?? ''));
    totalComponents += funcs.length;
  }

  const dsComponentsUsed = Object.values(usage).filter(u => u.count > 0).length;
  const coverageScore = (dsComponentsUsed / totalComponents * 100).toFixed(1);

  return {
    usage,
    totalComponents,
    dsComponentsUsed,
    coverageScore: `${coverageScore}%`,
    unused: DS_COMPONENTS.filter(c => usage[c].count === 0),
  };
}

// 런타임 추적 (개발/스테이징 환경)
function withUsageTracking<T extends object>(ComponentName: string, Component: React.ComponentType<T>) {
  return function TrackedComponent(props: T) {
    useEffect(() => {
      if (process.env.NODE_ENV !== 'production') {
        analytics.track('ds_component_used', { component: ComponentName, page: window.location.pathname });
      }
    }, []);
    return <Component {...props} />;
  };
}

// 리포트 생성
async function generateAdoptionReport() {
  const analysis = await analyzeComponentUsage('./src');
  const report = {
    date: new Date().toISOString().split('T')[0],
    coverageScore: analysis.coverageScore,
    topUsed: Object.entries(analysis.usage).sort((a, b) => b[1].count - a[1].count).slice(0, 5),
    unused: analysis.unused,
    recommendation: analysis.unused.length > 3
      ? '미사용 컴포넌트를 검토하고 deprecation을 고려하세요'
      : '컴포넌트 사용률이 양호합니다',
  };
  return report;
}

import { useEffect } from 'react';
import React from 'react';
const analytics = { track: (event: string, data: any) => {} };

마무리

디자인 시스템 성과는 "커버리지 스코어"와 "미사용 컴포넌트 수"로 정량화된다. AST 기반 정적 분석으로 코드베이스 전체의 DS 컴포넌트 사용 현황을 자동 집계하고, CI 파이프라인에 포함시켜 PR마다 리포트를 생성하면 팀이 도입 현황을 실시간으로 파악할 수 있다.