jQuery在Safari上的速度比Chrome / Firefox慢

时间:2016-11-29 16:11:03

标签: javascript jquery html

我有一个大的HTML表格(1,000-1,500行,40列宽)。我有一些输入和选择框,以便用户可以过滤行。附加到它的相关javascript / jquery(注意:不是整个代码库被粘贴,因为它不是瓶颈)看起来像:

#include <iostream>
#include <stdlib.h>

using namespace std;

struct Node {
    int num;
    Node *pNode, *nNode;  // Add a new pointer to the previous node.
};

int Input() {
    int number;
    cout << "Enter the number: "; cin >> number;
    return number;
}

Node *_MakeList2(int n, Node *last=NULL) {
    if (n > 0) {
        Node *node = new Node;
        node->num = Input();
        node->pNode = last;
        node->nNode = _MakeList2(n - 1, node);
        return node;
    }
    return NULL;
}

Node *MakeList2(int n) {
    return _MakeList2(n);
}

void Print(Node *head, int toRight=1) {
    if (head != NULL) {
        cout << head->num << " ";
        if (toRight)
            Print(head->nNode, 1);
        else
            Print(head->pNode, 0);
    }
}

Node* AddNode(Node *head, int index, int elm) {
    Node *p = new Node;
    p->num = elm;
    p->pNode = NULL;  // Make the link between this node and the previous one.
    p->nNode = NULL;

    if (head == NULL)  {
        head = p;
    } else {
        Node *current = head;
        for (int i = 0; (i < index - 1) && (current->nNode != NULL); i++) {
            current = current->nNode;
        }
        if (index == 0) {
            p->nNode = head;
            head->pNode = p;  // Make link between next node's previous node and the current one. 
            head = p;
        } else {
            if (current->nNode != NULL)  {
                p->nNode = current->nNode;
            }
            p->pNode = current;  // Make the link between this node and the previous one.
            current->nNode = p;
        }
    }
    return head;
}

int Sum(Node* head) {
    int sum = 0;
    Node *p = head;
    while(p) {
        if ((p->num > 3) && (p->num < 8))
            sum += p->num;
        p = p->nNode;
    }

    return sum;
}

void DeleteList(Node *head) {
    if (head != NULL) {
        DeleteList(head->nNode);
        delete head;
    }
}

int main() {
    int n = 10;
    Node *head = NULL, *tail = NULL;

    cout << "Enter " << n << " number(s) to the list" << endl << endl;
    head = MakeList2(n);
    int sum = Sum(head);
    head = AddNode(head, 0, sum);

    cout << endl << "List: ";
    Print(head);
    cout << endl;

    tail = head;
    if (tail) {
        while (tail->nNode != NULL)
            tail = tail->nNode;
        cout << endl << "List reversed: ";
        Print(tail, 0);
        cout << endl;
    }
    DeleteList(head);

    system("pause");
    return 0;
}

在尽可能少地删除代码时,违规代码是

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

var teamCols = $(),
    GPCols = $(),
    posCols = $(),
    ageCols = $();

$("#myTablePlayers .playerData").each(function() {
  var columns = $(this).find('td');
  teamCols = teamCols.add($(".colTeam", this));
  GPCols = GPCols.add(columns.eq(colGP));
  posCols = posCols.add(columns.eq(colPos));
  ageCols = ageCols.add(columns.eq(colAge))
});

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

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

    /* Loop through to check for teams */
    if (teams) {
      teamCols.each(function() {
        if (!this.innerHTML.toUpperCase().includes(teams)) {
          $(this).parent().hide();
        }
      });
    }

    /* Loop and check for min GP */
    GPCols.each(function() {
      if ( Number(this.innerHTML) < minGP) {
        $(this).parent().hide();
      }
    });

    /* Check for age requirement */
    if (age) {
      age = Number(age)
      ageCols.each(function() {
        thisAge = Number(this.innerHTML);
        if ( thisAge < age || thisAge >= age+1 ) {
          $(this).parent().hide();
        }
      });
    }

    /* Check the position requirement */
    if (position) {
      posCols.each(function() {
        var thisPos = this.innerHTML
        if (position == "D") {
          if (thisPos.indexOf("D") == -1) {
            $(this).parent().hide();
          }
        } else if (position == "F") {
          if (thisPos.indexOf("D") != -1) {
            $(this).parent().hide();
          }
        } else if (thisPos != position) {
          $(this).parent().hide();
        }
      });
    }

    autoRank();
}
var.each(function() { ... 函数中的

当我在Chrome或Firefox上运行它时,它会快速运行(低于1秒)并正确呈现DOM。当我在Safari上执行时需要30秒以上。

为什么这个以及我该怎么做以适应这个浏览器?

jQuery:1.11.1(即使在升级到3.1.1之后也是同样的问题)。

Safari:10.0.1
Firefox:50
Chrome:54.0。

1 个答案:

答案 0 :(得分:1)

从代码中删除所有重复和不必要的复杂功能后,剩下的就是:

var colRank = 0, colTeam = 1, colGP = 2, colAge = 3, colPos = 4;

function filterTable() {
    var minGP = +$("#mingp").val();
    var age = +$("#age").val();
    var teams = $("#teamFilter").val().toUpperCase();
    var position = $("#position").val();
    var rank = 0;

    $("#myTablePlayers .playerData").each(function () {
        if (
            (teams && this.cells[colTeam].textContent.toUpperCase().includes(teams)) ||
            (minGP && +this.cells[colGP].textContent < minGP) ||
            (age && (+this.cells[colAge].textContent < age || +this.cells[colAge].textContent >= age+1)) ||
            ((position === "D" || position === "F") && this.cells[colPos].textContent.indexOf(position) === -1) ||
            (!(position === "D" || position === "F") && (this.cells[colPos].textContent !== position))
        ) {
            this.cells[colRank].textContent = ++rank;
            this.style.display = "";
        } else {
            this.style.display = "none";
        }
    });
}

我已经删除了几乎所有的jQuery,转而支持本机DOM操作。

如果你想要挤出最后一点可能的表现,剩下的.each()可以调到for上的普通document.getElementById('myTablePlayers').tBodies[0].rows循环。

按可能性重新排序if条件:从通常过滤掉大多数行的那个到将过滤掉最少行的行。由于JS短路条件,这种方式总体上检查的条件较少。

制作table display: fixed也可以牺牲灵活性来提高渲染性能。

最后,您可以使用CSS to do counters。这可能比手动设置表格单元格的内容更快 。为自己测试。