么是JS延遲加載?
JS延遲加載,也就是等頁面加載完成之后再加載JavaScript文件
為什么讓JS實現延遲加載?
js的延遲加載有助于提高頁面的加載速度。
Js延遲加載的方式有哪些?一般有以下幾種方式:
·defer屬性
·async屬性
·動態創建DOM方式
·使用jQuery的getScript方法
·使用setTimeout延遲方法
·讓JS最后加載
HTML 4.01為<script>標簽定義了defer屬性。標簽定義了defer屬性元素中設置defer屬性,等于告訴瀏覽器立即下載,但延遲執行標簽定義了defer屬性。
用途:表明腳本在執行時不會影響頁面的構造。也就是說,腳本會被延遲到整個頁面都解析完畢之后再執行在<script>元素中設置defer屬性,等于告訴瀏覽器立即下載,但延遲執行
<!DOCTYPE html>
<html>
<head>
<script src="test1.js" defer="defer"></script>
<script src="test2.js" defer="defer"></script>
</head>
<body>
<!--這里放內容-->
</body>
</html>
說明:雖然<script>元素放在了<head>元素中,但包含的腳本將延遲瀏覽器遇到</html>標簽后再執行HTML5規范要求腳本按照它們出現的先后順序執行。在現實當中,延遲腳本并不一定會按照順序執行defer屬性只適用于外部腳本文件。支持HTML5的實現會忽略嵌入腳本設置的defer屬性
HTML5 為<script>標簽定義了async屬性。與defer屬性類似,都用于改變處理腳本的行為。同樣,只適用于外部腳本文件。標簽定義了async屬性。與defer屬性類似,都用于改變處理腳本的行為。同樣,只適用于外部腳本文件。
目的:不讓頁面等待腳本下載和執行,從而異步加載頁面其他內容。異步腳本一定會在頁面 load 事件前執行。不能保證腳本會按順序執行
<!DOCTYPE html>
<html>
<head>
<script src="test1.js" async></script>
<script src="test2.js" async></script>
</head>
<body>
<!--這里放內容-->
</body>
</html>
async和defer一樣,都不會阻塞其他資源下載,所以不會影響頁面的加載。
缺點:不能控制加載的順序
//這些代碼應被放置在</ body>標簽前(接近HTML文件底部)
<script type="text/javascript">
function downloadJSAtOnload() {
varelement = 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>
$.getScript("outer.js" , function(){ //回調函數,成功獲取文件后執行的函數
console.log(“腳本加載完成")
});
<script type="text/javascript" >
function A(){
$.post("/1ord/1ogin" ,{name:username,pwd:password},function(){
alert("Hello");
});
}
$(function (){
setTimeout('A()', 1000); //延遲1秒
})
</script>
把js外部引入的文件放到頁面底部,來讓js最后引入,從而加快頁面加載速度例如引入外部js腳本文件時,如果放入html的head中,則頁面加載前該js腳本就會被加載入頁面,而放入body中,則會按照頁面從上倒下的加載順序來運行JavaScript的代碼。所以我們可以把js外部引入的文件放到頁面底部,來讓js最后引入,從而加快頁面加載速度。
上述方法2也會偶爾讓你收到Google頁面速度測試工具的“延遲加載javascript”警告。所以這里的解決方案將是來自Google幫助頁面的推薦方案。
//這些代碼應被放置在</body>標簽前(接近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>
這段代碼意思等到整個文檔加載完后,再加載外部文件“defer.js”。
使用此段代碼的步驟:
6.1)復制上面代碼
6.2)粘貼代碼到HTML的標簽前 (靠近HTML文件底部)
6.3)修改“defer.js”為你的外部JS文件名
6.4)確保文件路徑是正確的。例如:如果你僅輸入“defer.js”,那么“defer.js”文件一定與HTML文件在同一文件夾下。
注意:
這段代碼直到文檔加載完才會加載指定的外部js文件。因此,不應該把那些頁面正常加載需要依賴的javascript代碼放在這里。而應該將JavaScript代碼分成兩組。一組是因頁面需要而立即加載的javascript代碼,另外一組是在頁面加載后進行操作的javascript代碼(例如添加click事件。
部分前端工程師入門的理由是:前端好上手,在最初學習的時候,甚至不需要 IDE 就可以開始 coding 了。但隨著對語言的深入,也會慢慢了解到為什么做前端經常被后端“鄙視”,更深一層次的是,為什么 JavaScript 這門語言常常也會被鄙視。
JavaScript 從設計之初,就是很隨性的:隨性的作用域、隨性的變量聲明....雖然隨著語言不斷的升級,很多問題都可以用新的語法和特性規避了,但是實際開發起來,由于開發者的自我約束低甚至是不自知,寫出來的代碼還是會出現一些性能問題的——一不小心,就會讓 JavaScript 變慢。
接下來我會分享一些實際開發中的小技巧,目的是讓 JavaScript 跑得更快~
當一個變量被引用時,JavaScript 會沿著作用域鏈逐級向下查找它。在這個作用域鏈中,通常都會包含一些可訪問的局部變量,還有一些幾乎所有主流瀏覽器都實現了的全局變量。JavaScript 引擎會首先查找掛載到當前作用域下和以函數參數形式傳遞進來的局部變量,然后是定義在函數作用域/塊級作用域內的局部變量,最后去遍歷查找全局變量。簡而言之,需要訪問變量所在的作用域鏈越深,代碼執行時的耗時就越長。
局部變量總是第一個被查找的,也就是說,局部變量總是最快被查找到的,因此,當你需要多次使用一個全局變量時,最直接的優化方式就是將它定義成為局部變量,like this:
// 優化前 const div = document.querySelector('#div') const images = document.querySelectorAll('img') // 優化后 const doc = document const div = doc.querySelector('#div') const images = doc.querySelectorAll('img');
眾所周知,with() 語句是個魔鬼。這是因為它會把一坨額外的變量掛到作為參數的作用域上,這意味著每當任何一個變量被使用到時,JavaScript 引擎首先會將 with() 中的作用域遍歷一遍,然后才是各個局部變量及全局變量,也就是說,有了它的存在,引擎查找變量的路勁就會不可避免的變長,進而降低了 JavaScript 執行時的性能。
閉包是 JavaScript 中很實用的一個特性,但它是一把雙刃劍,自打出生起就有著性能上的缺陷。
大部分時候你可能沒察覺自己用到了閉包,但實際上,你確實已經寫了不少了,比如:
document.querySelector('#div').onclick = function(ev) { console.log('Hello Closure'); }
在定義一個閉包時,它的問題就出現了,閉包會使得函數中的變量都保存在內存中,對內存造成很大的消耗。即便如此,閉包仍是一個很有用的語言特性,在多數場景下能為開發者提供便利并且提高代碼的可讀性,所以,閉包雖好,可不要貪杯哦。
當談及 JavaScript 數據時,最常見的有四種表達形式:字面量、變量、對象屬性和數組項。如果從性能層面考量,字面量和變量相差無幾,但都明顯快過對象屬性和數組項。
所以,當你需要多次讀取/賦值同一個對象屬性或數組項時,可以通過定義普通變量來提高代碼的性能。
雖然 Firefox 搞了一些事情,讓數組的存取效率超過了普通變量,但如果你的用戶們并不完全是 Firefox 的忠實粉絲,還是乖乖的遵循這條規則吧。
在日常開發中,尤其是和后端同學定數據協議時,要盡量避免多維數組的出現。道理也很簡單,層級越深,操作越慢。簡而言之,數組的讀取本身就不是一件很快的事情,再搞個多維數組那可就更慢了。
都 9102 年了,遍歷一個對象的時候還在用 for-in?for-in 會遍歷指定對象及其原型鏈上的所有可枚舉屬性,也就是說,由于總是干一些多余的事情,會導致這行遍歷代碼慢下來,就算用 hasOwnProperty 得出了預期的結果,但...它還是會去遍歷那些繼承來的屬性呀(攤手)
于是乎,我建議采用這樣的寫法(我平時就是這么干的):
const keys = Object.keys(obj); for (const key of keys) { console.log(obj[key]); }
Object.keys() 天生就是用來遍歷一個對象自身的所有可枚舉屬性,并且以數組的形式返回,這樣就不用擔心遍歷的時候做了一些拖慢性能的無用功了。
一時間也想不到其他的了,如果你有一些別的技巧可以分享,不妨貼在評論區,一起學習進步喔
者:Tam Hanna
轉發鏈接:https://www.creativebloq.com/how-to/21-ways-to-optimise-your-css-and-speed-up-your-site
*請認真填寫需求信息,我們會在24小時內與您取得聯系。