js實(shí)現(xiàn)延遲加載的幾種方法詳解
這是一個(gè)面試經(jīng)常問(wèn)到的問(wèn)題:js的延遲加載方法 (js的延遲加載有助于提高頁(yè)面的加載速度)
主要考察對(duì)程序的性能方面是否有研究,程序的性能是一個(gè)項(xiàng)目不斷地追求的,通常也是項(xiàng)目完成后需要長(zhǎng)期做的一件事情,像騰訊QQ依然對(duì)程序的性能不斷地做優(yōu)化,讓用戶的體驗(yàn)更好,性能優(yōu)化的核心思想就是快,可以預(yù)先準(zhǔn)備數(shù)據(jù)(如緩存的使用),可以按需獲取,可以分段獲取等都是常見的優(yōu)化手段。
解題思路 :
1.defer屬性
<script src="file.js" defer> </script>
瀏覽器會(huì)并行下載 file.js和其它有 defer 屬性的script,而不會(huì)阻塞頁(yè)面后續(xù)處理。defer屬性在IE 4.0中就實(shí)現(xiàn)了,超過(guò)10多年了!Firefox從 3.5 開始支持defer屬性 。
注:所有的defer腳本保證是按順序依次執(zhí)行的。
2.async屬性
<script src="file.js" async> </script>
async屬性是HTML5新增的。作用和defer類似,但是它將在下載后盡快執(zhí)行,不能保證腳本會(huì)按順序執(zhí)行。它們將在onload 事件之前完成。
Firefox3.6、Opera 10.5、IE 9和 最新的Chrome 和 Safari 都支持 async 屬性??梢酝瑫r(shí)使用 async 和 defer,這樣IE 4之后的所有IE 都支持異步加載。
3.動(dòng)態(tài)創(chuàng)建DOM方式 (使用的最多)
<script type="text/javascript"> function downloadJSAtOnload() { var element = document.createElement("script"); element.src = "defer.js"; document.body.appendChild(element); } if (window.addEventListener) //添加監(jiān)聽事件 window.addEventListener("load",downloadJSAtOnload, false); //事件在冒泡階段執(zhí)行 else if (window.attachEvent) window.attachEvent("onload",downloadJSAtOnload); else window.onload = downloadJSAtOnload; </script>
PS: 這里插一句addEventListener()
也是常考的知識(shí)點(diǎn)之一:
addEventListener() 方法用于向指定元素添加事件句柄。
使用 removeEventListener() 方法來(lái)移除 addEventListener() 方法添加的事件句柄。
語(yǔ)法:element.addEventListener(event, function, useCapture)
- event (必須)字符串,指定事件名。注意: 不要使用 “on” 前綴。 例如,使用 “click” ,而不是使用 “onclick”。
- function (必須)指定要事件觸發(fā)時(shí)執(zhí)行的函數(shù)。當(dāng)事件對(duì)象會(huì)作為第一個(gè)參數(shù)傳入函數(shù)。 事件對(duì)象的類型取決于特定的事件。例如, “click” 事件屬于 MouseEvent(鼠標(biāo)事件) 對(duì)象。
- useCapture (可選)布爾值,指定事件是否在捕獲或冒泡階段執(zhí)行?!総rue:事件句柄在捕獲階段執(zhí)行; false:默認(rèn),事件句柄在冒泡階段執(zhí)行】
<p>該實(shí)例使用 addEventListener() 方法來(lái)向按鈕添加點(diǎn)擊事件。</p> <button id="myBtn">點(diǎn)我</button> <p id="demo"></p> <script> document.getElementById("myBtn").addEventListener("click", function(){ document.getElementById("demo").innerHTML = "Hello World"; }); </script>
效果如圖:
4.使用Jquery的getScript()方法
$.getScript("outer.js",function(){//回調(diào)函數(shù),成功獲取文件后執(zhí)行的函數(shù) console.log("腳本加載完成") });
從源碼可以看出,這個(gè)方法最后還是調(diào)用了jQuery.ajax()
來(lái)請(qǐng)求了js文件的。
5.使用setTimeout延遲方法的加載時(shí)間
延遲加載js代碼,給網(wǎng)頁(yè)加載留出時(shí)間
<script type="text/javascript"> function A(){ $.post("/lord/login",{name:username,pwd:password},function(){ alert("Hello World!"); }) } $(function (){ setTimeout("A()",1000); //延遲1秒 }) </script>
6.讓js最后加載
例如引入外部js腳本文件時(shí),如果放入html的head中,則頁(yè)面加載前該js腳本就會(huì)被加載入頁(yè)面,而放入body中,則會(huì)按照頁(yè)面從上倒下的加載順序來(lái)運(yùn)行javascript的代碼~~~ 所以我們可以把js外部引入的文件放到頁(yè)面底部,來(lái)讓js最后引入,從而加快頁(yè)面加載速度。
上述方法5,6也會(huì)偶爾讓你收到Google頁(yè)面速度測(cè)試工具的“延遲加載javascript”警告。所以這里的解決方案將是來(lái)自Google幫助頁(yè)面的推薦方案。
//這些代碼應(yīng)被放置在</body>標(biāo)簽前(接近HTML文件底部) <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>
這段代碼意思是等到整個(gè)文檔加載完后,再加載外部文件“defer.js”。
使用此段代碼的步驟:
- 復(fù)制上面代碼
- 粘貼代碼到HTML的標(biāo)簽前 (靠近HTML文件底部)
- 修改“defer.js”為你的外部JS文件名
- 確保你文件路徑是正確的。例如:如果你僅輸入“defer.js”,那么“defer.js”文件一定與HTML文件在同一文件夾下。
注意:這段代碼直到文檔加載完才會(huì)加載指定的外部js文件。因此,不應(yīng)該把那些頁(yè)面正常加載需要依賴的javascript代碼放在這里。而應(yīng)該將JavaScript代碼分成兩組。一組是因頁(yè)面需要而立即加載的javascript代碼,另外一組是在頁(yè)面加載后進(jìn)行操作的javascript代碼(例如添加click事件或其他東西)。這些需等到頁(yè)面加載后再執(zhí)行的JavaScript代碼,應(yīng)放在一個(gè)外部文件,然后再引進(jìn)來(lái)。
若有不足請(qǐng)多多指教!希望給您帶來(lái)幫助!
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
相關(guān)文章
JavaScript基礎(chǔ)篇之變量作用域、傳值、傳址的簡(jiǎn)單介紹與實(shí)例
這篇文章介紹了變量的作用域,傳值,傳址的一些簡(jiǎn)單使用,有需要的朋友可以參考一下2013-06-06全面解析Bootstrap中tab(選項(xiàng)卡)的使用方法
這篇文章主要為大家全面解析Bootstrap中tab(選項(xiàng)卡)的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-06-06探討JavaScript語(yǔ)句的執(zhí)行過(guò)程
本文給大家介紹JavaScript語(yǔ)句的執(zhí)行過(guò)程的相關(guān)知識(shí),對(duì)js語(yǔ)句執(zhí)行過(guò)程的相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2016-01-01bootstrap側(cè)邊欄圓點(diǎn)導(dǎo)航
這篇文章主要為大家詳細(xì)介紹了bootstrap側(cè)邊欄圓點(diǎn)導(dǎo)航效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01人人網(wǎng)javascript面試題 可以提前實(shí)現(xiàn)下
JavaScript面試題要求:以下題目必須從一至四題中,選出三道題,使用原生代碼實(shí)現(xiàn),不可使用任何框架,第五題為選作題2012-01-01JavaScript偽數(shù)組和數(shù)組的使用與區(qū)別
這篇文章主要給大家介紹了關(guān)于JavaScript偽數(shù)組和數(shù)組使用與區(qū)別的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05一個(gè)非常全面的javascript URL解析函數(shù)和分段URL解析方法
本文詳細(xì)介紹了一個(gè)非常全面的javascript URL解析函數(shù),可以解析一個(gè)URL中的協(xié)議、主機(jī)、查詢字符串甚至錨鏈接,非常實(shí)用,一并總結(jié)了js自帶的分段URL解析方法,需要的朋友可以參考下2014-04-04微信小程序用swiper實(shí)現(xiàn)滑動(dòng)刻度尺
這篇文章主要為大家詳細(xì)介紹了微信小程序用swiper實(shí)現(xiàn)滑動(dòng)刻度尺,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06