javascript - 请帮我重构这个 jQuery 代码

标签 javascript json translation

我需要让这个 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/

相关文章:

javascript - 想要将函数参数传递到 JavaScript 中的 setTimeout 调用的最佳方式的模式

asp.net - 从 MVC 中的 Controller 返回 JSON 中的部分 View

php - 如何强制 gettext 独立于当前语言翻译特定语言?

Symfony:为什么方法 $this->get() 在构造函数中不可用?

architecture - React/Redux 和多语言(国际化)应用程序 - 架构

javascript - 这是立即调用的函数表达式吗?

javascript - 在 Javascript 中让一个函数与另一个函数配合

javascript - 当水 visibility 关闭时,谷歌会在景观上绘制奇怪的多边形

javascript - 如何在javascript中更新json的属性值

javascript - 通过 UI 过滤 JSON 对象数组