簡體   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