【问题标题】:JavaScript code improvementJavaScript 代码改进
【发布时间】:2009-12-02 02:18:56
【问题描述】:

我不是一个伟大的 JavaScript 性能专家。只是想知道,我可以让下面的代码更紧凑吗?不像打包或压缩它,而是它的编写方式。

(function() {
    var jq = document.createElement('script');
    var an = document.createElement('script');
    var cm = document.createElement('script');
    var ga = document.createElement('script');
    var domain = 'http://example.com/';

    jq.src = domain + 'jquery.1.3.2.js';
    an.src = domain + 'jquery.alphanumeric.js';
    cm.src = domain + 'common.js';
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    ga.setAttribute('async', 'true');

    document.documentElement.firstChild.appendChild(jq);
    document.documentElement.firstChild.appendChild(cm);
    document.documentElement.firstChild.appendChild(an);
    document.documentElement.firstChild.appendChild(ga);
})();

干杯!

【问题讨论】:

    标签: javascript asynchronous performance


    【解决方案1】:

    其编写方式的紧凑性与性能无关。但是要以更紧凑、可重用的方式编写它:

    function appendScript(url, async) {
        var el = document.createElement('script'),
            root = document.documentElement;
        el.async = async;
        el.src = url;
        // avoid an IE6 bug by using insertBefore (http://bugs.jquery.com/ticket/2709)
        root.insertBefore(el, root.firstChild);
    }
    
    
    appendScript('http://example.com/js/jquery.1.3.2.js', false);
    appendScript('http://example.com/js/jquery.alphanumeric.js', false);
    appendScript('http://example.com/js/common.js', false);
    appendScript(('https:' == document.location.protocol ? '//ssl' : '//www') + '.google-analytics.com/ga.js'), true);
    

    【讨论】:

    • +1 但很挑剔,可能值得为域使用变量
    • 你肯定希望域是一个变量——这个重构增加了不灵活性。
    • 确定吗?正如盛宴所说,它“可能”是值得的。在我看来,这是一个简单的问题遇到了一个简单的解决方案。使域成为变量会增加复杂性(尽管很小)并降低性能而实际上没有任何好处(节省几个字节的带宽?)。
    • 我会“肯定地”退出——很好,但是如果您需要在开发服务器或本地服务器上使用它,则需要重写。当然,您可以搜索和替换,但将其作为变量便于其他开发人员进行修改。
    • 好点,如果这是脚本 URL 可能只是相对的问题。
    【解决方案2】:
    'https:' == document.location.protocol ? 'https://ssl' : 'http://www'
    

    可以变成:

    'http' + 'https:'==document.location.protocol ? 's://ssl' : '://www'
    

    这是我能看到的唯一改进,除非你愿意使用非标准的 javascript,而不是创建元素,而是将实际的 html 元素转换为字符串,然后将其附加到文档 .innerHTML

    【讨论】:

    • 有趣。我只是想知道是否有一种方法可以组合 var 或所有 dom 指令。我想那时不会:)
    【解决方案3】:
    var child1 = document.documentElement.firstChild;
    child1.appendChild(jq);
    child1.appendChild(cm);
    child1.appendChild(an);
    child1.appendChild(ga);
    

    【讨论】:

      【解决方案4】:

      您可以创建一个 addScriptElement() 函数来减少这种重复。

      【讨论】:

        【解决方案5】:

        好的,这是我的想法。不确定它现在能节省多少,但如果你最终在example.com 上拥有更多资产,它会加快速度。

        (function(){
            var scripts    = ['jquery.1.3.2', 'jquery.alphanumeric', 'common'],
                head       = document.documentElement.firstChild,
                domain     = 'http://example.com/',
                add_script = function(url, async){
                    var script = document.createElement('script');
                    script.src = url;
                    if(async === true) script.setAttribute('async', 'true');
                    head.appendChild(script);
                };
        
            for(script in scripts) add_script( domain + scripts[script] + '.js' );
        
            add_script( ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js', true);
        })();
        

        【讨论】:

          【解决方案6】:

          这是一种方法。希望这可以直接添加或删除脚本(需要或不需要 async 属性:

          ({
              DOMAIN : 'http://example.com/',
              SCRIPTS : [ {file:'jquery.1.3.2.js'},
                      {file:'jquery.alphanumeric.js'},
                      {file:'common.js'},
                      {file: ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'
                          , async: 'true'} ],
              init: function() {
                  for (var i in this.SCRIPTS) {
                      var script = this.SCRIPTS[i];
                      var sc = document.createElement('script');
                      sc.src = (script.file.match(/^http/gi)) ? sc.src = script.file : sc.src = this.DOMAIN + script.file;
                      if (typeof script.async !== 'undefined') {
                          sc.setAttribute('async', script.async);
                      }
                      document.documentElement.firstChild.appendChild(sc);
                  }
          
              }
          }).init();
          

          【讨论】:

            【解决方案7】:

            我确信这会因为“臃肿”而被否决,但只是分享一下我会怎么做:

            首先,我将定义这样一个高度可扩展的函数:

            function addElements(objlist) {
                // One or many
                objlist = [].concat(objlist);
            
                while(objlist.length > 0) {
                    var current = objlist.pop();
            
                    var node = document.createElement(current.element || 'div');
                    for(attr in current.attributes)
                        node.setAttribute(attr, current.attributes[attr]);
            
                    if(current.parent)
                        current.parent.appandChild(node);
                }
            }
            

            然后,使用它:

            addElements([
                {
                    parent: document.documentElement.firstChild,
                    element: 'script',
                    attributes: {
                        src: 'http://example.com/jquery.1.3.2.js'
                    }
                },
                {
                    parent: document.documentElement.firstChild,
                    element: 'script',
                    attributes: {
                        src: 'http://example.com/jquery.alphanumeric.js'
                    }
                },
                {
                    parent: document.documentElement.firstChild, 
                    element: 'script',
                    attributes: {
                        src: 'http://example.com/common.js'
                    }
                },
                {
                    parent: document.documentElement.firstChild, 
                    element: 'script',
                    attributes: {
                        src: ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js',
                        async: true
                    }
                }
            ]);
            

            这就是我所说的“幂函数”。它的可读性很高,即使有重复,也能用力量表达出来。

            您甚至可以自动创建对象:

            var elements = [
                'jquery.1.3.2.js',
                'jquery.alphanumeric.js',
                'common.js',
                ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'
            ];
            
            for(var i=0; i<4; ++i) {
                elements[i] = {
                    element: 'script',
                    parent: document.documentElement.firstChild,
                    attributes: {
                        src: 'http://example.com/' + elements[i]
                    }
                };
            }
            
            elements[3].attributes.async = true;
            
            addElements(elements);
            

            【讨论】:

            • 我不会投反对票的,但是为什么要为几行就可以完成的事情费那么大的劲呢?
            • 为了“权力”。我喜欢概括和编写可以做“一切”的函数。在这种特定情况下,这似乎是一个不好的例子,但它让我想编写和分享这样的方法。
            • 很高兴分享。在您的第一行中使用免责声明,您将不会获得任何反对票。当然不是来自我:P
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-01-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多