2016-12-01 8 views
4

この問題は、特定の問題の解決策を探すのではなく、この例ではSafariが非効率である理由を理解しようとしています。大幅に遅く話すと、コードはFirefoxとChromeで1秒未満で実行され、Safariでは30〜90秒の範囲で実行されます。それはすでに文書化された問題の可能性が高いですが、私は理由を知らない。Firefox/ChromeよりもSafariでjQueryの方が大幅に遅いのはなぜですか?


状況は私にはかなり大きいHTMLテーブルがあります。 1,000〜1,500行×40列です。構造は次のようになります。

<table id="myTablePlayers" class="tablesorter table table-striped table-bordered table-hover" style="overflow: visible"> 
    <thead> 
     <tr> 
      <th>...</th> 
      <th>...</th> 
      <th>...</th> 
      <th>...</th> 
      ... 
      <th>...</th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr class="playerData"> 
      <td>...</td> 
      <td>...</td> 
      <td>...</td> 
      <td>...</td> 
      ... 
      <td>...</td> 
     </tr> 
     ... 
    </tbody> 
</table> 

多くのフォームフィールドでは、ユーザーが選択して行をフィルタリングするのに役立つ情報を入力できます。私は関係なく、ループ内で何の、コード、実行に時間がかかる問題のあるコードをダウン剪定を開始すると

function autoRank() { 
    // auto number 
    rank = 0; 
    $("#myTablePlayers .playerData").each(function() { 
     if ($(this).css("display") != "none") { 
      rank++; 
      $(this).find('td').eq(colRank).text(rank); 
     } 
    }); 
} 

function filterTable() { 
    // Need some error checking on input not number 
    minGP = $("#mingp").val() 
    teams = $("#teamFilter").val() 
    position = $("#position").val() 
    age = $("#age").val() 

    $("#myTablePlayers .playerData").show(); 

    $("#myTablePlayers .playerData").each(function() { 
     toHide = false; 

     if (teams != "") { 
      if (!$(this).find('td').eq(colTeam).text().toUpperCase().includes(teams.toUpperCase())) { 
       toHide = true; 
      } 
     } 

     if (Number($(this).find('td').eq(colGP).text()) < minGP) { 
      toHide = true; 
     } 

     if (position != "") { 
      if (position == "D") { 
       if ($(this).find('td').eq(colPos).text().indexOf("D") == -1) { 
        toHide = true; 
       } 
      } else if (position == "F") { 
       if ($(this).find('td').eq(colPos).text().indexOf("D") != -1) { 
        toHide = true; 
       } 
      } else if ($(this).find('td').eq(colPos).text() != position) { 
       toHide = true; 
      } 
     } 

     if (age != "") { 
      column = Number($(this).find('td').eq(colAge).text()) 
      age = Number(age) 
      if ( column < age || column >= age+1 ) { 
       toHide = true; 
      } 
     } 

     if (toHide == true) { 
      $(this).hide(); 
     } 

    }); 

    autoRank(); 
} 

$("#teamFilter").on('change', filterTable); 

$("#mingp").on('change', filterTable); 

$("#position").on('change', filterTable); 

$("#age").on('change', filterTable); 

、私は問題を解決し$("#myTablePlayers .playerData").each(function() {...

のようです:jQueryのは次のようになりますバニラJSにコードを書き直しても、このコードが1つのブラウザではあまり効率的でない理由はわかりません。

+4

問題はほとんど '.each()'ではなく、 '.css()'を使ってレイアウトを行っていることを確認しています。 – Pointy

+3

また、 'let'や' var'でローカル変数を宣言する必要があります。 – Pointy

+0

これはおそらくそうではないかもしれませんが、その一部かもしれません。 $(これ)を何度も繰り返してはいけません。各呼び出しでjQueryオブジェクトで 'this'をラップしているので、結果では全く新しいオブジェクトを作成しています。 同じことはセレクタにも適用されます。そのような$( "#myTablePlayers .playerData")のように2回クエリを実行しているので、ブラウザはドキュメントを2回クエリし、これらのノードを探します。それは良くないね。 jQueryの検索結果を変数にキャッシュするだけです。 – grzesiekgs

答えて

5

.css()で問い合わせを行ってDOMの状態を確認するのは非常にコストがかかることがあります。 .hide().show()の要素を隠す代わりに、クラスを追加/削除します。あなたの.each()ループがちょうどそのクラスを確認することができ

.hidden { display: none; } 

その後:あなたのCSSで

$("#myTablePlayers .playerData").each(function() { 
    if (!$(this).hasClass("hidden")) { 
     rank++; 
     $(this).find('td').eq(colRank).text(rank); 
    } 
}); 

何かを非表示にするには、あなたはそれを削除したいだけでそのクラスを追加したいし、それを表示します:

if (toHide) { 
     $(this).addClass("hidden"); 
    } 

そして表示する:

$("#myTablePlayers .playerData").removeClass("hidden"); 

今、.find().text()のすべてのコールが高価になります。テーブルを一度上に移動し、それぞれの行の興味深い値を効果的にキャッシュするために、それぞれの<tr>にデータプロパティを作成することによって、テーブルを初期化することはおそらく価値があります。 jQueryの.data()によるルックアップは、DOMのセレクタで見るよりも大幅に安くなります(現代のDOM実装はかなり速いですが)。

+1

'if(toHide == true){'は 'if(tohide){'(誰かが 'var toHide = new Boolean(false);'をどこかに持っていることを心配している場合を除きます) –

+0

@IsmaelMiguelはい、私はちょうどコピー/貼り付けますが、私はそれを修正します。 – Pointy

+2

クラスチェックをセレクタにローリングすることも検討してください。 '$("#myTablePlayers .playerData:not(.hidden) ")'。 –

関連する問題