簡介
延緩執行 JavaScript 是一個能有效提升網頁加載速度以及提高用戶閱讀體驗質量的途徑。從實際經驗來看,將咱們的網站從經濟實惠的 VPS 遷移到 Softlayer(美國著名的一個數據中心)獨立服務器平臺上只能給網站加載速度帶來20%的提高,可是經過延緩執行 JavaScript 卻能幫助提速 50% ,不妨看看 Google Webmaster 工具 > Site Performance(網站性能)的統計結果:
javascript
實戰
網頁開發遵循一個假設,就算有 JS 文件忽然被中斷了,只要沒有 JS 執行錯誤,那網頁就必定會被正確渲染。簡單的說,延緩執行 JS 能夠採起下面兩種規則:java
- 等到頁面 Document 準備好以後再來執行內聯的 JS 代碼,這些代碼至少也得放在頁面底部。
- 動態地加載外部 JavaScript 文件。若是多個 JS 文件之間存在依賴,確保主要的 JS 文件引用寫在網頁底部以便最後加載。
下面這個主頁面的代碼片斷指出了咱們如何在開發中延緩 JavaScript 的執行。
1 |
< script type = "text/javascript" >// <![CDATA[ |
2 |
_lazyLoadScripts = new Array(); |
3 |
_lazyExecutedCallbacks = new Array(); |
5 |
< script type = "text/javascript" src = "/scripts/jquery-1.4.4.min.js" ></ script > |
6 |
< script type = "text/javascript" src = "/scripts/website-lazy-load.js" ></ script > |
在開發中常常會有些嵌套網頁或者構件須要依賴一些外部 JS 文件或 JS 代碼的執行。在這種狀況下,能夠像上面例子那樣在主頁面頂部定義兩個變量 「_lazyLoadScripts」 和 「_lazyExecutedCallbacks」 。
在下面代碼片斷中,你能夠看到這兩個變量是如何被使用在嵌套網頁或構件上的。jquery
01 |
<script type= "text/javascript" > // <![CDATA[ |
02 |
_lazyExecutedCallbacks.push( function () |
04 |
// in the case you need to execute some scripts in a nested page or module. |
05 |
// don't execute them explicitly, but push them into the callback list. |
08 |
<script type= "text/javascript" > // <![CDATA[ |
09 |
// push the external JS files into the list for deferring loading. |
10 |
_lazyLoadScripts.push( "/scripts/your-script.js" ); |
這些被壓入(push)到 「_lazyExecutedCallbacks」 裏的 JS 代碼和被插入到 「_lazyLoadScripts」 裏的外部 JS 文件所有都會在 「website-lazy-load.js」 裏被執行,執行的代碼片斷以下:
01 |
// dynamically load external JS files when document ready |
02 |
// dynamically load external JS files when document ready |
03 |
function loadScriptsAfterDocumentReady() |
05 |
if (_lazyLoadScripts && _lazyLoadScripts != null ) |
07 |
for ( var i = 0; i < _lazyLoadScripts.length; i++) |
09 |
var scriptTag = document.createElement( 'script' ); |
10 |
scriptTag.type = 'text/javascript' ; |
11 |
scriptTag.src = _lazyLoadScripts[i]; |
12 |
var firstScriptTag = document.getElementsByTagName( 'script' )[0]; |
13 |
firstScriptTag.parentNode.insertBefore(scriptTag, firstScriptTag); |
18 |
// Execute the callback when document ready. |
19 |
function invokeLazyExecutedCallbacks() |
21 |
if (_lazyExecutedCallbacks && _lazyExecutedCallbacks.length > 0) |
22 |
for ( var i=0; i<_lazyExecutedCallbacks.length; i++) |
23 |
_lazyExecutedCallbacks[i](); |
26 |
// execute all deferring JS when document is ready by using jQuery. |
27 |
jQuery(document).ready( function () |
29 |
loadScriptsAfterDocumentReady(); |
30 |
invokeLazyExecutedCallbacks(); |
小貼士
- 開發網頁的合理步驟應該是首先編寫 HTML 和 CSS 。等這些網頁在瀏覽器裏可以正確地(符合你的指望)被渲染出來以後,再開始編寫 JS 代碼來支持動畫或者其餘的效果。
- 不要在 HTML 頁面上的任何一個元素上編寫 onclick="..." 代碼來綁定事件,可是能夠在 HTML Document 都準備好的狀況下進行綁定。這樣能夠避免在 JS 文件加載完成以前因用戶觸發了 onclick 事件而致使的 JS 錯誤。
- 若是你的網站須要普遍地加載外部 JS 文件,那麼將它們寫在 「website-lazy-load.js」 裏動態的加載進來,例如 Google Analytics tracking 的JS 文件、 Google AdSense 的JS 文件等等。
- 這種方法一樣地對 CSS 文件也有效。可是別對 主CSS 文件這麼作。