iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 24
0
Modern Web

再談 PixiJS,那些先前不一定有提到的部分與地雷系列 第 24

[Re:PixiJS - Day24] 用 Texture 實作把網頁弄壞 的 Demo

標題看起來好像有點厲害,但是是要實作把 網頁弄壞的 Demo

先前提到 Texture.from(<canvas>) 會產生 TextureCache / BaseTextureCache

由於會變成 PixiJS 裡的快取,沒有手動清除時可能會讓 記憶體資源耗盡


先前使用 Canvas 當成材質的範例:


[ Demo ] 使用 同一個 Texture

const gradTexture = createGradTexture();

setInterval(()=>{
    const sprite = new PIXI.Sprite(gradTexture);
    app.stage.addChild(sprite);
    sprite.x = Math.random() * (app.screen.width - 100);
    sprite.y = Math.random() * (app.screen.height - 100);
}, 1000);


[ Demo ] 每次使用不同的 Texture
會產生越來越多個 TextureCache / BaseTextureCache 快取

setInterval(()=>{
    const gradTexture = createGradTexture();
    const sprite = new PIXI.Sprite(gradTexture);
    app.stage.addChild(sprite);
    sprite.x = Math.random() * (app.screen.width - 100);
    sprite.y = Math.random() * (app.screen.height - 100);
}, 1000);

因為會越來越多,然後就整個頁面壞了


來把頁面弄壞吧!

[ Demo ]

  1. 先提示這是個 Demo 會造成頁面壞掉,是否繼續
  2. 更新情況還算溫和,設定 160毫秒 更新一次 (大約6FPS) Texture,但每次更新時,產生的 BaseTexture 快取圖片並不小
  3. 以我自己 2017年 SONY Xperia XZ1 來說,不用一分鐘就黑畫面了
  4. Sprite 數量不變,只有看 不到的 TextureCacheBaseTextureCache 增加
  5. 然後它就壞掉了,很簡單吧!

if (window.confirm("Crash Demo")) { 
}else{
    window.history.go(-1);
}

function createGradTexture(w, h) {
    const canvas = document.createElement('canvas');
    // 重新繪製漸層
    return PIXI.Texture.from(canvas);
};

setInterval(()=>{
    app.stage.children.forEach((child)=>{
        child.texture = createGradTexture(spriteWidth, spriteHeight);
    });
}, 160);

註:這次直接列出有多少數量的 TextureCache / BaseTextureCache

function ObjectLength( object ) {
    return Object.keys(object).length;
};

ObjectLength(PIXI.utils.TextureCache);

弄壞了要修好

[ Demo ]

setInterval(()=>{
    app.stage.children.forEach((child)=>{
        child.texture.destroy(true); // 加上這行,把 Texture 與 BaseTexture 清除
        child.texture = createGradTexture(spriteWidth, spriteHeight);
    });
}, 160);

只加了一行 child.texture.destroy(true);
放了一陣子後,嗯,沒壞。

一行解決 擔心專案上不了線 的問題

今日心得: TextureBaseTexture 看不見,也會以爲在沒使用時會被回收
但實際上是容易造成 記憶體資源耗盡 的原因之一

參考討論:Difference between texture and baseTexture?


上一篇
[Re:PixiJS - Day23] 了解 Texture / BaseTexture
下一篇
[Re:PixiJS - Day25] destroy(),連同快取一起摧毀物件
系列文
再談 PixiJS,那些先前不一定有提到的部分與地雷45

尚未有邦友留言

立即登入留言