更好的Javascript性能

问题描述:

我目前在React中构建一个应用程序来学习语言。该应用程序是一款游戏,在游戏中,我使用Howler.js播放很多声音。咆哮很棒,因为它可以让我轻松创作声音,而且非常重要的是,我可以调整声音的音高,我可以用一个样本制作旋律。更好的Javascript性能

我开始运行到时我在不同的音高事情有很多不同的声音的问题是性能。随着代码我已设置循环播放我的声音对象是相当沉重,我想知道是否有一种方法来优化它(我绝不是一个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声音的代码。请注意,上述对象的生活在我的应用程序状态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); 
     } 
    } 


} 

我尝试做尽可能多的事情,我可以在“阵营”的方式,但我还在学习,以便不确定是否有更好的方式来整合Play功能和我的Apps状态以获得更好的浏览器性能。

我已经想过使用音频精灵(这实际上是建立在吼工作得很好)。我试过用这个here。我实际上有一个安装问题,coudln't让它运行,但即使我设法解决这个问题,那么我不认为我可以添加声音与从howler API应用到精灵的音高弯曲?

谢谢,我欢迎对性能/解决方案的人可能有什么建议!

+1

一个微优化你可以做,不会对性能产生任何显着的影响,但可以与可维护性有助于将移动src'的'分配和'id'了'j'循环的地方'notesLength'被创建。它们只会在'i'改变时才会改变,所以每次'j'循环都不需要重读/重写它们。另外,如果你改变使用'let'而不是'var'将它们移动到合适的范围,也可能会阻止一些GC减速,因为使用'let'你将会不断创建和销毁变量,因为'let'是块范围。 –

+0

仅供参考,当前版本的audiosprite已损坏,请尝试使用以前的版本。另外,你应该没有问题用howler操纵单个精灵。 –

+0

谢谢詹姆斯,有没有一种方法可以推荐改变音频的音调,但以一种转换声音的方式?即使音高更高/更低但保持样本长度相同?此外,我已经尝试了一种新方法来解决我的性能问题:https://jsfiddle.net/xs5Lu4db/不确定是否可以推荐比这更精简的方法?这是最好的我可以拿出.. –

我不知道你的游戏是如何工作的,但也许你并不需要遍历整个阵列上。如果您将声音存储在散列中,并通过某个唯一标识符(可能是声音名称?)访问它们,则这应该会显着提高性能。

因此,而不是代替声明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']; 

不确定这是否合理你的游戏的上下文,但这至少可以帮助你重复整个循环。

+0

感谢您的提示,这将阻止我循环“外”forloop,但我仍然必须循环音符数组,除非有绕过这个方向吗? –

+0

为什么你需要在游戏的上下文中迭代notes数组?迭代音符实际上意味着什么?是否有任何东西阻止你使用散列而不是内部数组? – grizzthedj

+0

Basicaly笔记是基于用户输入(其音乐游戏)的动态。因此,当用户点击一系列按钮时,根据按钮,它会分配一定的声音以及该声音的不同音符(再次,音符取决于用户点击了哪个按钮,并且分配给该音符的变量将具有唯一性延迟和可选的音调(或速率)变化,这就是为什么我需要一种方式来循环播放声音 - 因为它们是基于用户输入的动态。不确定是否有方法可以在用户之前存储每个声音的功能点击播放可以在播放时保存性能? –