![](/img/trans.png)
[英]Ordering of javascript execution (inline and external), IE vs. Firefox
[英]When should I use Inline vs. External Javascript?
我想知道在性能和易於維護方面,我什么時候應該包含外部腳本或將它們與 html 代碼內聯編寫。
這方面的一般做法是什么?
真實世界場景 - 我有幾個需要客戶端表單驗證的 html 頁面。 為此,我使用了一個包含在所有這些頁面上的 jQuery 插件。 但問題是,我是否:
謝謝。
在這個答案最初發布時(2008 年),規則很簡單:所有腳本都應該是外部的。 無論是維護還是性能。
(為什么是性能?因為如果代碼是分開的,它可以更容易地被瀏覽器緩存。)
JavaScript 不屬於 HTML 代碼,如果它包含特殊字符(例如<
、 >
),它甚至會產生問題。
如今,Web 的可擴展性已經發生了變化。 由於發出多個 HTTP 請求的延遲,減少請求數量已成為一個有效的考慮因素。 這使得答案更加復雜:在大多數情況下,仍然建議使用外部 JavaScript。 但對於某些情況,尤其是非常小的代碼片段,將它們內聯到站點的 HTML 中是有意義的。
可維護性絕對是將它們保持在外部的一個原因,但是如果配置是單行的(或者通常比將這些文件放在外部所獲得的 HTTP 開銷更短),那么將它們保持內聯在性能方面更好。 永遠記住,每個 HTTP 請求都會在執行時間和流量方面產生一些開銷。
當您的代碼長於幾行並且不是真正特定於一個頁面時,這一切自然變得無關緊要。 當您希望能夠重用該代碼時,將其設為外部。 如果你不這樣做,看看它的大小然后再決定。
如果你只關心性能,這個線程中的大部分建議都是錯誤的,並且在 SPA 時代變得越來越錯誤,我們可以假設沒有 JS 代碼的頁面是無用的。 我花了無數個小時來優化 SPA 頁面加載時間,並使用不同的瀏覽器驗證這些結果。 總體而言,通過重新編排您的 html 可以顯着提高性能。
為了獲得最佳性能,您必須將頁面視為兩級火箭。 這兩個階段大致對應於<head>
和<body>
階段,但可以將它們視為<static>
和<dynamic>
。 靜態部分基本上是一個字符串常量,您可以盡可能快地將其推入響應管道。 如果您使用大量設置 cookie 的中間件(這些需要在發送 http 內容之前設置),這可能有點棘手,但原則上它只是刷新響應緩沖區,希望在跳入某些模板代碼(razor、php、等)在服務器上。 這聽起來可能很難,但我只是解釋錯了,因為它幾乎微不足道。 您可能已經猜到了,這個靜態部分應該包含所有內聯和縮小的 javascript。 它看起來像
<!DOCTYPE html>
<html>
<head>
<script>/*...inlined jquery, angular, your code*/</script>
<style>/* ditto css */</style>
</head>
<body>
<!-- inline all your templates, if applicable -->
<script type='template-mime' id='1'></script>
<script type='template-mime' id='2'></script>
<script type='template-mime' id='3'></script>
由於通過網絡發送這部分內容幾乎不需要任何費用,因此您可以預期客戶端在連接到您的服務器后大約 5 毫秒 + 延遲時間開始接收此內容。 假設服務器合理關閉,此延遲可能在 20 毫秒到 60 毫秒之間。 瀏覽器一收到它就會開始處理它,處理時間通常比傳輸時間高出 20 倍或更多,這現在是服務器端處理<dynamic>
部分的分攤窗口。
瀏覽器(chrome,rest 可能慢 20%)處理內聯 jquery + signalr + angular + ng animate + ng touch + ng routes + lodash 大約需要 50 毫秒。 這本身就非常了不起。 大多數 Web 應用程序的代碼少於所有那些流行庫的總和,但假設您有同樣多的代碼,那么我們將在客戶端上贏得延遲 + 100 毫秒的處理(這個延遲勝利來自第二個傳輸塊)。 當第二個塊到達時,我們已經處理了所有的 js 代碼和模板,我們可以開始執行 dom 轉換。
您可能反對此方法與內聯概念正交,但事實並非如此。 如果您不是內聯,而是鏈接到 cdns 或您自己的服務器,則瀏覽器將不得不打開另一個連接並延遲執行。 由於此執行基本上是免費的(因為服務器端正在與數據庫對話),所以必須清楚所有這些跳轉的成本比根本不進行跳轉要高。 如果有一個瀏覽器怪癖說外部 js 執行得更快,我們可以衡量哪個因素占主導地位。 我的測量表明,額外的請求會降低此階段的性能。
我在 SPA 應用程序的優化方面做了很多工作。 人們通常認為數據量很重要,但實際上延遲和執行往往占主導地位。 我列出的縮小庫加起來有 300kb 的數據,這只是 68kb gzip 壓縮,或者在 2mbit 3g/4g 手機上下載 200ms,這正是在同一部手機上檢查是否有相同數據所需要的延遲已經在其緩存中,即使它是代理緩存的,因為移動延遲稅(電話到塔延遲)仍然適用。 同時,具有較低第一跳延遲的桌面連接通常無論如何都具有較高的帶寬。
簡而言之,現在(2014 年),最好內聯所有腳本、樣式和模板。
編輯(2016 年 5 月)
隨着 JS 應用程序的不斷增長,我的一些有效負載現在堆疊到 3 兆字節以上的縮小代碼,很明顯至少不應再內聯公共庫。
外部化 javascript 是雅虎性能規則之一:http: //developer.yahoo.com/performance/rules.html#external
雖然您應該始終外部化腳本的硬性規定通常是一個不錯的選擇,但在某些情況下您可能希望內聯一些腳本和樣式。 但是,您應該只內聯您知道會提高性能的東西(因為您已經對此進行了測量)。
我認為特定於一頁的短腳本案例(僅)是內聯腳本的防御案例
應始終使用外部腳本的另一個原因是為了更容易過渡到內容安全策略 (CSP) 。 CSP 默認禁止所有內聯腳本,使您的站點更能抵抗 XSS 攻擊。
我會看一下所需的代碼,並根據需要將其分成盡可能多的單獨文件。 每個 js 文件只會包含一個“邏輯集”的功能等。 所有登錄相關功能的一個文件。
然后在每個 html 頁面上的網站開發過程中,您只包括需要的那些。 當您開始使用您的網站時,您可以通過將頁面需要的每個 js 文件合並到一個文件中來進行優化。
我可以為內聯 javascipt 提供的唯一防御是,在將強類型視圖與 .net MVC 一起使用時,您可以在我發現有用的 javascript 中引用 c# 變量。
三個注意事項:
關於將 JavaScript 保持在外部:
ASP.NET 3.5SP1 最近引入了創建復合腳本資源的功能(將一堆 js 文件合並為一個)。 這樣做的另一個好處是,當打開 Web 服務器壓縮時,下載一個稍大的文件將比許多較小的文件有更好的壓縮率(也更少的 http 開銷、往返等...)。 我想這可以節省初始頁面加載時間,然后瀏覽器緩存就會像上面提到的那樣啟動。
除了 ASP.NET,這個截屏視頻更詳細地解釋了好處: http ://www.asp.net/learn/3.5-SP1/video-296.aspx
使用 Firebug 也更容易調試外部腳本。 我喜歡對我的 JavaScript 進行單元測試,並讓所有外部幫助。 我討厭在 PHP 代碼和 HTML 中看到 JavaScript,這對我來說是一團糟。
外部腳本的另一個隱藏好處是您可以輕松地通過jslint等語法檢查器運行它們。 這可以使您免於遇到許多令人心碎的、難以發現的 IE6 錯誤。
在您的場景中,聽起來將外部內容寫在頁面之間共享的一個文件中對您有好處。 我同意上面所說的一切。
在早期原型制作期間,為了快速迭代的好處,請保持代碼內聯,但一定要在生產時將其全部放在外部。
我什至敢說,如果你不能把你所有的 Javascript 放在外部,那么你手下的設計就很糟糕,你應該重構你的數據和腳本
Google 已將加載時間納入其頁面排名測量中,如果您內聯很多,蜘蛛將需要更長的時間來抓取您的頁面,如果您必須包含很多內容,這可能會影響您的頁面排名。 在任何情況下,不同的策略都可能影響您的排名。
好吧,我認為在制作單頁網站時應該使用內聯,因為腳本不需要跨多個頁面共享
擁有內部 JS 專業人員:更容易管理和調試您可以看到發生了什么
內部 JS 缺點:人們可以改變它,這真的會讓你煩惱。
外部 JS 專業人士:不改變周圍你可以看起來更專業(或者至少我是這么認為的)
外部 JS 缺點:更難管理,很難知道發生了什么。
始終嘗試使用外部 Js,因為內聯 js 總是難以維護。
而且,專業要求你使用外部js,因為大多數開發人員建議使用外部js。
我自己使用外部js。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.