2017-02-17 5 views
0

В настоящее время я создаю приложение в React для изучения языка. Приложение - игра, и в игре я играю много звуков, используя Howler.js. Howler замечательный, поскольку он позволяет мне легко создавать звуки, а также очень важно, чтобы я мог настроить высоту звука, чтобы я мог создавать мелодии всего одним образцом.Лучшее Javascript performance

Проблема, с которой я начинаю сталкиваться, когда у меня много разных звуков на разных этапах, это производительность. С кодом, который у меня установлен, чтобы зациклиться на моем звуковом объекте, довольно тяжело, и мне интересно, есть ли способ его оптимизировать (я ни в коем случае не эксперт по Javascript, поэтому я не удивлюсь, если бы существовал намного более компактный способ выполнения звукового объекта). Во всяком случае вот мой звук объект ниже, чтобы дать вам идею:

var testTrack = [{ 
     rowId:1, 
     rowExtras:"notExpanded", 
     rowSample: 
      { 
       sampleId:"1", 
       notes:[ 
        { 
         keyNumber:0, 
         noteDelay:0, 
         notePitch:1 
        },{ 
         keyNumber:2, 
         noteDelay:460, 
         notePitch:1 
        },{ 
         keyNumber:4, 
         noteDelay:920, 
         notePitch:1 
        },{ 
         keyNumber:6, 
         noteDelay:1380, 
         notePitch:1 
        },{ 
         keyNumber:8, 
         noteDelay:1840, 
         notePitch:1 
        },{ 
         keyNumber:10, 
         noteDelay:2300, 
         notePitch:1 
        },{ 
         keyNumber:12, 
         noteDelay:2760, 
         notePitch:1 
        },{ 
         keyNumber:14, 
         noteDelay:3220, 
         notePitch:1 
        }        
       ], 
       sampleName:"Heavy Kick", 
       sampleSource:"../../samplesWav/sample1.wav" 
      } 

     },{ ...there are 12 more objects in the array with different samples in them 

Вот код, я использую, чтобы перебрать и воспроизводить звук с Howler.js. Пожалуйста, обратите внимание выше жизни объекта в моем состоянии Apps под this.state.trackObject:

playTrack(){ 

    var audioArray = this.state.trackObject; 

    for(var i=0; i <= audioArray.length - 1; i++) { 

     var rowObject = this.state.trackObject[i] 

     var notesLength = rowObject.rowSample.notes.length 

     for(var j=0; j <= notesLength - 1; j++) { 
      var notes = rowObject.rowSample.notes[j].noteDelay; 
      var id = rowObject.rowSample.sampleId; 
      var src = rowObject.rowSample.sampleSource; 
      var pitch = rowObject.rowSample.notes[j].notePitch; 

      playSample(id,notes,src,pitch)     
     } 

    } 

    function playSample(id,notes,src,pitch){ 

     if(id != "null"){ 
     setTimeout(function(){ 

     //this is where howler is used 
     var sound = new Howl({ 
       src: [src], 
       rate:pitch 
     }) 

     sound.play();     

     }, notes); 
     } 
    } 


} 

Я стараюсь делать вещи так, как я могу в пути «React», но я все еще учусь, так не если бы был лучший способ перевести функцию воспроизведения в состояние «Мои приложения» для лучшей производительности браузера.

Я думал об использовании аудио спрайтов (которые на самом деле настроены для работы в Howler). Я попытался использовать этот номер here. У меня на самом деле была проблема с установкой и не удалось запустить ее, но даже если мне удастся это исправить, я не думаю, что я мог бы добавить звуки с изгибом высоты, применяемым в API справки к спрайту?

Спасибо, и я приветствую любые предложения по производительности/решениям, которые могут быть у любого!

+1

Одна из микро-оптимизации, которую вы могли бы сделать, которая не оказала бы заметного влияния на производительность, но могла бы помочь в ремонтопригодности, заключалась в перемещении назначения 'src' и' id' из цикла 'j' в место, где Создается 'notesLength'. Они меняются только при изменении 'i', поэтому нет необходимости перечитывать/переписывать их каждый раз, когда' j' пеет. Кроме того, если вы когда-либо переходите на использование 'let' вместо' var', перемещая их в нужную область, вероятно, также предотвратит замедление работы GC, поскольку с 'let' вы будете постоянно создавать и уничтожать переменные, потому что' let' является блочным областью , –

+0

Просто FYI, текущая версия аудиосприта сломана, попробуйте использовать предыдущую версию. Кроме того, у вас не должно быть проблем с манипуляцией шагом на отдельных спрайтах с помощью howler. –

+0

Спасибо, Джеймс, есть ли способ, по которому вы можете порекомендовать изменить высоту звука, но таким образом, чтобы переносить звук? т.е. делает шаг выше/ниже, но сохраняет длину образца одинаково?Также я пробовал новый подход для своих проблем с производительностью здесь: https://jsfiddle.net/xs5Lu4db/ не уверен, что вы можете рекомендовать более простой способ, чем это? Это лучшее, что я мог бы придумать. –

ответ

1

Я не уверен, как работает ваша игра, но, возможно, вам не нужно перебирать весь массив. Если вы храните звуки в хэше и получаете доступ к ним с помощью уникального идентификатора (возможно, звукового имени?), Это должно резко повысить производительность.

Так вместо того, чтобы вместо того, чтобы объявить TestTrack как массив, как это ...

var testTrack = [{ 
    rowId:1, 
    rowExtras:"notExpanded", 
    rowSample: { // Code removed for brevity } 
},{ 
    rowId:2, 
    rowExtras:"notExpanded", 
    rowSample: { // Code removed for brevity } 
}]; 

Объявите это так ...

var testTrack = { 
    "track1": { 
    rowId:1, 
    rowExtras: "notExpanded", 
    rowSample: { } 
    }, 
    "track2": { 
    rowId:2, 
    rowExtras:"notExpanded", 
    rowSample: { } 
    } 
}; 

Затем доступ к элементам, используя один из следующих способов , где «track1» будет звуковым именем ...

var myTrack = testTrack.track1; 
var myTrack = testTrack['track1']; 

Не уверен, что это имеет смысл в c ontext вашей игры, но это, по крайней мере, избавит вас от повторения всего цикла.

+0

Спасибо за подсказку, что помешало бы мне зациклиться на «внешнем» шлюзе, но мне все равно пришлось бы перебирать массив примечаний, если бы не было и пути вокруг этого? –

+0

Зачем вам нужно перебирать массив примечаний в контексте игры? Что означает итерация заметок? Есть ли что-нибудь, препятствующее вам использовать хэш вместо внутреннего массива? – grizzthedj

+0

Основными примечаниями являются динамические данные, основанные на пользовательском вводе (его музыкальная игра). Поэтому, когда пользователь нажимает на несколько бутонов, в зависимости от кнопки он назначает определенный звук, а также различные ноты для этого звука (снова заметки зависят от того, какая кнопка нажата пользователем, а переменная, назначенная этой ноте, будет иметь уникальный задержки и опционального изменения высоты тона (или скорости), поэтому мне нужен способ петли над звуками - потому что они динамически основаны на пользовательском вводе. Не уверен, что есть способ сохранить функцию для каждого звука перед пользователем чтобы сохранить производительность во время игры? –