HTML5 Canvas · Sprite ve varlık sistemi
Varlık önbellekleme: tarayıcı ve bellek katmanları
Canvas oyununda aynı sprite levhası on kez «ihtiyaç duyuldu» diye on kez ağdan indirilmez;
tarayıcı
HTTP önbelleği ilk yanıtı saklar, siz de isteğe bağlı olarak
bellek içi (
in-memory ) bir sözlükte HTMLImageElement veya onu üreten
Promise tutarsınız. Bu sayfa tekilleştirme (
aynı URL için tek uçuş ), sürümleme ile önbellek kırma ve eşzamanlı
yükleme yarışlarını Canvas öğretim hedefiyle sabitler. Dosyayı ilk kez getirmek
Resim yükleme sayfasında; dilimleme
Sprite levhası, kare zamanlaması
Kare animasyonu başlıklarındadır.
Zaman ve çizim disiplini için Kare yönetimi ve Update vs render ile birlikte düşünün; ağır yükleme fazını oyun döngüsünden ayırmak kare fazları düşüncesiyle uyumludur.
Özet: iki katmanlı önbellek
| Katman | Ne tutar? | Yöneten |
|---|---|---|
| HTTP önbelleği | Ağ yanıt gövdesi ( dosya baytları ) | Tarayıcı + başlıklar |
| Bellek sözlüğü | Promise veya Image |
Uygulama kodu |
| Görüntü nesnesi | Dekode edilmiş raster | Tarayıcı / GPU |
| Sürüm | URL veya sorgu anahtarı | Yayın süreciniz |
| Tüketim | drawImage |
Dilim çizimi |
Tarayıcı önbelleği ve uygulama sözlüğü: roller
İlk fetch veya img.src = url isteği sunucuya gider; yanıt
Cache-Control ve benzeri başlıklarla tarayıcı diske veya belleğe alınabilir.
İkinci kez aynı URL ile istek yapan kod, ağ paketini görmeyebilir —
ama yine de yeni bir Image nesnesi oluşturup dekode ederseniz
JavaScript belleğinde ikinci kopya oluşturmuş olursunuz. Bu yüzden üretimde
genelde «tek URL → tek uygulama düzeyi önbellek girişi» hedeflenir.
Statik site veya sürüm çözümlemesi zayıfsa kullanıcı eski dosyayı görmeye devam eder; bu, Canvas hatası gibi görünür ama aslında önbellek politikasıdır. Geliştirici araçlarında «önbelleği devre dışı bırak» ile davranış farkını ayırt etmek yaygın teşhis adımıdır.
Bu sayfa sunucu başlıklarını yapılandırmayı öğretmez — yalnız istemci tarafı tekilleştirme ve sürümleme ile ürün kodunun önbellekle nasıl uyumlu kalacağını sabitler.
Promise önbelleği: aynı URL için tek uçuş
İki modül aynı karede loadImage(url) çağırabilir; tarayıcı ağ katmanında
istekleri birleştirse bile istemci tarafında yine de iki ayrı
HTMLImageElement üretilip iki kez dekode edilebilir. Promise önbelleği bu
yüzden
«tek uçuş» (
aynı mantıksal anahtar için tek paylaşılan Promise ) sağlar: ikinci çağrı
yeni istek başlatmak yerine aynı vaadi döner. Bu, HTTP önbelleğinin ne yaptığından
bağımsız bir optimizasyondur — katman farkı
birinci bölümde özetlenmiştir.
Önbellek anahtarı dizedir; göreli / mutlak
URL farkı iki giriştir — normalleştirme
yedinci bölümde. Vaat reddedilirse
haritadan silmek (
aşağıdaki .catch kalıbı ) gerekir; aksi halde sonsuza kadar reddedilmiş bir
Promise kalır ve yeniden denemeler boşa çıkar. Başarılı sonuçta girişi tutmak
ise tekrar await maliyetini önler — bellek ile takas (
bellek bütçesi ).
Uzun oturumlarda harita büyür; seviye değişiminde
clear() veya kullanılmayan anahtarları
delete etmek, atlasları bırakmayı mümkün kılar — ayrıntılı strateji yine
dördüncü
bölümde, burada yalnız Promise katmanının ömür yönetimine değinilir.
loadFn enjeksiyonu (
dependency injection ), önbellek modülünü ağ politikasından ayırır;
loadImage
veya
dekodlu yükleme
ile
birleştirmek tek satırda yapılır. Böylece güvenlik beyaz listesi yükleme katmanında kalır;
bu
kutu rastgele URL üretmez (
resim yükleme ·
anti-kalıplar
ile hizalı ).
/**
* loadFn: (url) => Promise<HTMLImageElement> — aynı url için paylaşılan Promise döner.
* Hata: giriş silinir; başarılı sonuç aynı Promise ile yeniden kullanılır.
*/
function createImagePromiseCache() {
const map = new Map();
return {
load(url, loadFn) {
let p = map.get(url);
if (!p) {
p = loadFn(url).catch((err) => {
map.delete(url);
throw err;
});
map.set(url, p);
}
return p;
},
has(url) {
return map.has(url);
},
delete(url) {
map.delete(url);
},
clear() {
map.clear();
},
};
}
Sürümleme ve önbellek kırma: güvenli URL sözleşmesi
Yayınlanan varlık değiştiğinde tarayıcı eski dosyayı sunmaya devam edebilir; en basit
istemci
çözümü sorgu parametresi (
?v=20260515 ) veya dosya adına karma eklemektir. Parametre değerini
sizin kontrolünüzdeki bir derleme kimliğinden üretin; kullanıcı girdisiyle
birleştirmeyin.
Aynı mantıksal varlık, farklı sürümde farklı tam URL olduğunda
uygulama
önbelleğinde iki giriş bulunur — bu beklenen davranıştır; eski girişi temizlemek bellek
kazanır. Serbest bırakma (
garbage collection ) yalnız referanslar düştüğünde gerçekleşir;
global listede tutulan Image’leri elle «unut» etmek gerekir.
Ön yükleme listelerinde ( toplu yükleme ) sürümlenmiş URL’e geçmek, tüm haritayı tutarlı kılar.
/** version: derleme / yayın kimliği; null/undefined ise url aynen döner. */
function withCacheVersionQuery(url, version) {
if (version == null || version === "") return url;
const sep = url.includes("?") ? "&" : "?";
return `${url}${sep}v=${encodeURIComponent(String(version))}`;
}
Bellek bütçesi: ne zaman temizlemek gerekir
Büyük atlaslar mobil cihazlarda kolayca yüzlerce megabayt grafik belleği tüketir; tüm
levhaları
oyun başında yüklemek basit ama riskli bir stratejidir. Seviye bazlı yükleme: yeni bölüme
girerken haritayı doldur, çıkarken referansları bırak —
Map.clear() ve ilgili değişkenleri sıfırlamak yeterli olabilir, nesneler başka
yerde tutulmuyorsa.
«Zayıf» ( WeakRef ) referanslar ileri bir konudur; çoğu Canvas projesinde açık yaşam döngüsü ( yükle → kullan → bırak ) daha anlaşılırdır. Bellek profili çıkarmak için tarayıcı geliştirici araçları yeterlidir — bu sayfa profilleme rehberi değildir.
Sekme arka plandayken görüntüleri tutmak pil ve bellek açısından maliyetlidir; ürün politikası sekmeyi dondurmak ise duraklatma ile bağlanır, önbelleği boşaltma kararı ayrıca verilir.
Ön yükleme ipuçları ve kritik yol
İlk karede takılmayı azaltmak için kritik görseller (
arayüz, oyuncu levhası ) yüklenene kadar ilerlemeyi kilitlemek veya düşük çözünürlüklü yer
tutucu göstermek yaygındır — akış
decode ve giriş ekranı
tasarımının bir parçasıdır. İsteğe bağlı
<link rel="preload"> (
HTML ) bazı tarayıcılarda ilk isteği öne çeker; tutarlılık için
yine de kodda aynı sürümlenmiş URL’i kullanın.
Service Worker ile önbellek stratejisi kurmak bu serinin dışındadır;
temel Canvas öğreniminde önce tekilleştirilmiş Image yükleme yeterlidir. İşçi
iş parçacığına taşımak decode’u karmaşıklaştırır — ayrı araştırma gerektirir.
Çoklu format ( WebP yedekli PNG ) kaynak seçimi önbellekten bağımsız bir katmandır; seçim yapıldıktan sonra önbellek anahtarı nihai URL olmalıdır.
Önbellek ve CORS: tuval güvenliği köprüsü
Aynı görüntü nesnesini önbellekte tutarken crossOrigin ataması o anki tüketimle
uyumlu olmalıdır; kirlenmiş tuval, daha sonra aynı dosyayı «düzgün yükledim» sansanız bile
okuma API’lerini kilitleyebilir. Politikayı proje başında tekilleştirin —
resim yükleme · CORS
bölümüyle aynı hat üzerinde durun.
Farklı kökten yakalanmış iki kopya ( biri kirli, biri temiz ) aslında aynı dosya olsa bile farklı güvenlik durumunda olabilir; tek yükleme yolundan geçirmek bu sürprizi azaltır.
Veri URL’leri (
data: ) ve yerel blob URL’leri önbellek anahtarı olarak geçerli ama
yaşam döngüsü farklıdır; blob URL’leri kullanımdan sonra
revokeObjectURL ile serbest bırakılmalıdır — sprite levhası akışında daha az
yaygındır.
Yinelenen haritalar ve tutarsız anahtar
Aynı dosya için biri göreli (
/assets/a.png ), biri mutlak (
https://site/a.png ) iki anahtar iki ayrı önbellek girişi yaratır. Temel kural:
uygulama içinde tek normalleştirilmiş URL biçimi (
genelde mutlak veya taban + göreli çözümleyici ).
Ön yükleme dizisi ve çalışma anı istekleri farklı dize kullanırsa tekilleştirme bozulur;
küçük
bir resolveAssetUrl(path) fonksiyonu tüm yükleme noktalarına yayılır.
Sürüm parametresi bazen yalnız ön yüklemede eklenip oyun sırasında unutulursa iki farklı gerçek kaynak kullanılmış olur — ya hep sürümlü ya hep ham yol seçin.
Anti-kalıplar: sözlüksüz kopya ve aşırı kırma
Aşağıdaki örnekler ya bellek şişmesi ya da güncelleme sonrası «neden eski sprite kaldı?» sorununu üretir; kök çözüm çoğu zaman tek uçuş + sürüm + tek tip URL üçlisidir. Bu bölüm, aynı temanın yan etkilerini ayırarak teşhis etmeyi kolaylaştırır — çizim geometrisi levha sayfasında değişmez.
Her istekte yeni Image: Ağ önbelleği baytı tekrar indirmese
bile her new Image() yoluyla yeniden dekod ve bellek ayırımı tetiklenebilir;
özellikle aynı levha çok varlık tarafından paylaşılıyorsa tek referans üzerinden
drawImage (
dilim çizimi ) tercih
edilmelidir. Uygulama önbelleği
resim yükleme ·
tekilleştirme ile aynı amaca hizmet eder; birini seçip iki kez uygulamayın.
Her yayında rastgele sorgu (
cache bust ):
Date.now() veya rastgele token ile URL her seferinde
benzersiz
olursa tarayıcı ve CDN önbelleği devre dışı kalır; mobil veri ve
soğuk
açılış zarar görür. Yalnız içerik değişince
withCacheVersionQuery veya
eşdeğer bir sürüm kimliği artırılmalıdır.
Hata sonrası giriş silinmeden yeniden deneme: Reddedilmiş
Promise haritada kaldıysa sonraki
load çağrıları aynı ölü vaide takılı kalır.
createImagePromiseCache
içindeki silme kalıbı tam bu içindir; özelleştirirken aynı sözleşmeyi koruyun.
Haritayı sıfırlayıp sahne referanslarını eski tutmak: Önbellek boşaldı
sanılırken dünya nesneleri hâlâ eski
Image’e işaret eder; yeni sürüm yüklense bile çizim eski pikselleri gösterir.
Temizlik anında hem
Map hem oyun içi görsel tutamaçları (
levha referansı, varlık alanları ) birlikte güncellenmeli; aksi halde «dosya doğru, ekran
yanlış» hayaleti oluşur —
toplu ön
yükleme
listesiyle referansların aynı sürümlü URL’den geldiğini doğrulamak hızlı kontrol sağlar.
Bu sayfanın sınırı
CDN yapılandırması, çığ ( stale-while-revalidate ) politikaları ve kapsamlı Service Worker önbellek şemaları burada derinleştirilmez. Odak: Canvas tabanlı oyunlarda istemci tarafı görüntü yeniden kullanımı ve güvenli URL sözleşmesidir.
- Aynı varlık için tek Promise / tek
Imagekuralı var mı? - Sürüm veya karma tek yerden üretiliyor mu?
- URL normalleştirme tüm yükleme yollarında ortak mı?
- Büyük oturumlarda bellek için bölüm sonu temizliği planlandı mı?
- CORS politikası önbelleklenen nesnelerde tutarlı mı?