> 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) 이것이 어떻게 작동할 수 있는지에 대해.

끊김을 피하는 측면에서 최상의 결과를 얻으려면, 엔티티의 shape의 `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\&token=6ba1a8ad-a1e4-472b-b9ca-a3b9d1aab9d8)

이 메뉴를 확장하여 세부 정보를 볼 수 있습니다.

![](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\&token=65973f60-8eda-4193-9a81-f5a42d4c5032)

다음은 이 지표들을 개선하는 몇 가지 팁입니다:

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

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

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

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

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

* **삼각형 수를 줄이기** Decimate 모디파이어를 사용하세요. 이미 가지고 있는 모델을 복구할 때 쓰는 도구입니다. 새 모델은 처음부터 로우폴리로 모델링하는 것이 더 좋습니다.
* **텍스처 크기 조정** 을 2의 거듭제곱 크기, 즉 1024x1024 이하로 맞추고, 이를 *.glb*.
* **플레이어가 절대 보지 못하는 면 삭제**, 예를 들어 소품의 아래쪽과 뒷면 같은 부분입니다. [백페이스 컬링](#backface-culling) 을 켜서 지오메트리를 두 겹으로 만드는 대신 사용하세요.
* **재질 병합** 을 한 개로, 부품마다 하나의 텍스처를 쓰는 대신 단일 아틀라스 텍스처를 사용하세요.
* **에서 조명, 카메라, 재질을 제거하세요 `_collider` 메시.** 엔진은 이를 무시하므로, 순수한 부담일 뿐입니다.

전후의 삼각형 수와 재질 수를 확인한 뒤, 같은 파일에 다시 내보내세요. 미리보기가 실행 중이라면, 변경 사항을 반영해 다시 로드됩니다.

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

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

```ts
// GOOD: 하나의 파일, 여러 엔티티
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) 많은 *서로 다른* 모델을 각각 고유한 세트와 함께 가지는 것입니다. 그래서 씬을 재사용되는 더 작은 모델 라이브러리를 중심으로 통합하면 그 점에서 도움이 됩니다.

### 백페이스 컬링

성능 최적화를 위해 Backface Culling은 **켜짐** 에서 **모든** 엔진에서 렌더링된 모델의 재질은 설정과 관계없이

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

#### 문제 해결

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

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

* 씬이 게시된 경우 `/debug` 명령을 채팅창에 입력하세요.
* 씬이 미리보기 모드인 경우, Bug 아이콘(

  <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&amp;token=42a33cd5-b516-43ea-a6b3-8c33c21e4359" 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\&token=e41f8a8a-1115-4a8b-b0e9-d4016a74da21)

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 %}

## 연결성

씬이 서드파티 서버에 연결하거나 [메시지버스](/creator/content-creator-ko/sdk7/networking/serverless-multiplayer.md#send-explicit-messagebus-messages) 를 사용해 플레이어 간에 메시지를 보낸다면, 염두에 두어야 할 사항이 몇 가지 더 있습니다.

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

## 씬 UI

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

{% hint style="info" %}
**💡 팁**: 여러 요소를 하나의 단일 이미지로 합치도록 하세요. 예를 들어 여러 텍스트 요소가 있는 메뉴가 있다면, 타일의 텍스트와 추가 이미지를 배경 이미지에 함께 굽는 것이 이상적입니다. 그러면 각 텍스트 요소마다 매 프레임 추가 드로우콜이 하나씩 발생하는 것을 엔진이 피할 수 있습니다.
{% endhint %}

매 프레임 UI를 조정하는 것은 피하세요. 이런 작업은 특히 비용이 크고 대기열에 쌓일 수도 있습니다. 예를 들어 UI에 일정 시간에 걸쳐 줄어들어야 하는 체력 바가 있다면, 플레이어는 아마 10 FPS로 업데이트되든 매 프레임 30 FPS로 업데이트되든 큰 차이를 느끼지 못할 것입니다. 이 바를 업데이트하는 시스템은 100밀리초를 세는 짧은 타이머를 사용할 수 있고, 이 타이머가 0이 될 때만 UI에 영향을 주면 됩니다.

숨겨진 UI 요소를 많이 두지 마세요. 렌더링되지 않더라도 성능에 영향을 줍니다. 가능하면 필요할 때 UI 구성 요소를 만드세요.

## 월드의 지형

에 게시된 씬은 [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 서버가 연결되면, 에이전트는 다음을 수행할 수 있습니다:

* **씬이 콘텐츠 예산을 준수하는지 확인하기**: 씬 통계 패널과 같은 실시간 통계를 읽고 이를 [씬 제한 사항](/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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
