holodepth

Framework entegrasyonları · Angular + Three

Kare Döngüsü & NgZone: Tik ile Vergi Diplomasisi

Host ve harita kurulduktan sonra sahne her karede nefes alır. Bu sayfa requestAnimationFrame ile NgZone vergisini anlatır: Angular zone 101 dersi değil · Three tikinin Zone'a batmaması.

Holodepth bu yaprağı RxJS veya change detection temeli olarak yazmaz. R3F kare diplomasi useFrame / useThree yaprağındadır (Fiber store). Host açılışı Host & kök , harita Şablon → Object3D yapraklarındadır. Ms / jank SLA Platform · FPS yaprağındadır. Ağır Zone kaçışı / ada Zone kaçışı & performans yaprağında derinleşir. glTF bu kapının konusu değildir.

Sayfayı bitirdiğinizde şu cümleye inanın: «rAF metronomdur; NgZone patch'i vergi olabilir. Render döngüsü çoğu üründe runOutsideAngular içindedir. UI güncellemesi seyrek Zone'a döner. Her kare detectChanges zehirdir. Destroy görünürlük ile döngüyü keser. Sonraki kapı yükleme & OnDestroy'dır.»

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

Bu sayfa Angular + Three'de kare / NgZone diplomasisini anlatır:

  • Zone vergisi · rAF metronom
  • runOutsideAngular döngü
  • Seyrek UI dönüşü · detectChanges zehri
  • Pause / destroy · üç kare profili

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

Kısa ayrım: Bu sayfa «tik Zone'a batmasın» · R3F useFrame «Fiber kare aboneliği» · Zone kaçışı «uzun vadeli ada / vergi eşiği» · Platform FPS «ms bütçesi».

Zone vergisi

NgZone, async işleri Angular'ın haber alacağı şekilde yamar. rAF, timer ve bazı DOM olayları Zone içindeyse her kare change detection adayı üretebilir. Holodepth: 60 Hz render döngüsünü Zone'un «her şey oldu» hattına bağlamak, görünmez ikinci motor çalıştırmaktır.

R3F'de setState zehri vardı; Angular'da kuzeni her kare Zone + CD selidir. Teşhis aynı aileden: yüksek frekanslı iş, düşük frekanslı UI çerçevesinden ayrılmalı.

Tik ucuz sandığınız Zone patch'i, CD faturası keser.

rAF metronom

requestAnimationFrame ekran ritmine yaslanır; Three render'ı genelde burada çağrılır. Host yaprağında renderer mühürlendi; burada metronom sahibi host (veya scene service) olur. Çift rAF (hem servis hem child) yarış üretir; tek döngü varsayılandır.

Delta / elapsed: THREE.Clock veya kendi zamanınız. Aynı karede çift getDelta tuzağı Three zaman omurgasındadır; loop'ta bir kez ölçün. Platform FPS ms dilimini, siz yalnızca tik politikasını mühürlersiniz.

runOutsideAngular: döngü evi

Holodepth ürün varsayılanı: render / animasyon rAF zinciri NgZone.runOutsideAngular içinde başlar ve sürer. Böylece her kare Angular'ı uyandırmaz. Mesh mutasyonu Object3D üzerinde kalır; şablon ağacı her tikte yeniden doğmaz.

Zone dışı, «Angular öldü» demek değildir. UI'ye yansıyacak seyrek olay (seçim id, yükleme bitişi) bilinçli NgZone.run ile içeri alınır.

Ne zaman Zone'a dönülür?

Frekans diplomatisi
İş Konum Not
renderer.render / mesh itiş Zone dışı Her kare
Seçim id → şablon Zone içi (seyrek) run / markForCheck
Her kare HUD sayısı Kaçının veya seyreltin CD selı

Pointer picking sonuçlarını bir sonraki Angular yaprak bağlar; burada kural: isabet sonucu state'e yazılacaksa Zone'a kontrollü dönün, her pointermove'da değil.

detectChanges zehri

Döngü içinde ChangeDetectorRef.detectChanges() veya sınırsız markForCheck yağmuru, Zone dışına çıkmış olsanız bile UI ağacını her kare sarsabilir. Holodepth: 3D hareket ref/Object3D'de; Angular state seyrek. OnPush disiplini Vue/Angular temeline aittir; köprü cümlesi «her kare CD yok»tur.

Pause, görünürlük, destroy

Gizli sekme veya ngOnDestroy: cancelAnimationFrame ile zinciri kesin. Aksi hâlde ölü bileşen tik atmaya devam eder. document.visibilityState ile pause ürün politikasıdır (pil). Dispose derinliği OnDestroy yaprağındadır; burada mühür: metronom ömürle ölür.

Orphan rAF, orphan context'in ikizidir.

Sürekli vs talepte çizim

Vitrin idle motion sürekli rAF ister. Dashboard paneli verisi gelince tek kare (veya kısa burst) çizebilir: «demand» politikası R3F frameloop'una kardeş, Angular'da sizin bayrağınızdır (needsRender). Holodepth: boşta dönen loop pil yer; panelde always varsayılanı sorgulanır.

Güvenli tik: simüle döngü

Örnekler öğretim amaçlıdır. Host'ta renderer/scene/camera hazır kabul edilir. Angular zone temeli öğretilmez.

Simüle · Zone dışı rAF döngüsü.

import { Injectable, NgZone, OnDestroy } from '@angular/core'
import * as THREE from 'three'

@Injectable()
export class FrameLoopService implements OnDestroy {
  private raf = 0
  private running = false
  private readonly clock = new THREE.Clock()

  constructor(private readonly zone: NgZone) {}

  /**
   * Döngüyü Zone dışında başlat.
   * onTick: delta saniye · Object3D mutasyonu burada (CD yok).
   */
  start(
    render: () => void,
    onTick?: (delta: number, elapsed: number) => void,
  ): void {
    if (this.running) return
    this.running = true
    this.clock.start()

    this.zone.runOutsideAngular(() => {
      const frame = () => {
        if (!this.running) return
        const delta = this.clock.getDelta()
        const elapsed = this.clock.elapsedTime
        onTick?.(delta, elapsed)
        render()
        this.raf = requestAnimationFrame(frame)
      }
      this.raf = requestAnimationFrame(frame)
    })
  }

  /** Seyrek UI: Zone içine kontrollü dönüş */
  runInAngular(fn: () => void): void {
    this.zone.run(fn)
  }

  stop(): void {
    this.running = false
    cancelAnimationFrame(this.raf)
    this.raf = 0
  }

  ngOnDestroy(): void {
    this.stop()
  }
}

Simüle · demand bayrağı (panel). Boşta rAF yok; işaret gelince bir kare.

import { NgZone } from '@angular/core'

/** Panel: sürekli loop yok · invalidate benzeri tek kare */
export function requestRender(
  zone: NgZone,
  render: () => void,
): void {
  zone.runOutsideAngular(() => {
    requestAnimationFrame(() => {
      render()
    })
  })
}

/**
 * Veri seed değişince (Angular state):
 *   this.requestRender(this.zone, () => this.renderer.render(scene, camera))
 * Her CD turunda çağırmayın · yalnız anlamlı değişimde.
 */

Güvenlik: rAF callback içinde kullanıcı string'ini eval etmeyin. Sekme geri dönüşünde unbounded delta için hız tavanı düşünün (Zone kaçışı / ürün politikası).

Kare / Zone tuzakları

  1. Zone içi rAF: her kare CD adayı.
  2. detectChanges yağmuru: Outside yetmez.
  3. Çift metronom: iki servis iki loop.
  4. Destroy'süz rAF: orphan tik.
  5. Boşta always: panelde pil yangını.
  6. Her move'da zone.run: picking selı.
  7. useFrame ezberi: Angular'da Fiber store yok.

Üç kare profili

  • 01 · Tik

    Sürekli vitrin

    Loop
    OutsideAngular always
    UI
    Seyrek zone.run
    Risk
    Gizli sekmede unutulmak
  • 02 · Tik

    Demand panel

    Loop
    Tek kare invalidate
    Tetik
    Veri seed / resize
    Risk
    Always unutmak
  • 03 · Tik

    Hibrit HUD

    3D
    Outside mutasyon
    HUD
    N karede bir veya eşik
    Risk
    Her kare metin bind

Holodepth perspektifleri

Döngüyü dışarı alın

Varsayılan ev: runOutsideAngular. İçeriye yalnız seyrek UI.

Tek metronom

İkinci rAF zinciri ikinci gerekçe ister.

Ömürle öldürün

cancelAnimationFrame destroy'un parçasıdır.

Teşhis maddeleri

  1. rAF Zone dışında mı?
  2. Her kare detectChanges / markForCheck var mı?
  3. Tek döngü sahibi kim?
  4. Destroy / visibility pause var mı?
  5. Panel always mı demand mı?
  6. UI dönüşleri seyrek mi?
  7. Delta bir kez mi ölçülüyor?
  8. R3F useFrame veya glTF bu sayfaya sızmış mı?

Holodepth içgörüsü

«Angular yavaşlatıyor» çoğu zaman Three değildir; Zone içi tik + CD selidir. Önce metronomun evini okuyun.

Sonraki kapı: yükleme & OnDestroy

Tik canlıyken asıl yük çoğu zaman asenkron varlıktadır. Sonraki sayfa Yükleme & OnDestroy loader ömrü ile dispose sahipliğini anlatır. Picking ve Zone kaçışı sonraki yapraklardadır.