繁体   English   中英

我将所有内容保存在一个外部.js文件中。 但并非所有功能都在每个页面上使用。 这会影响速度吗?

[英]I keep everything in an external .js file. But not all functions are used on every page. Does this affect speed?

我的应用程序的JavaScript / jQuery包含在一个外部scripts.js文件中。 通常看起来像这样:

$('document').on('ready', function() {
    giraffe();
    elephant();
    zebra();
});

function giraffe() {
    // code
}

function elephant() {
    // code
}

function zebra() {
    // code
}

giraffe()仅用于/animal/giraffe可用的视图
elephant()仅用于/animal/elephant可用的视图
zebra()仅用于/animal/zebra的视图,

但是所有这3个都应该在可用的/animal/all视图上运行。 这是一个简单的示例,但这是将它们全部保存在一个.js文件中的原因,除了将HTTP请求保持在最低限度之外。

我的问题是,这会影响JavaScript渲染吗? 即使未在/animal/zebra上使用giraffe() (没有要处理的元素),仍在调用它。 如果JS / jQuery没有任何作用,它会忽略该函数吗? 我确定已读取整个脚本,这可能需要时间。 那么,处理此问题的最佳方法是什么?

一种解决方案

为了避免冲突,我在js文件的顶部创建了条件语句,以仅运行活动页面所需的功能:

$('document').on('ready', function() {
    var body = $('body');

    if( body.hasClass('giraffe') ) {
        giraffe();
    }

    if( body.hasClass('elephant') ) {
        elephant();
    }

    if( body.hasClass('zebra') ) {
        zebra();
    }
});

这比我想要的更为冗长,但是可以成功地使这些功能保持模块化/无冲突。 我欢迎对此解决方案进行改进。

当然,只运行所需的代码会更好。 这并不困难; 唯一的次要复杂性是处理/animals/all情况。 如果要将所有代码保存在一个文件中,可以采用以下方式:

var animals = {
    giraffe: function() {
        console.log( "I'm a giraffe" );
    },
    elephant: function() {
        console.log( "I'm an elephant" );
    },
    zebra: function() {
        console.log( "I'm a zebra" );
    }
};

$(function() {
    var animal = location.pathname.split('/').pop();
    if( animal == 'all' ) {
        for( var animal in animals ) {
            animals[animal]();
        }
    }
    else if( animal in animals ) {
        animals[animal]();
    }
    else {
        console.log( "I'm a mystery animal" );
    }
});

您实际上可以通过在Stack Overflow上转到如下所示的URL来测试该代码,然后将该代码粘贴到JavaScript控制台中:

https://stackoverflow.com/animal/giraffe
https://stackoverflow.com/animal/elephant
https://stackoverflow.com/animal/zebra
https://stackoverflow.com/animal/ocelot
https://stackoverflow.com/animal/all

更新:好的,因此您在评论中解释了实际情况要复杂一些。 如果对任何人都有用,我将在此处保留此代码,但是对于您的情况,您可能更接近于已经拥有的代码所需要的内容。

WRT的问题是,当您在与页面无关的页面上使用哪种动物功能时,当然取决于它的编码方式。 它可能无法成功执行任何操作,或者可能有错误,对吧?

由于我们在谈论jQuery代码,因此这里有两个示例。 假设您有按ID查找元素的代码,然后假定该元素存在:

var zebraElement = $('#zebra')[0];
console.log( zebraElement.value );

#zebra元素存在的页面上,此代码将记录其value属性。 (我为讨论起见,它是一个具有值的元素,例如输入元素。)

但是,如果#zebra不存在,那么zebraElementundefined ,并且attemping访问其value在调试器将失败和土地。

OTOH,如果您这样编码:

var $zebra = $('#zebra');
console.log( $zebra.val() );

如果缺少#zebra ,它不会失败,它将成功打印undefined而不会引起错误。

类似地,如果您有使用$().each() ,则当缺少元素时,它将通常不会失败地运行,因为它根本不会执行回调函数:

$('.animal').each( function( i, e ) {
    console.log( $(e).val() );
});

如果没有元素带有class="animal" ,则将永远不会到达console.log()调用。 因此没有错误,它什么也不做。

根据您的操作,这可能是一种完全合理的方法,它仅触发您需要的行为—只需确保您的代码通过不做任何事情即可处理丢失的DOM元素。

另外,请务必阅读nick的答案以获得更多见解。

还有一个更新…在注释中,您提到了在body元素上键入类名。 做到这一点的一种好方法类似于上面的代码示例。 您不需要为每个动物设置条件,只需一个循环和一个条件即可:

var animals = {
    giraffe: function() {
        console.log( "I'm a giraffe" );
    },
    elephant: function() {
        console.log( "I'm an elephant" );
    },
    zebra: function() {
        console.log( "I'm a zebra" );
    }
};

$(function() {
    var $body = $('body');
    for( var animal in animals ) {
        if( $body.hasClass(animal) ) {
            animals[animal]();
        }
    }
});

因此,例如,如果您具有<body class="giraffe zebra"> ,它将调用animals.giraffe()animals.zebra()函数。

实际上,这里有两个问题,一个是是否加载所有功能,另一个是是否运行所有功能。 Michael Geary在其他答案中已经很好地解决了有关是否全部运行它们(以及仅运行所需功能的一些解决方案)的问题。

那么,您应该全部加载它们吗? 您需要权衡下载更大文件所需的时间,而不是提出额外的http请求。 只有3个“组”的功能在3个页面之间共享(并且一个页面使用所有这些功能),并且当您希望用户定期更改页面时,我会使用一个文件。

一旦项目变得很大,您将需要使用requirejs之类的工具来管理脚本并异步加载它们。 异步加载js脚本会提高页面的速度(以及页面的感知速度),如果出现问题(尤其是第三方托管的脚本),您的页面将无法获得帮助。 您当然可以在没有库的情况下执行此操作:

使用HTML5:

<script async src="http://google.com/script.js"></script>

有上百万种使用纯JS异步加载的方式,一种方式是:

<script>
  var resource = document.createElement('script'); 
  resource.src = "//google.com/script.js";
  var script = document.getElementsByTagName('script')[0];
  script.parentNode.insertBefore(resource, script);
</script>

Javascript将忽略任何未“调用”的函数。 就是 如果您没有在/ elephant或/ all页面以外的任何页面上都不调用Elephant(),则它将永远不会使用,也不会给您带来任何错误。

但是,您可能不希望在不用于快速加载页面的页面上不显示功能。 考虑为某些页面分离JS文件,或者通过从诸如PHP之类的后端服务器加载某些JS脚本来确定需要哪些功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM