正常網頁的加載流程:css
<script>
元素,就暫停解析,把網頁渲染的控制權轉交給 JavaScript 引擎。<script>
元素引用了外部腳本,就下載該腳本再執行,不然就直接執行代碼。上述加載方式爲同步加載,會阻塞瀏覽器的解析html文檔。故而咱們常將script元素放置於body的底部html
三種實現方式:動態腳本、async、deferjava
動態建立script標籤webpack
var scriptEle = document.createElement("script");
scriptEle.type = "text/javasctipt";
scriptEle.async = true;
scriptEle.src = "http://xxxxxxx";
var x = document.getElementsByTagName("head")[0];
x.insertBefore(scriptEle, x.firstChild);
複製代碼
async
屬性和defer
屬性相似,也是會開啓一個線程去下載js文件,但和defer
不一樣的時,它會在下載完成後馬上執行,而不是會等到DOM加載完成以後再執行,因此仍是有可能會形成阻塞。web
且不會按照順序執行,哪一個js文件先下載完就先執行哪一個gulp
對於內聯腳本無做用 (即沒有src屬性的腳本)。後端
當瀏覽器遇到帶有defer
屬性的<script>
標籤時,再開啓一個線程去下載js文件,同時繼續解析HTML文檔,等等HTML所有解析完畢DOM加載完成以後,再按照出現順序依次執行加載好的js文件。瀏覽器
對於內聯腳本無做用 (即沒有src屬性的腳本)。緩存
通常來講,是看腳本之間是否有依賴關係,有依賴的話應當要保證執行順序,應當使用defer
沒有依賴的話使用async
,同時使用的話defer
失效。要注意的是二者都不該該使用document.write,這個致使整個頁面被清除。服務器
優勢:
瀏覽器緩存分爲強緩存和協商緩存
若是資源沒過時,就取緩存,若是過時了,則請求服務器。
**cache-control:max-age = xxx **
聲明該資源在加載後的xxx秒內都直接使用緩存 使用的是相對時間 即加載文件本機的時間
expires: 絕對時間,服務器基於本身的時間返回一個文件過時時間
若是在Cache-Control
響應頭設置了 "max-age" 或者 "s-max-age" 指令,那麼 Expires
頭會被忽略。
強緩存步驟:
觸發條件:
也就是說,無論怎樣,均可能最後要進行協商緩存(no-store除外)
ETag:每一個文件有一個,改動文件了就變了,能夠看似md5
Last-Modified:文件的修改時間
每次http返回來 responseheader 中的 ETag和 Last-Modified,在下次請求時在 requestheader 就把這兩個帶上(可是名字變了ETag-->If-None-Match,Last-Modified-->If-Modified-Since ),服務端把你帶過來的標識,資源目前的標識,進行對比,而後判斷資源是否更改了。
協商緩存步驟總結:
預解析的實現:
用meta信息來告知瀏覽器, 當前頁面要作DNS預解析:
<meta http-equiv="x-dns-prefetch-control" content="on" />
複製代碼
在頁面header中使用link標籤來強制對DNS預解析:
<link rel="dns-prefetch" href="http://bdimg.share.baidu.com" />
複製代碼
注:dns-prefetch需慎用,多頁面重複DNS預解析會增長重複DNS查詢次數。
若是須要禁止隱式的 DNS Prefetch,可使用如下的標籤:
<meta http-equiv="x-dns-prefetch-control" content="off">
複製代碼
在瀏覽器中a標籤默認打開DNS預解析,可是在HTTPS中默認關閉
網絡請求的過程走最近的網絡環境,解決網絡擁堵。