這裡介紹實務上延遲載入各種 JavaScript 的作法,包含 facebook、Google+ 與 twitter 等各類工具。
在網頁中我們可以使用 async
或 defer
的方式來引入外部的 JavaScript 檔案,這樣可以減輕外部 JavaScript 檔對 HTML 解析的效能影響,而這裡我們要介紹另一種在實務上延遲載入各種 JavaScript 程式碼的作法,包含常見的社群按鈕以及各種 JavaScript 工具,例如 facebook、Google+ 與 twitter 等。
若單純只是使用 defer
來引入 JavaScript 檔案的話,瀏覽器會在背景載入該 JavaScript 檔,然後在 HTML 解析完成後執行,雖然不會打斷 HTML 的解析,但是多少還是會佔用網路連線與頻寬,影響其他網頁元素的載入速度。
有另外一種作法是將這個 JavaScript 程式碼的內容貼在 </body>
之前,但是這樣做也是會有同樣的問題,它會在完整的網頁載入完成之前就先執行 JavaScript 的內容。
如果要讓 defer.js
這個 JavaScript 檔案盡可能延後載入,可以將下面這段 JavaScript 放置在 </body>
之前:
<script type="text/javascript"> function downloadJSAtOnload() { var element = document.createElement("script"); element.src = "defer.js"; document.body.appendChild(element); } if (window.addEventListener) window.addEventListener("load", downloadJSAtOnload, false); else if (window.attachEvent) window.attachEvent("onload", downloadJSAtOnload); else window.onload = downloadJSAtOnload; </script>
這樣的作法是在整個完整的網頁(包含網頁的圖片、CSS 與 JavaScript 檔)都載入完成之後,才使用 JavaScript 插入 defer.js 這個 JavaScript 檔,所以對整個網頁內容的影響是最小的。
我們可以利用這樣的作法,將許多不同來源的 JavaScript 程式全部放在一個 defer.js
中,這樣不僅可以讓程式碼更精簡,也可以減少連線數。
facebook 按鈕預設的 JavaScript 程式碼分為兩部份,第一個部份是 facebook 的 JavaScript SDK,官方建議放在 <body>
之後,而第二部份則是外掛程式顯示位置的 HTML 碼:
<!-- Facebook JavaScript SDK,放置在 body 中 --> <div id="fb-root"></div> <script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/zh_TW/sdk.js#xfbml=1&version=v2.6&appId=241371325930982"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));</script> <!-- 將此程式碼放置在你希望外掛程式顯示的頁面位置 --> <div class="fb-like" data-href="http://blog.gtwang.org/" data-layout="standard" data-action="like" data-show-faces="true" data-share="true"></div>
facebook 這種方式是讓瀏覽器在解析 HTML 時就直接載入並執行他的程式碼,這樣會直接影響網頁載入的速度,若要改善這個問題可以將這裡 <script>
裡面的 JavaScript 程式碼搬到剛剛我們上面介紹的 defer.js
中,而其餘的純 HTML 碼則維持不變,這樣就可以強制 facebook 的外掛程式在網頁完全載入之後才執行。
twitter 按鈕的程式碼分為兩部份,第一行是 HTML 碼,而第二行則是 JavaScript 碼:
<a href="https://twitter.com/share" class="twitter-share-button">Tweet</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
twitter 這種載入方式也是會影響 HTML 解析的,我們可以將這裡第二行的 JavaScript 程式碼移到上面介紹的 defer.js
中,而第一行的 HTML 碼則維持不變,這樣就可以改善網頁載入的問題。
Google Plus 所提供的程式碼本身就已經有使用 defer
的方式載入了,如果將它的 JavaScript 程式碼放在 </body>
之前的話,對網頁載入的影響就會比較小。
<!-- 將這個標記放在標頭中,或放在內文結尾標記前面。 --> <script src="https://apis.google.com/js/platform.js" async defer> {lang: 'zh-TW'} </script> <!-- 在您要顯示「+1 按鈕」的位置放上這個標記。 --> <div class="g-plusone" data-annotation="inline" data-width="300"></div>
如果要讓 Google Plus 的 JavaScript 程式碼完全不影響網頁的載入,可以修改上面的 downloadJSAtOnload
函數,仿照 defer.js
的載入方式,插入 Google Plus 用的 JavaScript 程式碼:
<script type="text/javascript"> function downloadJSAtOnload() { var element = document.createElement("script"); element.src = "defer.js"; document.body.appendChild(element); // 加入 Google Plus 用的 JavaScript var googlePlusJS = document.createElement("script"); googlePlusJS.src = "https://apis.google.com/js/platform.js"; googlePlusJS.innerHTML = "{lang: 'zh-TW'}"; document.body.appendChild(googlePlusJS); } if (window.addEventListener) window.addEventListener("load", downloadJSAtOnload, false); else if (window.attachEvent) window.attachEvent("onload", downloadJSAtOnload); else window.onload = downloadJSAtOnload; </script>
這樣一來 Google Plus 的 JavaScrit 對於網頁的效能影響又會降低一些。
以上我們介紹這些延遲載入 JavaScript 的方式,其實適用於各種 JavaScript 外掛程式,原則上就是只要碰到 inline 的 JavaScript 就直接放進 defer.js
中,從外部引入的 JavaScript 檔就仿照 defer.js
的方式載入。
參考資料:varvy.com