> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-ko/sdk7/optimizing/performance-optimization.md).

# 성능 최적화

모든 플레이어에게 빠르게 로드되고 원활하게 실행되도록 씬을 최적화하세요.

방문하는 플레이어에게 가능한 최상의 경험을 보장하기 위해 씬에서 최적화할 수 있는 여러 측면이 있습니다. 이 문서에서는 씬의 로딩 속도와 해당 씬 또는 인접 씬에 있는 플레이어에게 씬이 얼마나 매끄럽게 실행되는지에 큰 차이를 만들 수 있는 몇 가지 모범 사례를 다룹니다.

많은 플레이어가 게임용으로 설계되지 않은 하드웨어로, 브라우저를 통해, 또는 그 [모바일 앱](/creator/content-creator-ko/build-for-mobile/mobile-client/overview.md) 휴대폰에서 Decentraland를 방문할 수 있다는 점을 기억하세요 — 이 모든 경우에 씬에서 사용할 수 있는 처리 능력이 제한됩니다. 씬을 방문하는 경험은 누구에게나 매끄러워야 합니다.

{% embed url="<https://www.youtube.com/watch?v=tc1PwYKW1Kc>" %}

확인해 보세요 [유용한 자료](/creator/content-creator-ko/sdk7/getting-started/useful-resources.md) 도움을 줄 수 있는 도구, 예를 들어 Decentraland Scene Optimizer를 확인해 보세요. 이 도구는 씬의 3D 모델에서 텍스처를 추출하고, 중복을 제거하고, 압축합니다.

{% hint style="info" %}
**📱 모바일**: 모바일 기기는 보통 가장 리소스 제약이 큰 클라이언트입니다. 씬이 모바일 플레이어를 대상으로 한다면 [모바일용 제작](/creator/content-creator-ko/build-for-mobile/mobile-client/overview.md) 도 모바일 전용 가이드를 참고하세요.
{% endhint %}

Decentraland 익스플로러는 엔진 수준에서 많은 최적화를 적용합니다. 이러한 최적화는 큰 차이를 만들지만, 브라우저에서 여러 사용자 생성 경험을 동시에 렌더링하는 일은 매우 큰 과제입니다. 원활하게 작동하도록 여러분의 도움이 필요합니다.

## 타이밍

### 비디오 재생

비디오 재생은 엔진이 처리해야 하는 작업 중 가장 비용이 큰 것 중 하나입니다. 씬에 비디오가 포함되어 있다면, 반드시 오직 *하나만* 의 VideoTexture가 한 번에 사용되도록 하세요. 성능에 큰 영향 없이 수십 개의 평면이 같은 VideoTexture를 공유할 수 있지만, 두 번째 VideoTexture를 추가하는 순간 프레임률에 미치는 영향이 매우 눈에 띄게 됩니다.

또한 보이지 않는 영역에서 비디오가 재생되지 않도록 해야 합니다. 예를 들어 실내에 스크린이 있다면 플레이어가 출입할 때를 기준으로 트리거 영역을 사용해 비디오를 켜고 끄세요.

{% hint style="info" %}
**💡 팁**: 몇몇 씬에서 사용한 요령은 서로 다른 평면에 다르게 매핑되는 여러 영역이 있는 하나의 비디오를 스트리밍하는 것입니다. 각 비디오 스크린은 [UV 매핑](/creator/content-creator-ko/sdk7/3d/materials.md#using-textures) 을 사용해 VideoTexture의 뚜렷한 일부만 표시합니다. 덕분에 여러 VideoTexture를 쓰는 비용 없이 별도의 비디오가 재생되는 것처럼 보이게 할 수 있습니다.
{% endhint %}

{% hint style="info" %}
**💡 팁**: 플레이어가 씬 바깥에 서 있을 때는 VideoTexture가 매 프레임 업데이트되지 않습니다. 이는 주변 씬에 대한 영향을 줄이는 데 도움이 됩니다. 그럼에도 비디오 재생은 플레이어가 [씬 안으로 들어갈 때만](/creator/content-creator-ko/sdk7/interactivity/event-listeners.md#player-enters-or-leaves-scene) .
{% endhint %}

### 지연 로딩

씬이 크거나 항상 보이지 않는 실내 영역이 있다면, 시작 시점부터 엔티티 전체 세트를 모두 로드하지 않도록 선택할 수 있습니다. 대신 플레이어가 씬의 다른 부분을 방문할 때마다 해당 영역의 콘텐츠를 로드하세요. 이렇게 하면 씬의 로딩 시간을 크게 줄일 수 있을 뿐 아니라, 엔진이 매 프레임 처리해야 하는 텍스처와 3D 콘텐츠의 양도 줄일 수 있습니다.

예를 들어 박물관의 본관은 시작부터 로드되지만, 각 층의 그림은 플레이어가 각 층을 방문할 때에만 로드될 수 있습니다.

참고 [이 예시 씬](https://github.com/decentraland-scenes/lazy-loading) 이 어떻게 작동할 수 있는지.

끊김을 피하는 측면에서 가장 좋은 결과를 얻으려면 엔티티의 도형의 `visible` 속성을 false로 바꿔 숨기세요. 이 방식에서는 엔티티를 만들 때 엔진에 추가하되, 모델을 단순히 보이지 않게만 합니다.

대안으로는 필요할 때까지 엔티티를 엔진에 추가하지 않는 방법도 있습니다. 엔티티가 처음 나타날 때 약간의 끊김이 생길 수 있고, 보이기까지 몇 초가 걸릴 수도 있습니다. 이 접근 방식의 장점은 다음을 우회하는 유효한 방법이라는 점입니다. [씬 제한 사항](/creator/content-creator-ko/sdk7/optimizing/scene-limitations.md). 씬 제한 수는 총 렌더링 가능 콘텐츠가 아니라, 특정 시점에 씬에서 렌더링되고 있는 콘텐츠를 기준으로 계산된다는 점을 기억하세요. 씬의 일부를 로드하고 언로드하면 이러한 제한을 우회할 수 있어야 합니다.

{% hint style="warning" %}
**📔 참고**: 보이지 않지만 엔진에 추가된 엔티티도 씬 제한 수에 포함됩니다.
{% endhint %}

또한 멀리 있거나 가려진 엔티티의 애니메이션을 켜거나 끌 수 있습니다. 예를 들어 아주 미세한 대기 애니메이션을 재생하는 NPC의 경우, 플레이어가 20미터 이내에 있을 때만 그 애니메이션을 재생하도록 할 수 있습니다. NPC 주변에 트리거 영역을 만들고 그에 따라 애니메이션을 켜거나 끄세요.

{% hint style="info" %}
**💡 팁**: 엔티티가 멀리 있고 충분히 작으면 엔진이 이를 컬링합니다. 이 컬링은 드로우콜 수준에서는 도움이 되지만, 엔티티를 엔진에서 제거하는 것이 항상 더 좋습니다. 또한 이 컬링은 다른 엔티티에 의한 가림을 고려하지 않으므로, 그다지 작지는 않지만 벽 뒤에 숨겨진 엔티티도 여전히 렌더링됩니다.
{% endhint %}

### 비동기 블록

의 블록 [비동기 코드](/creator/content-creator-ko/sdk7/programming-patterns/async-functions.md) 는 기다리는 동안 다른 모든 작업의 진행을 막지 않습니다. 씬은 계속 실행되고, 비동기 블록은 대기 중이던 응답이 도착하면 다시 시작됩니다. 씬은 단일 스레드에서 실행되므로 이것은 병렬 처리가 아니라, 외부 응답을 기다리는 동안 씬이 멈추는 것을 방지하는 것일 뿐이라는 점을 기억하세요.

다음과 같이 비동기 서비스의 응답에 의존하는 모든 프로세스는 `getPlayerData()` 또는 `getRealm()` 항상 비동기 블록에서 실행해야 합니다. 그렇지 않으면 응답을 기다리는 동안 씬의 나머지 로딩이 모두 막히기 때문입니다. 타사 서버를 호출하는 경우에도 마찬가지입니다.

비동기가 아닌 모든 작업이 끝나면 씬은 완전히 로드된 것으로 간주된다는 점에 유의하세요. 플레이어가 씬에 들어올 때 비동기 프로세스가 여전히 실행 중일 수도 있습니다. 비동기 프로세스가 엔티티를 로드하게 만들어 플레이어가 그 기하 구조 내부에 갇힐 수 있는 상황은 피하세요.

### 이벤트에 의존하기

씬의 로직이 [이벤트를 듣는 것](/creator/content-creator-ko/sdk7/interactivity/event-listeners.md) 에 가능한 한 많이 의존하도록 하세요. 매 프레임마다 검사를 실행하기보다는.

그 `update()` 함수의 데이터를 [시스템](/creator/content-creator-ko/sdk7/architecture/systems.md) 는 매 프레임, 이상적으로는 초당 30회 실행됩니다. 이벤트에 구독할 수 있다면 반복적인 검사는 피하세요.

예를 들어 플레이어의 착용 아이템을 계속 확인하는 대신 `onProfileChanged` 이벤트에 구독하고, 플레이어의 착용 아이템은 변경되었을 때만 확인할 수 있습니다.

시스템을 반드시 사용해야 한다면, 매 프레임마다 검사나 조정을 수행하지 않도록 하세요. update 함수의 일부로 타이머를 포함해 1초에 한 번만, 또는 상황에 맞는 간격마다만 검사를 실행할 수 있습니다.

## 3D 모델 최적화

3D 모델을 더 가볍게 최적화할 수 있는 여러 방법이 있습니다.

다음을 사용할 때 [크리에이터 허브](/creator/content-creator-ko/scene-editor/get-started/editor-installation.md), 씬의 3D 모델이 사용하는 리소스에 대한 통계를 볼 수 있고, 그것들이 다음의 [씬 제한 사항](/creator/content-creator-ko/sdk7/optimizing/scene-limitations.md).

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-88f68a93b0cfcb7f8c48270f31ba7137655ee2e1%2Ftriangle-limit1.png?alt=media)

이 메뉴를 펼치면 자세한 내용을 볼 수 있습니다.

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-aebaad725f1d9397552b2fb36a318eec91589b9c%2Ftriangle-limit2.png?alt=media)

다음은 이러한 지표를 개선하기 위한 몇 가지 팁입니다:

* 가능하다면 3D 모델 간에 텍스처를 공유하세요. 좋은 방법은 하나의 텍스처를 아틀라스 맵으로 사용해 씬의 모든 모델이 함께 공유하도록 하는 것입니다. 여러 개의 작은 텍스처보다 1024x1024 픽셀 크기의 큰 공유 텍스처 하나를 두는 편이 더 좋습니다.

  > 참고: 머티리얼의 알베도 텍스처와 노멀 맵 또는 발광 맵에 같은 이미지 파일을 사용하지 마세요. 동일하더라도 별도의 파일을 사용하세요. 같은 이미지 파일을 서로 다른 유형의 텍스처 속성에 할당하면 에셋 번들로 압축될 때 원치 않는 시각적 아티팩트가 생길 수 있습니다.
* *.glb* 은 압축 형식이므로 항상 *.gltf*보다 더 가볍습니다. 반면 *.gltf* 에서는 텍스처를 별도의 파일로 내보내기만 하면 텍스처 이미지를 쉽게 공유할 수 있습니다. 다음 [파이프라인](https://github.com/AnalyticalGraphicsInc/gltf-pipeline)을 사용하면 *.glb* 외부 텍스처 파일이 있는 모델을 사용할 수 있어 양쪽의 장점을 모두 취할 수 있습니다.
* 혼합 투명도 사용은 피하세요. 혼합 투명도는 렌더링 최적화의 상당수를 우회해야 합니다. 가능하다면 불투명 또는 알파 테스트된 지오메트리를 선호하세요.
* 스키닝된 메시 사용은 피하세요. 성능을 크게 떨어뜨릴 수 있습니다.

{% hint style="info" %}
**💡 팁**: 3D 모델 모범 사례에 대한 자세한 내용은 \[3D Modeling 섹션]\(/creator/3d-modeling/3d-models
{% endhint %}

### Blender에서 무거운 모델 구하기

통계가 특정 모델 하나를 가리킨다면, 코드로 우회하는 것보다 모델을 수정하는 편이 보통 더 빠릅니다. Blender나 비슷한 도구에서 가장 유용한 편집은 다음과 같습니다:

* **삼각형 수 줄이기** 를 Decimate 모디파이어로 수행하세요. 이것은 이미 가지고 있는 모델을 구제하는 도구입니다. 새 모델은 처음부터 로우폴리로 만드는 것이 더 좋습니다.
* **텍스처 크기 조정** 을 2의 거듭제곱 크기인 1024x1024 또는 그보다 작게 맞춘 뒤, 다시 *.glb*.
* **플레이어가 절대 보지 못하는 면 삭제**, 예를 들어 프롭의 아래쪽과 뒷면입니다. [백페이스 컬링](#backface-culling) 을 켜고, 지오메트리를 두 배로 늘리지 마세요.
* **머티리얼 병합** 을 하나로 합치고, 부품별 텍스처 하나씩 대신 단일 아틀라스 텍스처를 사용하세요.
* **에서 라이트, 카메라, 머티리얼을 제거하세요. `_collider` 메시.** 엔진은 이를 무시하므로 순수한 부담만 됩니다.

전후의 삼각형 수와 머티리얼 수를 확인한 다음, 같은 파일 위에 다시 내보내세요. 미리보기가 실행 중이면 변경사항으로 다시 로드됩니다.

### 같은 모델을 여러 번 재사용하기

씬에는 종종 반복되는 콘텐츠가 가득합니다: 거리의 가로등, 방의 의자, 공원의 나무들. 이를 만드는 가장 좋은 방법은 가장 단순한 방법입니다 — **각 복사본에 고유한 엔티티를 부여하고, 모두 같은&#x20;*****.glb*****&#x20;파일을 추가할 수 있습니다.**

```ts
// 좋음: 하나의 파일, 여러 엔티티
for (const position of lampPostPositions) {
  const lampPost = engine.addEntity()
  Transform.create(lampPost, { position })
  GltfContainer.create(lampPost, { src: 'assets/scene/lampPost.glb' })
}
```

엔진은 이러한 엔티티가 하나의 소스를 공유한다는 것을 인식합니다. 파일은 한 번만 다운로드되고, 한 번만 에셋 번들로 변환되며, 그 메시와 텍스처는 메모리에 한 번만 유지됩니다 — 스무 번째 가로등은 월드에서의 위치를 제외하면 거의 비용이 들지 않습니다. 이는 씬 간에도 작동합니다: 인접한 씬이 같은 파일을 사용하면 이미 메모리에 있습니다. 거의 동일한 파일 스무 개를 내보내는 대신 *.glb* 그러면 다운로드가 스무 번 발생하고 메모리에는 스무 개의 복사본이 생깁니다.

이것이 **줄이지 않는 것은 드로우콜입니다.** 가로등 스무 개는 스무 개의 객체를 그려야 한다는 뜻이며, 그것들이 스무 개의 엔티티에서 오든 하나의 *.glb* 안에 가로등 스무 개가 모델링되어 있든 마찬가지입니다. 이 수를 줄이는 유일한 방법은 모델링 도구에서 메시를 합치는 것이며, 이는 실제 트레이드오프입니다 — 다음을 참고하세요. [인스턴싱 vs 복제 vs 병합](/creator/content-creator-ko/3d/meshes.md#instancing-objects-vs-duplicating-objects) 언제 가치가 있는지.

몇 가지 관련 팁:

* **하나의 거대한 모델보다 클러스터로 묶으세요.** 흩어져 있는 프롭이 많다면 좋은 중간 지점은 하나의 *.glb* 당 그룹마다 — 거리 한 구역, 방 한 칸의 가구처럼 — 각 프롭마다 모델을 하나씩 두거나 씬 전체를 하나의 모델로 만들기보다 더 낫습니다. 객체 수는 줄이면서 각 클러스터를 충분히 작게 유지해 컬링이 여전히 유용하게 작동하도록 할 수 있습니다.
* **한 번에 많은 복사본을 생성하나요?** 먼저 [`AssetLoad` 컴포넌트](/creator/content-creator-ko/sdk7/optimizing/pre-load-resources.md)으로 모델을 미리 로드하세요. 그러면 각 복사본이 같은 다운로드를 기다리는 대신 이미 메모리에 있는 모델로부터 생성됩니다. 각 복사본을 만드는 데는 여전히 작업이 필요하므로, 큰 폭발적 생성은 어느 쪽이든 한 프레임을 소모할 수 있습니다 — 미리 로드는 파일을 기다리는 시간을 없애줄 뿐, 복사본 생성 비용을 없애주는 것은 아닙니다.
* **매우 큰 모델 하나는 여러 개의 작은 모델보다 엔진에 더 부담이 큽니다.** 엔진은 끊김을 피하기 위해 씬을 구성하는 작업을 여러 프레임에 나눠 처리하지만, 하나의 거대한 모델은 쪼갤 수 없습니다 — 그것은 한 프레임에 들어갑니다. 여러 개의 작은 조각은 매끄럽게 로드되지만, 하나의 거대한 덩어리는 눈에 띄는 끊김을 일으킬 가능성이 더 높습니다.
* **모델을 반복한다고 해서 새로운 텍스처나 지오메트리가 생기지는 않습니다.** 하나의 모델로 만든 가로등 스무 개는 새 세트를 추가하는 대신 그 모델의 메시와 텍스처를 공유합니다 — 스무 번째는 텍스처 메모리를 전혀 늘리지 않습니다. 예외는 머티리얼입니다. 엔진은 씬의 경계 클리핑을 적용하기 위해 렌더링된 객체마다 머티리얼 인스턴스를 생성하므로, 머티리얼 수는 사용하는 모델 수가 아니라 렌더링하는 객체 수를 따릅니다. 이러한 인스턴스는 동일한 텍스처와 셰이더 변형을 공유하므로 프레임 시간보다는 약간의 메모리만 사용합니다. 씬을 텍스처 [한도에](/creator/content-creator-ko/sdk7/optimizing/scene-limitations.md) 가깝게 만드는 것은 *서로 다른* 모델을 많이 가지는 것이며, 각 모델이 저마다 맞춤형 세트를 가지고 있을 때입니다 — 따라서 씬을 더 적은 재사용 모델 라이브러리로 통합하면 그 부분에서 도움이 됩니다.

### 백페이스 컬링

성능 최적화를 위해 백페이스 컬링은 **켜짐** 에서 **모든** 으로 설정됩니다. 모델의 머티리얼은 엔진에서 렌더링된 뒤에는 설정과 무관하게 그렇게 됩니다.

모델의 뒷면이나 내부를 보게 될 것으로 예상한다면, 면을 복제하고 노멀을 반전시키세요.

#### 문제 해결

씬에 머티리얼 백페이스 컬링 문제가 있는지 확인하려면 다음 단계를 따르세요:

1. 다음을 엽니다 `디버그` 패널을 씬에서.

* 씬이 게시되어 있다면 `/debug` 명령어를 채팅에 입력하세요.
* 씬의 프리뷰 모드에 있다면, 버그 아이콘(

  <img src="https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-92fe4dd70621a496d0da083ae9b5f9b2ef84d2dd%2Fdebug-icon.png?alt=media" alt="디버그 아이콘" width="32">

  )을 화면 오른쪽 상단에서 클릭하세요.

2. 디버그 패널이 화면 오른쪽 하단에 나타납니다.
3. 아래의 **현재 씬**, 클릭하세요 **백페이스 디버거** 버튼.

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-94f40725793fcbf697f6386ad6c6249ca681381c%2Fdebug-panel-backface-debugging.png?alt=media)

4. 토글 **백페이스 컬링 강제 적용**: 백페이스 컬링이 켜진 상태로 렌더링된 머티리얼을 보여줍니다. 이는 최적화가 실제 환경에서 적용될 때의 실제 렌더링입니다. 켜기/끄기를 전환해 수정이 필요한 머티리얼을 찾아보세요.
5. 다음을 토글하세요 **백페이스 디버거** 백페이스 컬링이 꺼진 머티리얼을 쉽게 찾을 수 있습니다. 다음 항목을 강조 표시합니다:

* **빨간색**: 백페이스 컬링이 **켜짐**.
* **초록색**: 백페이스 컬링이 적용된 머티리얼 **켜짐**.

<p align="center"><img src="https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-10a08003626ccbdfddd2c934ba820bee8f4c5233%2Fbackface-culling-off.png?alt=media" alt=""> <img src="https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-d6687fbcd37cba5a800269d6ff89eb3b20e828ea%2Fbackface-culling-on.png?alt=media" alt=""><br><em>백페이스 컬링 꺼짐(왼쪽) vs. 백페이스 컬링 켜짐(오른쪽) 머티리얼</em></p>

### 에셋 번들 변환

씬을 게시할 때마다 Decentraland 콘텐츠 서버는 그 안의 모든 *.gltf* 및 *.glb* 모델을 에셋 번들 형식으로 압축합니다. 이 형식은 *훨씬* 더 가벼워 씬의 로딩이 훨씬 빨라지고 실행이 더 매끄러워집니다. 변환은 각 배포 직후 시작됩니다. 보통 몇 초면 충분하지만, 매우 큰 씬이거나 서버가 바쁠 때는 더 오래 걸릴 수 있습니다. 플랫폼별로 변환이 별도로 실행되고 다른 씬 뒤에 대기열에 들어갈 수 있기 때문입니다. 다음을 할 수 있습니다 [변환 상태를 확인할 수 있습니다](/creator/content-creator-ko/scene-editor/publish/publish-scene.md#check-the-conversion-status) .

씬을 개발하는 동안에도 동일한 변환을 로컬에서 실행할 수 있습니다. 이렇게 하면 프리뷰가 더 매끄러워지고, 게시하기 전에 압축된 모델에 문제가 없는지 확인할 수 있습니다. 다음을 참고하세요. [최적화된 에셋으로 미리보기](/creator/content-creator-ko/sdk7/getting-started/preview-scene.md#preview-with-optimized-assets).

{% hint style="info" %}
**💡 팁**: Decentraland에서 이벤트를 계획할 때는 최소 한 시간 전에 최종 버전을 게시하세요. 그래야 그때까지 모든 모델이 에셋 번들로 변환되고 예상치 못한 문제를 수정할 시간이 생깁니다. 이벤트 전에 깜짝 요소를 미리 공개하고 싶지 않다면, 프로젝트 폴더에 최종 3D 모델을 모두 포함하되 보이지 않게 하거나 크기를 0으로 설정한 씬 버전을 배포할 수 있습니다.
{% endhint %}

{% hint style="warning" %}
**📔 참고**: 만약 *아무* 3D 모델 파일에
{% endhint %}

## 연결성

씬이 타사 서버에 연결하거나 [messagebus](/creator/content-creator-ko/sdk7/networking/serverless-multiplayer.md#send-explicit-messagebus-messages) 를 사용해 플레이어 간 메시지를 보낸다면, 기억해 둘 만한 몇 가지 사항이 있습니다.

* 씬은 한 번에 활성 WebSockets 연결을 하나만 가져야 합니다.
* HTTP 호출은 엔진이 한 번에 하나만 처리되도록 흘려보냅니다. 추가 요청은 내부적으로 대기열에 쌓이며 다른 요청이 완료될 때까지 기다려야 합니다. 이 대기열 처리는 자동으로 이루어지므로 따로 할 일은 없습니다.
* 다음을 사용할 때 [messagebus](/creator/content-creator-ko/sdk7/networking/serverless-multiplayer.md#send-explicit-messagebus-messages) 플레이어 간 메시지를 보내는 데 사용한다면, 서버 아일랜드의 다른 모든 플레이어에게 모든 메시지가 전송된다는 점을 염두에 두세요. 들어오는 메시지가 직접 다른 메시지 전송으로 이어지는 상황은 피하세요. 씬에 사람이 많을 때 메시지 수가 기하급수적으로 빠르게 늘어날 수 있습니다.

## 씬 UI

씬 UI는 여러 개의 개별 요소로 이루어져 있을 때 렌더링 비용이 커질 수 있습니다. 각 UI 요소마다 엔진에서 별도의 드로우콜이 필요하다는 점을 기억하세요.

{% hint style="info" %}
**💡 팁**: 여러 요소를 하나의 이미지로 합치세요. 예를 들어 여러 텍스트 요소가 있는 메뉴가 있다면, 타일의 텍스트와 추가 이미지를 배경 이미지에 합성해 두는 것이 이상적입니다. 이렇게 하면 각 텍스트 요소마다 매 프레임 엔진이 추가 드로우콜을 하나씩 수행하지 않아도 됩니다.
{% endhint %}

매 프레임 UI를 조정하는 일은 피하세요. 그런 작업은 특히 비용이 크고 결국 대기열에 쌓일 수 있습니다. 예를 들어 UI에 시간이 지남에 따라 줄어드는 체력 바가 있다면, 플레이어는 그것이 매 프레임 30 FPS로 업데이트되는 것보다 10 FPS로 업데이트될 때 차이를 거의 알아차리지 못할 것입니다. 이 바를 업데이트하는 시스템은 100밀리초를 세는 짧은 타이머를 사용할 수 있으며, 타이머가 0에 도달할 때만 UI에 영향을 주면 됩니다.

많은 숨겨진 UI 요소를 두는 것도 피하세요. 렌더링되지 않더라도 성능에 영향을 줍니다. 가능하다면 필요할 때 UI 구성 요소를 생성하세요.

## Worlds의 랜드스케이프 지형

다음에 배포된 씬은 [Decentraland World](https://github.com/decentraland/docs/tree/main/creator/worlds/about.md) 는 자동 생성된 초원, 나무, 바다 랜드스케이프로 둘러싸여 있습니다. 이 랜드스케이프를 렌더링하면 플레이어의 렌더링 예산 일부가 소모됩니다. 씬에 필요하지 않다면 [랜드스케이프 지형을 비활성화하고](/creator/content-creator-ko/sdk7/kinds-of-projects/scene-metadata.md#landscape-terrain) 당신의 `scene.json` 씬 자체 콘텐츠를 위해 그 리소스를 확보할 수 있습니다.

## 성능 모니터링

씬이 얼마나 잘 작동하는지 알 수 있는 가장 좋은 지표는 FPS(초당 프레임 수)입니다. 프리뷰에서는 디버그 패널에서 현재 씬 FPS를 확인할 수 있습니다. 항상 30 FPS 이상을 목표로 하세요.

배포된 씬에서는 채팅 창에 `/showfps` 를 입력해 이러한 지표를 보여주는 패널을 전환할 수 있습니다.

### 씬 통계 패널

데스크톱 클라이언트에서 프리뷰로 씬을 실행할 때, 씬 콘텐츠에 대한 실시간 통계를 보여주는 패널을 열 수 있습니다. 화면 오른쪽 상단의 콘솔 및 디버그 아이콘 옆에 있는 통계 아이콘을 클릭하세요.

<img src="https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-6b9e306d006a431474403f15b186791329c3dab4%2Fscene-stats-panel.png?alt=media" alt="씬 통계 패널" width="400">

이 패널은 씬의 삼각형, 엔티티, 바디, 텍스처를 각 한도와 비교해 계산하고, 각 예산의 몇 퍼센트를 사용 중인지 보여줍니다. 값이 한도의 80%에 도달하면 주황색으로 바뀝니다. 또한 머티리얼, 지오메트리, 콜라이더, 외부 비디오 또는 오디오의 단순 개수도 보여줍니다. 각 지표 옆의 정보 아이콘 위에 마우스를 올리면 무엇을 세는지, 그리고 왜 중요한지에 대한 설명을 볼 수 있습니다.

콘텐츠가 로드되고 언로드됨에 따라 숫자가 실시간으로 업데이트되므로, 다음과 같은 전략이 [지연 로딩](#lazy-loading) 엔진이 특정 시점에 실제로 처리하는 것에 어떤 영향을 주는지 확인하는 데 이 패널이 유용합니다. 각 한도에 대한 자세한 내용은 [씬 제한 사항](/creator/content-creator-ko/sdk7/optimizing/scene-limitations.md) 를 참고하세요. 이는 소프트 한도라는 점을 기억하세요: 하나를 초과해도 씬이 차단되지는 않지만, 플레이어의 성능을 저하시킬 수 있습니다.

### 씬과 엔진 간 메시지

씬 성능의 주요 병목 중 하나는 보통 씬 코드와 엔진 사이에서 메시지를 주고받는 일입니다.

씬을 프리뷰로 실행할 때 오른쪽 상단에 “Y = Toggle Panel”이라고 표시된다는 점에 유의하세요. 키보드에서 Y를 눌러 실시간으로 업데이트되는 유용한 정보가 담긴 패널을 여세요.

SDK와 엔진 사이의 메시지와 관련된 작업을 수행할 때 ‘Processed Messages’ 수가 증가하는 것을 보게 됩니다. ‘Pending on Queue’ 수를 주의 깊게 살펴야 하며, 항상 0이거나 0에 가까워야 합니다. 이는 이러한 메시지 중 몇 개가 처리되지 못하고 대기열로 밀려났는지를 알려줍니다. ‘Pending on Queue’ 수가 늘어나기 시작하면 위험 구간에 들어간 것이므로 씬에 더 많은 최적화를 해야 할지 생각해 보아야 합니다.

{% hint style="warning" %}
**📔 참고**: 사용하지 않을 때는 패널을 열어 두지 마세요. 성능에 부정적인 영향을 줍니다.
{% endhint %}

프리뷰에서 경험하는 성능이 프로덕션에서의 성능과 다를 수 있다는 점을 기억하세요:

* 주변 인접 씬이 부정적인 영향을 줄 수 있습니다
* 씬의 3D 모델이 에셋 번들로 압축되면 긍정적인 영향을 줄 수 있습니다
* 씬을 방문하는 일부 플레이어는 더 성능이 낮은 하드웨어에서 실행 중일 수 있습니다

항상 먼저 씬을 [Decentraland World](/creator/content-creator-ko/sdk7/publishing/publishing-options.md#decentraland-worlds) 로 배포해 더 철저한 테스트를 해보는 것이 좋은 습관입니다.

항상 플레이어에게 피드백을 요청하세요. 여러분이 씬을 어떻게 경험하는지가 다른 모든 사람에게도 같다고 당연하게 생각하지 마세요.

## AI로 최적화하기

AI 에이전트가 이 페이지에 설명된 측정과 수정 작업의 상당 부분을 대신 처리할 수 있습니다. Decentraland는 [AI 기술](/creator/content-creator-ko/sdk7/getting-started/vibe-coding.md#install-skills-for-any-ai-agent) 코딩 에이전트(예: Claude Code 또는 Cursor)에게 씬 최적화 방법을 가르치는 [MCP 서버](/creator/content-creator-ko/sdk7/getting-started/vibe-coding.md#let-the-ai-see-your-scene-in-world) 을 제공하며, 데스크톱 클라이언트에는

이 있어 에이전트가 실행 중인 씬을 직접 검사하고 측정할 수 있습니다. `optimize-scene` 및 `unity-explorer-mcp` 가 설치되고 MCP 서버가 연결되면, 에이전트는 다음을 할 수 있습니다:

* **씬이 콘텐츠 예산을 지키는지 확인**: Scene Stats 패널과 같은 실시간 통계를 읽고 [씬 제한 사항](/creator/content-creator-ko/sdk7/optimizing/scene-limitations.md)과 비교하여 어떤 예산이 빡빡해지고 있는지 알려줄 수 있습니다.
* **원인이 되는 에셋 찾기**: 특정 시점에서 보이는 것까지 포함해, 씬의 3D 모델 각각이 삼각형, 머티리얼, 드로우콜 측면에서 얼마나 기여하는지 순위를 매기므로, 어떤 모델부터 최적화해야 하는지 정확히 알 수 있습니다.
* **실제 프레임률 측정**: 씬의 원하는 지점에 플레이어를 배치하고, 순간적인 끊김까지 포함해 그곳에서 플레이어가 실제로 경험하는 FPS를 샘플링합니다.
* **자체 작업 검증**: 각 변경 후 다시 측정할 수 있으므로, 추측이 아니라 실제 수치에 기반해 권장 사항과 수정이 이루어집니다.

이렇게 최적화는 단순히 요청할 수 있는 작업이 됩니다:

> "씬이 한도 내에 있는지 확인하고, 스폰 지점 근처에서 프레임률을 떨어뜨리는 원인을 찾아 고치고, 수정 전후 수치를 보여줘."

### Blender MCP 서버와 결합하기

Decentraland 도구는 에이전트에게 어떤 모델이 가장 무거운지 알려주지만, 모델 자체를 편집하지는 않습니다. 더 나아가려면 다음과 결합해 볼 수 있습니다. [Blender MCP 서버](https://www.blender.org/lab/mcp-server/), 에이전트가 Blender의 편집 도구에 접근할 수 있게 해줍니다. 이를 통해 에이전트는 Blender에서 무거운 모델을 열어 삼각형 수를 줄이고, 머티리얼을 병합하거나, 텍스처를 줄인 다음, 결과를 다시 씬으로 `.glb` 파일로 내보내고, 그 상태에서 다시 월드 내 프레임률을 측정할 수 있습니다.

자동 메시 편집은 모델의 모양을 눈에 띄게 바꿀 수 있으므로, 항상 결과를 검토하고 원본 파일의 백업을 보관하세요.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.decentraland.org/creator/content-creator-ko/sdk7/optimizing/performance-optimization.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
