holodepth

HTML5 Canvas · Render döngüsü

Frame yönetimi: kare bütçesi ve döngü yaşam döngüsü

Frame ( kare ), bu bağlamda tek bir requestAnimationFrame turunda simülasyon ve çizim adımlarını tamamlayıp görünür bitmap’i güncellemiş olmanızdır — yani kullanıcının bir sonraki ekran yenilemesinde görebileceği «anlık görüntüyü» teslim ettiğiniz atomik birim. Frame yönetimi; bu birim için süre bütçesi ayırmayı, döngüyü güvenle başlatıp durdurmayı, geride kaldığınızda neyi keseceğinize karar vermeyi ve birden fazla canvas yüzeyini aynı zaman çizelgesinde tutmayı kapsar. Bu sayfa o kararları Canvas 2D üreticisi gözüyle sabitler.

Planlayıcı kancası requestAnimationFrame ; adım süresi Delta time ; piksel sıfırlama Clear & redraw ; güncelle / sun ayrımı Update vs render — burada odak, bir kareyi üretim hattı olarak nasıl yöneteceğiniz dir.

Özet: kare yönetimi başlıkları

Başlık Soru Canvas’ta tipik sonuç
Kimlik Bu tur hangi kare? Log, test, ikili açılarda senkron
Bütçe Bu tura ne kadar ms ayırdım? Yoğun çizimde kare atlama / sadeleştirme
Yaşam döngüsü Döngü çalışıyor mu, duraklatıldı mı? Sekme görünürlüğü, modal, cleanup
Çoklu yüzey Aynı karede kaç buffer güncellenir? HUD + ana sahne; tek planlayıcı tercih

Kare kavramı: görünür bitmap ve tek teslim

Tarayıcı açısından bir kare, ana iş parçacığında planlanan bir boyama fırsatıyla sınırlıdır; sizin sorumluluğunuzda ise o fırsatta canvas piksel önbelleğini hedef görünümle uyumlu hale getirmektir. «Yarım çizilmiş» ara durum teorik olarak mümkün olsa da çoğu ürün bir kareyi atomik teslim eder: temizlik veya zemin → dünya → HUD tek turda biter; kullanıcıya yansıyan kompozit katman bir sonraki düzenleme ve boyamada birleşir.

Kareyi yalnızca çizim ile sınırlamayın: aynı turda girdi özetleme, yapay kaydırma konumunun ilerlemesi veya ağ mesajı uygulama gibi mantık işleri de genelde bu birime dahildir ( Update vs render · sıra ). Frame yönetimi, bu işlerin toplam süresinin sağlıklı kalmasını izlemeyi de içerir.

Kısa süreli animasyon «tek kare ileri sarı» gibi özel efektler bilinçli istisnadır; üretimde varsayılan, yine atomik kare teslimidir — aksi halde ekran fotoğrafı veya video yakalama araçları ara hâlleri yakalayabilir.

Kare bütçesi: süre, ölçüm ve profil ayrımı

60 Hz ekranda tipik hedef ~16.7 ms; bu bir üst limit değildir — yalnızca hissî referanstır. Gerçek bütçe cihaz sıcaklığı, arka plan sekmeleri ve işletim sistemi zamanlayıcısıyla değişir. Profilde üç blok ayırmak işe yarar: mantık ( update), çizim ( render), çevresel (ölçüm, log). Hangi blok patlıyorsa optimizasyon yönü bellidir; tek bir «frame süresi» sayısı yeterli olmayabilir.

Bütçeyi kod içinde sabitlemek için performance.now() ile tur başı/sonu ölçümü yaygındır; rAF zaman damgası ( rAF · zaman damgası ) ile karıştırmayın — biri kareler arası delta, diğeri alt blok süreleri için ayrı kullanılabilir. Üretimde uyarı eşiğini ortam değişkeni veya basit ayar dosyasına bağlamak, kullanıcı cihazında gereksiz konsol gürültüsünü azaltır.

Çizim tarafında tam ekran shadowBlur, global filter veya dev getImageData çağrıları tek başına bütçeyi deler; bu araçların yönetimi frame başına sayaç veya kalite basamağı ( tier ) ile sınırlanır — detaylı maliyet tablosu bu sayfanın sınırı dışında bırakılır, yalnızca «kare yöneticisi bunları fark etmeli» uyarısı verilir.

/**
 * runFrame: tek karede update+render dahil tüm iş.
 * budgetMs: uyarı için üst eşik (üretimde log seviyesine bağlanır).
 */
function measureFrameWork(runFrame, budgetMs, onOverBudget) {
  const t0 = performance.now();
  runFrame();
  const ms = performance.now() - t0;
  if (typeof budgetMs === 'number' && ms > budgetMs && typeof onOverBudget === 'function') {
    onOverBudget(ms, budgetMs);
  }
  return ms;
}

Kare sayacı ve hata ayıklama kimliği

Monoton artan bir frameId ( 1, 2, 3… ), log satırlarını ve performans örneklerini tek bir eksende birleştirir: «1234. karede gölge açıldı» demek, Date.now ile milisaniye kovalamaktan daha okunaklıdır. Döngü durdurulup yeniden başlatıldığında sayacı sıfırlamak veya sıfırlamamak ekip kararıdır — karışık davranış, kayıtlı oturumları iki birleştirirken kafa karıştırır.

Bazı motorlar çift veya atlanan kareleri ayırt etmek için ayrıca mantık tik sayacı ( tick ) tutar; frameId yalnız görünür rAF turunu sayar, sabit adımda fizik iç döngüsü fazladan adım atabilir ( Delta time · sabit adım ). İsimlendirmede ikisini karıştırmayın.

Test harness’lerinde deterministik replay için frameId yerine sabit zaman adımlı simülasyon anahtarı kullanılabilir — bu sayfa üretim zamanlı canvas varsayar; test stratejisi yalnızca hatırlatma olarak not edilir.

/**
 * runFrame({ now, dt, frameId }) — dönüş yok; içeride update+render birleşebilir.
 */
function createFrameDriver(runFrame) {
  let rafId = 0;
  let running = false;
  let last = 0;
  let frameId = 0;

  function loop(now) {
    if (!running) return;
    const dt = last ? (now - last) / 1000 : 0;
    last = now;
    frameId += 1;
    runFrame({ now, dt, frameId });
    rafId = requestAnimationFrame(loop);
  }

  return {
    start() {
      if (running) return;
      running = true;
      last = 0;
      rafId = requestAnimationFrame(loop);
    },
    stop() {
      running = false;
      cancelAnimationFrame(rafId);
      rafId = 0;
      last = 0;
    },
    getFrameId: () => frameId,
  };
}

Döngü yaşam döngüsü: başlat, duraklat, temizle

start / stop çiftinin yanında çoğu ürün duraklat ( pause ) tanır: döngü planlanmaz, fakat dünya durumu korunur — modal açıldığında veya kullanıcı menüye girdiğinde süre akışı donar. Sekme gizliyken tarayıcı zaten kareleri seyreltir; uygulama içi duraklatma buna ek olarak mantıksal zamanda da ilerlemeyi kesebilir ( rAF · görünürlük ).

Bileşen yok olurken cancelAnimationFrame ile planlı geri çağrıyı iptal etmek zorunludur; aksi halde «hayalet kare» bellek ve hata konsolunda iz bırakır. Durum bayrakları ( running ) erken return ile korunmalıdır — istisna fırlatmayan rAF içi sessiz sızıntı yaygındır.

Uzun ömürlü dinleyiciler (fare, klavye) canvas ile aynı yaşam döngüsündeyse stop aşamasında kaldırılmalıdır; aksi halde durmuş sanılan döngüye hâlâ olay tetikler ve kirli bayraklar beklenmedik yeniden çizim üretir.

Geride kalma: kare atlama ve sadeleştirme

Bir tur bütçeyi aştığında tarayıcı yine bir sonraki rAF fırsatını verir; siz ise ya aynı ağır işi tekrarlarsınız ya da kaliteyi düşürür (gölgeyi kapat, parçacık sayısını yarıla, grafik ara noktalarını seyrelt). Frame yönetimi burada ürün kararıdır: oyun hissi mi, doğruluk mu — sabit kod yoktur.

Çoklu mantık adımı ( sabit adım birikimi ) ile aynı görünür karede CPU’yu zorlamak, bir sonraki karede boşluk doğurabilir; birikim tavanı hem fizik hem kare yönetimi sorumluluğundadır.

«Bu kareyi tamamen atla, bir sonrakinde dünya özetini çek» deseni nadirdir ve genelde ağ tabanlı senkron gerektirir; vanilla canvas öğreticisinde önerilmez — yalnızca var olduğunu not ederiz.

Birden fazla yüzey ve tek çizelge

Ana sahne ve HUD için iki canvas kullanıldığında ideal tablo: tek rAF planlayıcı önce dünya durumunu günceller, sonra sırayla her bağlamda çizer — iki bağımsız requestAnimationFrame zinciri çift maliyet ve senkron kayması üretir. İstisna: bir yüzey tamamen statik ve yalnız olayda çiziliyorsa ayrı planlayıcı düşünülebilir ( Update vs render · kirli bayrak kısa köprü).

Üst üste binen canvas’larda CSS ile konum hizalanır; kare yönetimi açısından önemli olan, her turda hangi sırayla kompozit edildiğidir — alt canvas önce, üst HUD sonra tipik pattern’dir. Boyut veya DPR değişiminde her iki dahili yüzey ölçüsü güncellenmeli, aksi halde bir katman bulanık veya kırpılmış kalır ( Resize mantığı ).

Offscreen yüzey veya worker senaryosu bu sayfada açılmaz; ana belgede çalışan çoklu görünür canvas varsayılır.

Anti-kalıplar: ölçümsüz ve çift planlayıcı

Sayaçsız üretim: Bisect ve profil olmadan kare hissini iyileştirmeye çalışmak rastgele körleme gibidir — en azından tur süresi ve frameId loglayın.

İptalsiz unmount : Planlı rAF devam eder; sessiz bellek sızıntısı ve konsol uyarıları.

Çift rAF: Aynı mantık iki zincirde iki kez güncellenir; dünya hızlanır veya titrer.

Bütçe yok varsayımı: Her cihaz 60 fps sanmak, düşük uçta sürekli kare düşüşü yaratır — ölçün, kalite basamağı hazırlayın.

Bu sayfanın sınırı

Tarayıcı sekmesi dışında çalışan render süreçleri ( WebGPU, workers ) ve video kodlayıcı zaman çizelgeleri farklı disiplinlerdir; burada yalnızca ana belge + Canvas 2D kare yönetimi anlatılmıştır.

Variable refresh rate ve OS düzeyinde kare sınırlama konuları cihaza bağlıdır — bütçe politikanızı sabit ms yerine ölçüme dayalı tutmak daha taşınır kalır.

  • Kare kimliği loglarda ve hata raporlarında tutarlı mı?
  • Tur süresi blokları (mantık / çizim) ayrı ölçülüyor mu?
  • stop / pause planlı rAF ve dinleyicileri temizliyor mu?
  • Çoklu canvas tek planlayıcıda mı, yoksa çift motor mu var?
  • Bütçe aşımında kalite düşürme veya adım tavanı devrede mi?