holodepth

Framework entegrasyonları · React Three Fiber

Yükleme & Suspense Köprüsü: Asenkron Kargo Diplomasisi

Canlı kare ağacı kurduktan sonra asıl risk çoğu zaman henüz gelmemiş varlıktır. Bu sayfa R3F'de useLoader, Suspense askısı ve dispose sahipliğini anlatır: React Suspense temeli değil · Three ↔ React asenkron köprüsü.

Holodepth bu yaprağı «Suspense nedir?» dersi veya glTF JSON şema turu olarak yazmaz. React askı modeli React Vitae omurgasındadır. Dosya alanları, bufferView, PBR slot spekü format izleklerindedir. Sıkıştırma / LOD kalitesi Platform · Asset sıkıştırma & LOD yaprağındadır. Canvas kökü, deklaratif katalog ve useFrame önceki R3F yapraklarındadır.

Sayfayı bitirdiğinizde şu cümleyi kurabilmelisiniz: «useLoader URL + loader sınıfı kimliğidir. Suspense eksik kargoda ağacı askıya alır. Cache paylaşımı clone politikası ister. Dispose sahiplik sözleşmesidir. Hatalar sınır bileşenine düşer. Ağır decode kareye gömülmez. Sonraki kapı pointer & picking'tir.»

Bu sayfanın sınırı · komşu konularla ayrım

Bu sayfa R3F'de asenkron varlık köprüsünü anlatır:

  • useLoader kimliği · Suspense askı semantiği
  • Cache / clone · fallback UX
  • Hata yolu · dispose sahipliği
  • Decode'u kareye gömmeme · üç yükleme profili

Bilinçli olarak dışarıda bırakılan konular:

Kısa ayrım: Bu sayfa «kargo nasıl askıya alınıp sahiplenilir?» · Format «paket içinde ne var?» · Platform asset «boyut / LOD kalitesi» · useFrame «geldikten sonra karede kim iter?».

Asenkron kargo · senkron ağaç

Deklaratif mesh anında vardır; doku, buffer geometri veya model ise ağdan / diskten gelir. R3F köprüsü bu gecikmeyi React ağacının askı diline çevirir: çocuk hazır değilse üst sınır fallback gösterir, hazır olunca katalog düğümü yerleşir.

Imperatif Three'de çoğunlukla callback / Promise ile scene.add edersiniz. R3F'de aynı işi «bileşen render yolunda askıya düşen yük» olarak yazarsınız. Holodepth: API farkı evrim değil; sahiplik ve hata yolunun nerede yazıldığı farkıdır.

Ağaç senkron görünür; kargo asenkron gelir. Köprü ikisini yalanlamadan birleştirir.

useLoader: kimlik sözleşmesi

useLoader(LoaderClass, url) (ve çoklu URL varyantları) yüklemeyi Fiber cache'ine bağlar. Holodepth kimlik kuralı: aynı loader sınıfı + aynı URL = paylaşılan cache kaydı adayıdır. URL'yi her render'da yeniden üretilmiş query ile rastgeleleştirmek cache'i deler; bilinçli busting ise ürün kararıdır.

Loader sınıfı TextureLoader, AudioLoader veya model loader olabilir. Bu sayfa glTF alan listesini açmaz: model loader'ı «bir loader örneği» olarak kullanırız. Paket şeması, skin, animasyon sampler'ı format omurgasındadır.

extensions / DRACOLoader bağlama gibi kurulumlar Three asset borusuna aittir; R3F tarafında merak ettiğiniz soru: kurulum bir kez mi, her bileşende mi? Holodepth: loader eklentilerini uygulama ömründe tek yerde mühürleyin, çocuklara çoğaltmayın.

Suspense: trafik ışığı

Suspense temelini Vitae anlatır. R3F köprüsünde semantik şudur: yükleyici henüz çözülmediyse alt ağaç «hazır değil» sinyalidir; en yakın Suspense sınırı fallback gösterir. Holodepth ürün dilinde fallback boş siyah kutu olmamalı: iskelet, düşük müsat / proxy mesh veya DOM spinner (host'ta) bilinçli seçilir.

Sınır nerede? Tüm Canvas'ı tek Suspense'e sarmak kaba ama basit; her ürün parçasına ayrı sınır koymak progressive reveal verir, fakat layout zıplaması üretebilir. Profil seçin (§10).

Askı sırasında useFrame abonelikleri o alt ağaçta yoktur (ağaç yoksa). Demand kökte ise yük bitince invalidate gerekebilir; kare sayfasındaki köprüyü burada hatırlatırız, yeniden öğretmeyiz.

Cache, clone, paylaşım

Cache iyidir: aynı dokuyu iki kez indirmezsiniz. Tehlike: paylaşılan Object3D / Material örneğini iki yerde dönüştürüp birbirini ezmek. Holodepth: okuma paylaşılır, yazma çoğaltılır. Sahneye birden fazla instance koyacaksanız clone (veya instancing; derin kaçış sonraki performansta) politikasını yazın.

Paylaşım diplomasi · kısa
Durum Tercih Risk
Aynı doku, iki mesh Materyal/doku paylaşımı OK Birinde dispose ötekini kırar
Aynı model, iki poz Scene clone / instancing Tek kökü iki parent'a bağlamak
Geçici preview Ayrı URL veya bilerek bust Cache kirlenmesi

«Clone her şey» bellek yer; «hiç clone yok» mantık yer. Ürün cümlesi tek satır olmalı: kim sahipse o dispose eder.

Dispose: sahiplik mührü

Unmount'ta GPU kaynakları (geometri, materyal, doku, render target) salınmazsa sekme şişer. R3F birçok intrinsikte yardımcı olur; paylaşılmış cache ve primitive misafirlerinde sahiplik sizin sözleşmenizdir. Deklaratif sayfadaki GuestObject örneği eşiği gösterdi; burada kuralı mühürleriz.

Holodepth üç sahiplik modeli:

  1. Bileşen özel: yükleyen unmount'ta dispose eder.
  2. Cache ortak: dispose etme; uygulama kapanışında / bilinçli purge.
  3. Misafir: çağıran verir, çağıran alır (primitive).

Yanlış model: ortak dokuyu ilk unmount'ta dispose edip ikinci mesh'i siyah bırakmak. Doğru model: ticket'a sahiplik cümlesi yazmak.

Hata yolu: sınır ve sessizlik

404, CORS, bozuk buffer veya desteklenmeyen sıkıştırma «sessiz siyah sahne» üretebilir. React Error Boundary (Vitae'de anlatılan sınır modeli) R3F alt ağacını yakalamak için ürün standardıdır. Holodepth: yükleme sınırında kullanıcıya okunur mesaj + yeniden deneme; konsola yalnız bırakılan reject kabul edilmez.

Güvenlik: kullanıcıdan gelen URL'yi doğrulamadan loader'a vermeyin (open redirect / beklenmeyen origin). crossOrigin ve CORS politikası host ile CDN sözleşmesidir; şema teorisi değil, köprü kırılmasıdır.

Decode'u kareye gömmeyin

useFrame içinde fetch + parse + texture upload yapmak jank üreticisidir. Platform FPS bunu dilim teşhisi olarak işler; burada R3F kuralı net: yükleme askı yolunda, hareket kare yolunda. İlk yerleşimde spike kaçınılmaz olabilir; spike politikasını ürün SLA'sına yazın, sürekli kareye yaymayın.

Progressive: önce düşük çözünürlük proxy, sonra yükseltme. Bu LOD / asset kalitesi sayfasına köprüler; R3F tarafında iki Suspense dalgası veya iki URL kimliği olarak görünür.

Askı pahalı görünebilir; kareye gömülü decode daha pahalıdır.

Güvenli yük: simüle köprü

Örnekler öğretim amaçlıdır; sürüm API'sini doğrulayın. Suspense / Boundary React temeli Vitae'dedir. Model alan spekü yok; TextureLoader ile köprü kalıbı gösterilir. Sabit, bilinen asset yolu kullanın.

Simüle · doku yükü + Suspense sınırı. URL sabit; kullanıcı girdisi yok.

import { Suspense } from 'react'
import { useLoader } from '@react-three/fiber'
import { TextureLoader } from 'three'

// Sabit, bilinen yol · kullanıcı string'i bağlamayın.
const PANEL_MAP = '/assets/demo/panel-albedo.jpg'

function TexturedPanel() {
  const map = useLoader(TextureLoader, PANEL_MAP)
  // Eğitim notu: colorSpace / flipY ürün sabitine göre mühürlenir (Canvas imzası ile uyumlu).
  map.colorSpace = 'srgb'

  return (
    <mesh>
      <planeGeometry args={[2, 1.25]} />
      <meshStandardMaterial map={map} roughness={0.55} metalness={0.05} />
    </mesh>
  )
}

export function TexturedPanelGate() {
  return (
    <Suspense fallback={null /* veya proxy mesh / DOM spinner */}>
      <TexturedPanel />
    </Suspense>
  )
}

Simüle · sahiplik notlu misafir. Paylaşılan sahne kökünde dispose'u çocuk değil çağıran yapar.

import { useEffect } from 'react'

/** @typedef {'component' | 'cache' | 'caller'} Ownership */

/**
 * object: dışarıda üretilmiş THREE.Object3D
 * ownership:
 *   - component → unmount'ta traverse dispose
 *   - cache     → dispose yok (paylaşılan kayıt)
 *   - caller    → dispose çağıranın işi
 */
export function OwnedGuest({ object, ownership = 'caller' }) {
  useEffect(() => {
    return () => {
      if (ownership !== 'component' || !object) return
      object.traverse((child) => {
        child.geometry?.dispose?.()
        const mats = child.material
        if (Array.isArray(mats)) mats.forEach((m) => m.dispose?.())
        else mats?.dispose?.()
      })
    }
  }, [object, ownership])

  if (!object) return null
  return <primitive object={object} />
}

Güvenlik özeti: sabit allowlist yolları; origin kontrolü; hata sınırında sızdıran stack'i kullanıcıya ham basmayın; bozuk dosyayı «başarılı yük» sanmayın.

Yükleme tuzakları

  1. Suspense'siz useLoader: askı yakalanmaz · kırılgan ağaç.
  2. URL kimliği kayması: her render yeni string · cache delinir.
  3. Ortak örneği dispose: komşu mesh ölür.
  4. Tek köke çift parent: clone unutulmuş model.
  5. Kare içi fetch: jank garantisi.
  6. Sessiz CORS: fallback yok · «Three bozuk» sanısı.
  7. Şema ezberi burada: glTF spekü bu sayfaya sızmasın.

Üç yükleme profili

  • 01 · Yük

    Tek vitrin kahramanı

    Sınır
    Canvas altı tek Suspense
    Fallback
    Proxy / iskelet kabul
    Risk
    Uzun tek spike · SLA'ya yaz
  • 02 · Yük

    Parça parça reveal

    Sınır
    Parça başına Suspense
    Cache
    Paylaş · clone bilinçli
    Risk
    Layout zıplaması
  • 03 · Yük

    Paylaşılan kütüphane

    Sahiplik
    cache / caller modeli
    Dispose
    İlk unmount'ta kesme
    Risk
    Ömür boyu şişen cache

Fallback UX ve host

Fallback null ise kullanıcı boşluk görür. Holodepth: ya düşük maliyetli proxy mesh (Canvas içi) ya host DOM'da ilerleme. İkisini birden yarıştırmayın. Erişilebilirlik: yük durumu metinsel de duyurulabilsin; yalnız animasyonlu spinner yetmez.

Prefetch (rota öncesi) ürün kararıdır; R3F cache'ini ısıtmak useLoader'ı gizli bir mount ile de yapılabilir. Bunu «sihir» sanmayın: yine aynı kimlik, aynı sahiplik.

Holodepth perspektifleri

Kimliği sabitleyin

Loader + URL ürün anahtarıdır. Rastgele string cache'i ve teşhisi bozar.

Sahiplik cümlesi yazın

Dispose tartışması teknik değil sözleşmeseldir. Ticket'a bir satır.

Askı ve kare ayrı şerit

Yük askıda biter; hareket karede akar. İkisini aynı callback'te ezmeyin.

Teşhis maddeleri

  1. useLoader Suspense sınırı altında mı?
  2. URL sabit / allowlist mi?
  3. Cache paylaşımı clone ile çelişiyor mu?
  4. Sahiplik modeli (component / cache / caller) yazılı mı?
  5. Error boundary var mı, sessiz mi?
  6. Decode useFrame'e mi kaçmış?
  7. Fallback bilinçli mi?
  8. glTF şema veya React Suspense 101 bu sayfaya sızmış mı?

Holodepth içgörüsü

«Model gelmedi» çoğu zaman loader bug'ı değil; kimlik, CORS, sahiplik veya sınır eksikliğidir. Önce kargonun pasaportuna bakın, sonra paket speküne inmeyin.

Sonraki kapı: pointer & picking

Kargo yerleştiğinde kullanıcı dokunur / tıklar. Sonraki sayfa Pointer olayları & picking R3F event yüzeyini raycast teorisinden ayırarak anlatır. Imperatif kaçış son yapraktadır.