我需要让这个 jquery 运行得更快,我没有创建所有这些函数,但需要它们的方法,来对页面内容进行实时翻译。
因此,如果有任何关于重构以获得更好性能的建议,我将不胜感激,如下代码。
<小时/>/* function 1 read json into array */
/* function 2 loop through array */
/* function 3 replace text nodes based on data from looped array */
var en_lang = new Array();
var fr_lang = new Array();
var frca_lang = new Array();
var my_data = null;
var en_count = 1;
var fr_count = 1;
var frca_count = 1;
if(typeof(language) != "undefined"){
var language = 'frca';
}
function replaceText(oldText, newText, node){
node = node || document.body; // base node
var childs = node.childNodes, i = 0;
while(node = childs[i]){
if (node.nodeType == 3){ // text node found, do the replacement
if (node.textContent) {
node.textContent = node.textContent.replace(oldText, newText);
} else { // support to IE
node.nodeValue = node.nodeValue.replace(oldText, newText);
}
} else { // not a text mode, look forward
replaceText(oldText, newText, node);
}
i++;
}
}
function parsejSON(my_data) {
/* THIS PART GRABS DATA FROM TOP OF JSON FILE */
/* grab recordcount */
var recordcount = my_data.recordcount;
/* grab columnlist */
var columnlist = my_data.columnlist;
/* grab json data */
var json_data = my_data.data;
/* PUTS JSON DATA INTO ARRAYS */
for(var x = 0; x < recordcount; x++) {
var lng = json_data.lng[x];
var phrase = json_data.phrase[x];
if (lng == 'french') {
fr_lang[fr_count] = phrase;
fr_count = fr_count + 1;
}
if (lng == 'french canadian') {
frca_lang[frca_count] = phrase;
frca_count = frca_count + 1;
}
if (lng == 'english') {
en_lang[en_count] = phrase;
en_count = en_count + 1;
}
}
/* use a replacetext function above to replace all text */
for(var x = 0; x < en_lang.length; x++) {
var from = en_lang[x];
if (language == 'fr') {
var to = fr_lang[x];
}
if (language == 'frca') {
var to = frca_lang[x];
}
replaceText(from, to);
}
}
抱歉,不太确定如何发布代码,格式正确,在这种情况下请随意编辑我的帖子..
谢谢。
最佳答案
通过检查您的代码,我可以告诉您,您的最大开销是在 ReplaceText 函数中创建的。对于每个文本项,您的代码都会一次又一次地遍历整个 DOM 结构。代码不是一次性执行此操作,而是多次遍历文档 en_lang.length
次。节点操作比 JavaScript 代码慢得多,因此如果 en_lang 数组中有很多项并且文档结构很复杂,则渲染时间可能会急剧增加。通过在一个循环中替换所有文本项将节省大量时间。
第二。我可以看到,在每个节点上您都执行分配操作。
node.textContent = node.textContent.replace(oldText, newText);
如果您的节点不包含任何匹配信息,则此操作是多余的。通过仅在需要的地方进行 DOM 分配,您可以节省另一毫秒的渲染时间。
<罢工>第三。递归。非常有趣的话题。可以用,也可以不用。你更喜欢什么。但有时递归可能成为代码中的瓶颈。在这种情况下,replaceText 是一个递归操作,这会导致不必要的内存使用和 CPU 时间。您可以通过使用 getElementsByTagName 函数询问来一次性获取所有节点。
第四个:第一个 for 循环中“parseJson”内的“if”操作。我不知道为什么,但你没有使用if-else语句,而是简单的if。这意味着运行时应该遍历所有“if”语句,即使它已经找到了正确的语句。在这种情况下,为了 JavaScript 效率,最好使用“switch”语句而不是“if”或“if-else”。速度更快。
第五。现在让我们看看第二个“for”循环。您根本不应该使用任何 switch 或 if 语句。该部分中的“if”语句完全是多余的。您在 for 循环之前知道“语言”变量的值,因此您可以在 for 循环之前缓存“to”数组并使用已缓存的数组。
六:另一个小改进,而不是使用 frca_count = frca_count + 1;您可以只使用增量运算符:frca_count++。它还会加速代码。
七。在第二个“for:”语句中,您在条件部分使用 en_lang.length 。如果您查看前面的“for”循环,您可以看到它具有保存相同值的变量:“en_count”。使用它而不是 en_lang 。长度来加速 for 循环本身。
将这些结合在一起,我想出了这样的东西。
function parsejSON(my_data) {
/* THIS PART GRABS DATA FROM TOP OF JSON FILE */
/* grab recordcount */
var recordcount = my_data.recordcount;
/* grab columnlist */
var columnlist = my_data.columnlist;
/* grab json data */
var json_data = my_data.data;
/* PUTS JSON DATA INTO ARRAYS */
for(var x = 0; x < recordcount; x++) {
var lng = json_data.lng[x];
var phrase = json_data.phrase[x];
// ( conclusion # 4)
switch(lng){
case 'french':
// ( conclusion # 6)
fr_lang[fr_count++] = phrase;
break;
case 'french canadian':
frca_lang[frca_count++] = phrase;
break;
case 'english':
en_lang[en_count++] = phrase;
break;
}
}
/* use a replacetext function above to replace all text */
// ( conclusion # 5)
var toCache = (language == 'fr') ? fr_lang
: (language == 'frca' ? frca_lang : null);
// ( conclusion # x)
var content = function(node, txt){
if(txt){
if(node.textContent){
node.textContent = txt;
}else if(node.nodeValue){
node.nodeValue = txt;
}
}else{
return node.textContent ? node.textContent : node.nodeValue;
}
};
// recursive tree walker
(function(parent){
var childs = parent.childNodes;
if(childs && childs.length){
for(var i=0,node;node = childs[i];i++){
if(node.nodeType == 3){ // text node found, do the replacement
var value = content(node);
// ( conclusion # 7)
for(var x = 0; x < en_count; x++) {
var from = en_lang[x];
var to = toCache[x];
// ( conclusion # 2)
if(value.match(from)){
content(node, value.replace(from,to));
}
}
}else{
arguments.callee(node);
}
}
}
})(document.body);
}
我希望所有这些都可以解决问题。祝你好运
编辑:因为 getElementsByTagName("*") 不返回 #text 节点,所以我更改了解决方案以使用递归树遍历器。
关于javascript - 请帮我重构这个 jQuery 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2156638/