CreateJS / PreloadJS

PreloadJS makes preloading assets & getting aggregate progress events easier in JavaScript. It uses XHR2 when available, and falls back to tag-based loading when not.
http://createjs.com/
MIT License
2.88k stars 761 forks source link

Best practice to load multiple times (LoadQueue reuse?). #232

Open xpol opened 7 years ago

xpol commented 7 years ago

I have a single page application (SPA) use PreloadJS for resource loading.

I have different screens (pages) in my SPA (have different url using react-router). I need load resources for each view when user navigate to. And if previous loading is not complete I need just stop all loading before new loading.

Should I create a new LoadQueue for each loading process or reuse the LoadQueue?

I first tried to reuse the queue:

const queue = new createjs.LoadQueue()
createjs.Sound.alternateExtensions = ['mp3']
queue.installPlugin(createjs.Sound)
queue.setMaxConnections(8)

const preload = (manifest) => {
  // console.log(manifest)
  manifest = unique(manifest).filter(i => i)
  console.log(`Loading ${manifest.length} assets...`)

  queue.removeAll()
  queue.removeAllEventListeners()
  queue.reset()

  return new Promise((resolve, reject) => {
    queue.on('complete', () => resolve({ok: true}))
    queue.on('error', (error) => reject({error}))
    queue.loadManifest(manifest)
  })
}

But it sometimes fires 'complete' when some resources not loaded.

Then I tried:

let queue

const preload = (manifest) => {
  if (queue) queue.destroy()

  queue = new createjs.LoadQueue()
  createjs.Sound.alternateExtensions = ['mp3']
  queue.installPlugin(createjs.Sound)
  queue.setMaxConnections(8)

  console.log(manifest)
  manifest = unique(manifest).filter(i => i)
  console.log(`Loading ${manifest.length} assets...`)

  return new Promise((resolve, reject) => {
    queue.on('complete', () => resolve({success: true}))
    queue.on('error', (error) => resolve({error}))
    queue.loadManifest(manifest)
  })
}

My question is which is the best practice to load different set of resources, create a new LoadQueue for each set or reuse one single LoadQueue? If reuse is OK, how to correct reset LoadQueue for next loading request.

lannymcnie commented 7 years ago

Typically we recreate queues, but I can see how issues surrounding caching could make reuse more useful.

owendwyer commented 7 years ago

I got caught out with this - complete firing when some resources not loaded.

var myLoadQueue=null;
var myManifest=[];
myManifest.push({src:'sprite0.png',id:'sprite0'});
myManifest.push({src:'sprite1.png',id:'sprite1'});
myManifest.push({src:'sprite2.png',id:'sprite2'});

function load(){
    myLoadQueue=new createjs.LoadQueue(false);
    myLoadQueue.addEventListener('complete',setupAssets);
    myLoadQueue.addEventListener('error',gotError);
    myLoadQueue.loadManifest(myManifest,true,resFolder);
}

function gotError(){
    myLoadQueue.removeEventListener('complete',setupAssets);
    myLoadQueue.removeEventListener('error',gotError);
    myLoadQueue.destroy();
    myLoadQueue=null;
    tryTimes--;
    if(tryTimes>0){
        console.log('Load Error - retrying');
        load();
    }else{
        console.log('Load Error - giving up');
    }
}

function setupAssets(){
}

If load fails the first time, then it seems to ignore that file on the second try and fire the complete event when the others have loaded.

I got it to work as intended by putting the manifest inside the load function:

function load(){    
    var myManifest=[];
    myManifest.push({src:'sprite0.png',id:'sprite0'});
    myManifest.push({src:'sprite1.png',id:'sprite1'});
    myManifest.push({src:'sprite2.png',id:'sprite2'});
    myLoadQueue=new createjs.LoadQueue(false);
    myLoadQueue.addEventListener('complete',setupAssets);
    myLoadQueue.addEventListener('error',gotError);
    myLoadQueue.loadManifest(myManifest,true,resFolder);
}