Framework entegrasyonları · Vue + Three
Kare Döngüsü & watchEffect: Reaktif Graf Vergisinden Kaçış
Reaktif harita kurulduktan sonra sahne
her karede nefes alır. Bu sayfa
requestAnimationFrame ile Vue reaktivite sınırını
anlatır: Vue 101 dersi değil · tik içinde bağımlılık grafiği
üretmemek.
Holodepth bu yaprağı Composition API sözlüğü veya
watch / watchEffect temeli olarak
yazmaz. R3F kare diplomasi
useFrame / useThree
yaprağındadır (Fiber store aboneliği). Angular Zone vergisi
Kare döngüsü & NgZone
yaprağındadır. Mount kökü
Mount & kök sözleşmesi
, reaktif harita
Reaktif şablon → Object3D
yapraklarındadır. Ms / jank SLA
Platform · FPS
yaprağındadır. Ağır reaktif kaçış
Reaktif kaçış & performans
yaprağında derinleşir. glTF bu kapının konusu değildir.
Sayfayı bitirdiğinizde şu cümleye inanın: «rAF metronomdur; her karede watchEffect grafiği vergi keser. Döngü reaktif kapı dışında yaşar. Object3D markRaw hattındadır. onDemand invalidate kökü uyandırır. Gizli sekme pause eder. onBeforeUnmount yalnızca stop eder; dispose bir sonraki kapıdadır.»
Bu sayfanın sınırı · komşu konularla ayrım
Bu sayfa Vue + Three'de kare / reaktivite diplomasisini anlatır:
- rAF metronom · bağımlılık grafiği yasağı
watchEffectkötüye kullanım · render vergisiuseLoopcomposable · TresuseRenderyüzeyi- always / onDemand · invalidate köprüsü
- Görünürlük pause ·
onBeforeUnmountstop silueti
Bilinçli olarak dışarıda bırakılan konular:
- R3F useFrame / store seçicileri → R3F · useFrame / useThree
- Angular NgZone / runOutsideAngular → Angular · Kare & NgZone
- Mount / canvas ref / DPR kökü → Mount & kök sözleşmesi
- markRaw / şablon haritası → Reaktif şablon → Object3D
- Loader / dispose derinliği → Yükleme & onBeforeUnmount
- Pointer / picking → Olay bağları & picking
- Vue reaktivite 101 · FPS ms SLA → Platform · glTF → format
Kısa ayrım: Bu sayfa «tik grafiği üretmesin» · R3F useFrame «Fiber kare aboneliği» · NgZone «CD patch vergisi» · Platform FPS «ms bütçesi».
useLoop: metronomun evi
Holodepth ürün varsayılanı: kare döngüsünü tek bir composable
(useLoop) içinde toplamak. Böylece rAF sahibi, pause
politikası ve onBeforeUnmount stop tek yerde mühürlenir.
Dağınık onMounted içi döngüler ikinci metronom riski taşır;
useLoop «tek sahip» sözleşmesidir.
useLoop callback'i reaktif kapı dışında çalışmalıdır: içinde
ref okumak grafiğe bağlar, her karede yeniden izleme
adayı üretir. Parametre olarak gelen delta ve
elapsed yeterlidir; kare içinde watchEffect
açmayın.
TresJS gibi kütüphaneler benzer yüzeyi useRender adıyla
sunar. Holodepth burada kütüphane API'sini kataloglamaz; yalnızca
«kare aboneliği composable'da yaşar» ilkesini mühürler. Kendi
useLoop'unuz veya Tres useRender aynı diplomatiktir:
ince callback, ağır iş yok.
watchEffect vergisi
Vue reaktivitesi güçlüdür; kare döngüsü için fazla güçlüdür.
watchEffect içinde her tikte okunan ref,
reactive veya computed bağımlılık kaydı
açar. 60 Hz vitrinde bu, saniyede 60 kez «graf güncelle, belki render
et» demektir. R3F'deki setState zehri ve Angular'daki Zone içi rAF
ile aynı aileden bir faturadır: yüksek frekanslı 3D iş, düşük
frekanslı UI çerçevesine sızmamalıdır.
Tipik hata: watchEffect(() => { mesh.rotation.y += 0.01 })
veya rAF callback içinde reaktif state okuyup yazmak. Doğru hat:
karede Object3D'yi doğrudan itmek; UI'ye yansıyacak değeri seyreltmek
(watch ile anlamlı değişimde, veya N karede bir).
Tik ucuz sandığınız watchEffect, ikinci bir render motoru çalıştırır.
rAF: her karede graf yok
requestAnimationFrame ekran ritmine yaslanır; Three
renderer.render çoğu üründe burada çağrılır. Holodepth
kuralı: rAF zinciri reaktif sistemle konuşmamalı,
yalnızca sahne grafını güncellemelidir. Mount yaprağında renderer
mühürlendi; burada metronomun Vue Proxy'sine değil Object3D'ye
bağlandığını doğrulayın.
Çift rAF (hem parent hem child composable) yarış üretir. Tek döngü
sahibi useLoop veya eşdeğeridir. Delta ölçümü karede bir kez yapılır;
aynı tikte ikinci clock.getDelta() tuzağına düşmeyin.
Platform FPS ms dilim teşhisi ayrı yapraktadır; siz yalnızca tik
politikasını mühürlersiniz.
İki saat: şablon ve kare
Vue şablon render'ı durum değişince (veya üst yeniden çizilince)
çalışır. Three karesi ise rAF metronomuna bağlıdır: sürekli
(always) veya talepte (onDemand).
Holodepth: bu iki saati aynı boruda karıştırmayın. Panel checkbox'ı
için ref güncellemesi; orbit, sallanma, trail için kare
callback'i.
Imperatif Three'de kendi animate döngünüzü yazarsınız.
Vue + Three'de döngüyü composable toplar; sizin işiniz o döngüye
reaktif olmayan iş eklemektir. Şablonu her kare yeniden
uzlaştırmak, R3F'de her kare JSX prop yazmaya benzer pahalıdır.
Tres useRender yüzeyi
TresJS, Vue şablonunda deklaratif Three bileşenleri sunarken kare
aboneliğini useRender ile verir. Holodepth burada Tres
kurulumu öğretmez; yalnızca yüzey eşlemesini not eder:
useRender((state) => { … }) R3F useFrame
kardeşidir, fakat Vue reaktivite kuralları geçerlidir: callback ince
kalmalı, içinde reaktif okuma yapılmamalıdır.
Kendi composable'ınız (useLoop) veya Tres
useRender seçimi ürün mimarisidir. İkisini aynı sahnede
ikinci metronom olarak çalıştırmayın. Kütüphane sürümünüzde pause /
priority semantiği değişebilir; sözleşmeyi «tek sahip, ince callback»
olarak yazın.
Object3D mutasyon hattı
Kare içinde mesh konumunu değiştirmenin yolu işaretlenmiş Object3D
referansıdır: önceki yaprakta markRaw ile Proxy'den
kaçınmış shallowRef veya template ref. Karede
root.value.rotation.y += speed * delta yazılır; bu,
şablon prop'unu her karede yeniden başlatmaz.
Reaktif haritada mühürlenen «tek kaynak» kuralı burada şöyle okunur:
sürekli değişen bir alanı hem :rotation-y bağlaması hem
kare callback'i ile itmek çift kapıdır. Ya deklaratif (seyrek) ya kare
(sık); ikisini aynı eksen için yarıştırmayın.
| İş | Konum | Not |
|---|---|---|
| renderer.render / mesh itiş | rAF callback (reaktif dışı) | Her kare |
| Seçim id → şablon | watch (seyrek) |
Anlamlı değişimde |
| Her kare HUD metni | Kaçının veya seyreltin | Render selı |
always, onDemand ve invalidate
Vitrin idle motion sürekli rAF ister (always profili).
Dashboard paneli verisi gelince tek kare (veya kısa burst) çizebilir:
onDemand politikası R3F frameloop="demand"
kardeşidir. Holodepth: boşta dönen loop pil yer; panelde always
varsayılanı sorgulanır.
onDemand iken dış event, prop seed veya resize sonrası tek kare
uyandırmak gerekir (invalidate benzeri bayrak veya
kontrollü requestAnimationFrame). Karışık profil: sürekli
idle motion isteyen çocuk + onDemand kök = uyumsuz sözleşme. Ya kökü
always yapın ya idle motion'u bırakın ya da kontrollü invalidate üretin.
Görünürlük, pause ve onBeforeUnmount stop
Gizli sekme (document.visibilityState === 'hidden') veya
bileşen görünürlük bayrağı: döngüyü duraklatın. Pil ve ısı için ürün
politikasıdır. useLoop içinde pauseWhenHidden veya eşdeğer
dinleyici tek yerde mühürlenir; her child'ın ayrı visibility listener'ı
ikinci politika riskidir.
Sekme geri döndüğünde unbounded delta için hız tavanı düşünün; uzun aralıktan sonra tek karede dev sıçrama animasyonu kırar. Bu, Platform FPS jank teşhisine köprüler; burada yalnızca pause / resume sözleşmesi yazılır.
Bileşen ömrü bittiğinde cancelAnimationFrame ile zinciri
kesin. Holodepth bu sayfada yalnızca stop siluetini
mühürler: metronom ömürle ölür. Geometry, material, texture dispose
derinliği
Yükleme & onBeforeUnmount
yaprağındadır; burada tekrar anlatılmaz.
Orphan rAF, orphan WebGL context'in ikizidir. useLoop
onBeforeUnmount içinde stop() çağırmalıdır;
aksi hâlde unmount sonrası tik atmaya devam eden callback, Proxy'siz
ama hayalet sahneye yazar.
Görünmez sekmede akan rAF, görünmez fatura keser.
Güvenli kare: simüle composable
Örnekler öğretim amaçlıdır; paket sürümünüzü doğrulayın. Mount'ta renderer/scene/camera hazır kabul edilir. Vue reaktivite temeli öğretilmez.
Simüle · useLoop: reaktif graf yok, pause ve stop mühürlü. Mutasyon markRaw Object3D üzerinden; her karede ref yazımı yok.
import { onBeforeUnmount, onMounted } from 'vue'
import * as THREE from 'three'
type LoopCallback = (delta: number, elapsed: number) => void
export function useLoop(render: () => void, onTick?: LoopCallback) {
let raf = 0
let running = false
const clock = new THREE.Clock()
const frame = () => {
if (!running) return
const delta = clock.getDelta()
const elapsed = clock.elapsedTime
onTick?.(delta, elapsed)
render()
raf = requestAnimationFrame(frame)
}
const pauseWhenHidden = () => {
if (document.hidden) {
running = false
cancelAnimationFrame(raf)
raf = 0
} else if (!running) {
running = true
clock.start()
raf = requestAnimationFrame(frame)
}
}
onMounted(() => {
running = true
clock.start()
document.addEventListener('visibilitychange', pauseWhenHidden)
raf = requestAnimationFrame(frame)
})
onBeforeUnmount(() => {
running = false
cancelAnimationFrame(raf)
document.removeEventListener('visibilitychange', pauseWhenHidden)
})
}
Simüle · onDemand tek kare uyandırma. Panel profili: sürekli loop yok; seed değişince bir kare.
import { watch, type Ref } from 'vue'
/** Panel: sürekli loop yok · invalidate benzeri tek kare */
export function useOnDemandRender(
seed: Ref<unknown>,
render: () => void,
): void {
watch(seed, () => {
requestAnimationFrame(() => {
render()
})
})
}
/**
* Veri seed değişince (Vue ref):
* useOnDemandRender(dataSeed, () => renderer.render(scene, camera))
* Her render turunda çağırmayın · yalnız anlamlı değişimde.
*/
Güvenlik: rAF callback içinde kullanıcı string'ini
eval etmeyin. Kare içinde reaktif okuma yapmayın; UI
güncellemesi seyrek watch ile ayrı kanalda kalsın.
Kare / reaktivite tuzakları
- watchEffect içi rAF: her kare graf güncellemesi.
- rAF içi ref okuma: sessiz bağımlılık kaydı.
- Proxy'li Scene: markRaw atlanmış mesh.
- Çift metronom: iki composable iki loop.
- Unmount'süz rAF: orphan tik.
- Boşta always: panelde pil yangını.
- Her move'da ref yazımı: picking selı (sonraki yaprak).
- useFrame / NgZone ezberi: Vue'da Fiber store veya Zone yok.
Üç kare profili
-
01 · Tik
Sürekli vitrin
- Loop
- useLoop always · pauseWhenHidden
- UI
- Seyrek watch
- Risk
- Gizli sekmede unutulmak
-
02 · Tik
onDemand panel
- Loop
- Tek kare invalidate
- Tetik
- Ref seed / resize
- Risk
- always unutmak
-
03 · Tik
Tres + composable hibrit
- 3D
- useRender ince callback
- UI
- Şablon seyrek · kare sık
- Risk
- İkinci metronom
Holodepth perspektifleri ve sonraki kapı
Kareyi ince tutun
useLoop callback'i bir mikro-işletmendir; uygulama çekirdeği değildir. Ağır iş kare dışına veya worker'a itilir.
Grafiği karede üretmeyin
Reaktivite güçlü araçtır; 60 Hz borusuna bağlamak pahalıdır. Object3D hattı Proxy dışındadır.
Ömürle öldürün
cancelAnimationFrame onBeforeUnmount'un parçasıdır; dispose ayrı kapıdadır.
Teşhis maddeleri
- rAF callback reaktif okuma yapıyor mu?
- watchEffect döngü içinde mi?
- Tek döngü sahibi kim?
- pauseWhenHidden / visibility var mı?
- onBeforeUnmount stop mühürlü mü?
- Panel always mı onDemand mı?
- UI güncellemeleri seyrek mi?
- useFrame, NgZone veya glTF bu sayfaya sızmış mı?
Holodepth içgörüsü
«Vue yavaşlatıyor» çoğu zaman Three değildir; kare içinde açılan reaktif graf ve şablon selidir. Önce metronomun evini okuyun, sonra tici yazın.
Sonraki kapı: yükleme & onBeforeUnmount
Tik canlıyken asıl yük çoğu zaman asenkron varlıktadır. Sonraki sayfa Yükleme & onBeforeUnmount loader ömrü ile dispose sahipliğini anlatır. Picking ve reaktif kaçış sonraki yapraklardadır.