성능 최적화 가이드
Unity WebGL로 만든 앱인토스 미니앱의 성능은 사용자 경험에 직접적인 영향을 줘요.
이 가이드는 미니앱의 속도와 안정성을 높이기 위한 성능 최적화 전략과 실용적인 가이드를 정리했어요.
1. 성능 최적화 개요
최적화 목표
🎯 성능 목표
├── 시작 시간: < 3초
├── 프레임레이트: 30+ FPS (모바일)
├── 메모리 사용량: < 200MB
├── 로딩 시간: < 5초 (추가 씬)
└── 배터리 효율: 네이티브 대비 90%최적화 우선순위
🔥 높은 우선순위 (즉시 개선 필요)
├── 시작 성능 - 사용자 첫인상 결정
├── 메모리 관리 - 크래시 방지
└── 모바일 성능 - 주요 타겟 플랫폼
⚡ 중간 우선순위 (점진적 개선)
├── 렌더링 성능 - 시각적 품질 개선
├── 네트워킹 - 안정성 향상
└── 리소스 최적화 - 용량 및 로딩 개선
낮은 우선순위 (여유 있을 때)
├── 고급 기능 최적화
├── Edge case 처리
└── 미세 조정2. 시작 성능 최적화
핵심 전략
로딩 최적화
c#
// 점진적 로딩 구현
public class ProgressiveLoader : MonoBehaviour
{
public async Task LoadGameProgressively()
{
// 1단계: 핵심 UI 로드
await LoadEssentialUI();
ShowGame(); // 사용자에게 빠르게 보여주기
// 2단계: 게임 로직 로드 (백그라운드)
_ = LoadGameLogicAsync();
// 3단계: 추가 리소스 로드 (지연)
_ = LoadAdditionalAssetsAsync();
}
}리소스 동적 로딩
3. 메모리 최적화
메모리 관리 전략
텍스처 최적화
c#
// 텍스처 메모리 절약
public class TextureOptimizer : MonoBehaviour
{
void OptimizeTextures()
{
// 플랫폼별 압축 설정
var importer = AssetImporter.GetAtPath(texturePath) as TextureImporter;
// 모바일 최적화
var mobileSettings = new TextureImporterPlatformSettings
{
name = "WebGL",
maxTextureSize = 1024, // 모바일에서는 작게
format = TextureImporterFormat.DXT5, // 압축 포맷
compressionQuality = 50 // 품질 vs 용량 균형
};
importer.SetPlatformTextureSettings(mobileSettings);
}
}메모리 누수 방지
c#
public class MemoryManager : MonoBehaviour
{
void OnDestroy()
{
// 이벤트 해제
EventBus.Unsubscribe(this);
// 텍스처 해제
if (texture != null)
{
DestroyImmediate(texture);
texture = null;
}
// 리소스 정리
Resources.UnloadUnusedAssets();
System.GC.Collect();
}
}4. 렌더링 성능 최적화
렌더링 최적화 문서
Unity WebGL 렌더링 성능 최적화EmscriptenGLX 렌더링 모드
Draw Call 최적화
c#
// 배칭 최적화
public class BatchingOptimizer : MonoBehaviour
{
void OptimizeDrawCalls()
{
// Static Batching 활용
StaticBatchingUtility.Combine(staticObjects);
// Dynamic Batching 설정
// Player Settings에서 활성화
// GPU Instancing 활용
Graphics.DrawMeshInstanced(mesh, 0, material, matrices);
}
}LOD 시스템
c#
public class LODManager : MonoBehaviour
{
public LOD[] lods;
void SetupLOD()
{
var lodGroup = gameObject.AddComponent<LODGroup>();
// 거리별 LOD 설정
lods[0] = new LOD(0.1f, highQualityRenderers); // 가까이
lods[1] = new LOD(0.02f, mediumQualityRenderers); // 중간
lods[2] = new LOD(0.005f, lowQualityRenderers); // 멀리
lodGroup.SetLODs(lods);
}
}5. 프로파일링 및 분석
성능 분석 도구
실시간 성능 모니터링
c#
public class PerformanceMonitor : MonoBehaviour
{
public Text fpsText;
public Text memoryText;
private float frameCount = 0;
private float dt = 0.0f;
private float fps = 0.0f;
private float updateRate = 4.0f; // 4번 업데이트/초
void Update()
{
frameCount++;
dt += Time.deltaTime;
if (dt > 1.0f / updateRate)
{
fps = frameCount / dt;
frameCount = 0;
dt -= 1.0f / updateRate;
// UI 업데이트
fpsText.text = $"FPS: {fps:0}";
memoryText.text = $"Memory: {System.GC.GetTotalMemory(false) / 1024 / 1024:0}MB";
// 경고 임계값 체크
if (fps < 20) Debug.LogWarning("Low FPS detected!");
}
}
}6. 플랫폼별 최적화
모바일 최적화
웹 브라우저 최적화
javascript
// JavaScript 최적화
class WebOptimizer {
static optimizeForBrowser() {
// 브라우저별 최적화
if (this.isChrome()) {
this.optimizeForChrome();
} else if (this.isSafari()) {
this.optimizeForSafari();
}
// 메모리 가비지 컬렉션 최적화
if (window.performance && window.performance.memory) {
this.monitorMemoryUsage();
}
}
static optimizeForChrome() {
// Chrome WebGL 최적화
Module.canvas.addEventListener('webglcontextlost', this.handleContextLost);
}
}7. 리소스 최적화
에셋 최적화
파일 크기 최적화
c#
// 빌드 후처리 최적화
public class BuildPostProcessor : IPostprocessBuildWithReport
{
public int callbackOrder => 1;
public void OnPostprocessBuild(BuildReport report)
{
string buildPath = report.summary.outputPath;
// 불필요한 파일 제거
RemoveUnnecessaryFiles(buildPath);
// 압축 최적화
OptimizeCompression(buildPath);
// 파일 크기 리포트
GenerateSizeReport(buildPath);
}
}8. 코드 최적화
스크립트 최적화
c#
public class CodeOptimization : MonoBehaviour
{
// 캐싱으로 성능 향상
private Transform cachedTransform;
private Camera cachedCamera;
void Awake()
{
// 자주 사용하는 컴포넌트 캐싱
cachedTransform = transform;
cachedCamera = Camera.main;
}
void Update()
{
// 프레임마다 실행되는 코드 최적화
// ❌ 나쁜 예
// transform.position = Vector3.Lerp(transform.position, target, Time.deltaTime);
// ✅ 좋은 예
cachedTransform.position = Vector3.Lerp(cachedTransform.position, target, Time.deltaTime);
}
}WASM 최적화
9. 네트워킹 성능
네트워크 최적화
c#
public class NetworkOptimizer : MonoBehaviour
{
// 연결 풀링
private Queue<UnityWebRequest> requestPool = new Queue<UnityWebRequest>();
public async Task<string> OptimizedHttpRequest(string url)
{
UnityWebRequest request;
// 재사용 가능한 요청 객체 사용
if (requestPool.Count > 0)
{
request = requestPool.Dequeue();
request.url = url;
}
else
{
request = UnityWebRequest.Get(url);
}
try
{
await request.SendWebRequest();
return request.downloadHandler.text;
}
finally
{
// 풀에 반환
if (requestPool.Count < 10) // 풀 크기 제한
{
requestPool.Enqueue(request);
}
else
{
request.Dispose();
}
}
}
}10. 최적화 체크리스트
개발 단계별 체크리스트
초기 개발 (프로토타입)
- unity 권장 버전 사용
- 기본 성능 측정 기준점 설정
- 주요 리소스 크기 제한 설정
중간 개발 (알파/베타)
- Profiler로 병목 지점 파악
- 메모리 사용량 모니터링
- 모바일 테스트 시작
- 기본 최적화 적용
출시 준비 (RC)
- 모든 최적화 기법 적용
- 다양한 기기에서 성능 테스트
- 성능 벤치마크 달성 확인
- 사용자 테스트 피드백 반영
성능 기준표
| 항목 | 최소 요구사항 | 권장 | 우수 |
|---|---|---|---|
| 시작 시간 | < 5초 | < 3초 | < 2초 |
| 평균 FPS | 20+ | 30+ | 50+ |
| 메모리 사용량 | < 300MB | < 200MB | < 150MB |
| 첫 프레임 | < 10초 | < 5초 | < 3초 |
| 배터리 사용 | 네이티브 대비 120% | 110% | 100% |
