運(yùn)行環(huán)境介紹:
- 瀏覽器可以通過(guò)訪問(wèn)鏈接來(lái)得到頁(yè)面內(nèi)容
- 通過(guò)繪制和渲染,顯示出頁(yè)面的最終樣子,有視覺(jué)效果的樣子
- 整個(gè)過(guò)程中,我們要考慮什么問(wèn)題 ? 如下:
問(wèn)題
1.從輸入url到得到HTML的詳細(xì)過(guò)程
2.window.onload和DOMContentLoaded的區(qū)別
3.性能優(yōu)化的幾個(gè)示例
知識(shí)點(diǎn)
1: 頁(yè)面加載過(guò)程
2: 性能優(yōu)化
3: 安全性
1: 頁(yè)面加載,渲染過(guò)程
- 加載資源的形式
- 輸入url(或跳轉(zhuǎn)頁(yè)面)加載HTML http://jianshu.com
- 加載 html 中的靜態(tài)資源
<img src = 'loding.jpg'>
加載一個(gè)資源的過(guò)程
(從輸入U(xiǎn)RL 到得到 html 的詳細(xì)過(guò)程)瀏覽器根據(jù) DNS 服務(wù)器解析得到與域名相對(duì)應(yīng)的 IP 地址 (輸入的域名會(huì)被解析成 IP的)
向這個(gè) IP 的機(jī)器發(fā)送 http(s) 請(qǐng)求
服務(wù)器收到,處理并返回 http 請(qǐng)求(返回的可能是一個(gè)html頁(yè)面,可能是一張圖片...)
瀏覽器得到返回的內(nèi)容
瀏覽器渲染頁(yè)面的過(guò)程
根據(jù) html 結(jié)構(gòu)生成 DOM Tree
根據(jù) css 生成 CSSOM
將 DOM 和 CSSOM 整合形成 RenderTree
根據(jù) RenderTree 開(kāi)始渲染和展示
遇到
<script>時(shí),會(huì)執(zhí)行script代碼并阻塞渲染script有權(quán)限改變dom結(jié)構(gòu)補(bǔ)充:為什么把
script標(biāo)簽放到body后面呢? 1: 因?yàn)?code>script標(biāo)簽會(huì)阻塞代碼的渲染,放在下面不會(huì)阻塞上面一些代碼的渲染,能讓頁(yè)面更快的出來(lái),能提升性能; 2: 放在下面, script 代碼能拿到上面所有的標(biāo)簽DOMContentLoaded 與window.onload區(qū)別
<body>
<p>test</p>
<p></p>
<p>test</p>
</body>
window.onloadListener('load',function(){
//頁(yè)面的全部資源加載完后才會(huì)執(zhí)行,包括圖片視頻等
})
window.onloadListener('load',function(){
// DOM 渲染完即開(kāi)始執(zhí)行,此時(shí)的圖片,視頻可能還沒(méi)有加載完
})
jQuory 和 zepto 使用的是 DOMContentLoaded;
2: 性能優(yōu)化
加載資源優(yōu)化
- 靜態(tài)資源的壓縮合并
- 靜態(tài)資源緩存
- 使用 CDN 讓資源加載更快
- 使用 SSr 后端渲染,數(shù)據(jù)直接輸出到 html 中
渲染優(yōu)化
- CSS 放前面,JS 放后面
- 懶加載(圖片懶加載, 下拉加載更多)
- 減少DOM 查詢(xún),對(duì)DOM 查詢(xún)做緩存
- 減少DOM 操作,多個(gè)操作盡量合并在一起
- 事件節(jié)流
- 盡早執(zhí)行操作 (如 DOMContentLoaded)
示例
-
合并合并js文件,減少請(qǐng)求次數(shù) -
緩存通過(guò)連接名稱(chēng)控制緩存<script src="abc_1.js"></script>, 只有內(nèi)容改變時(shí)才更改鏈接名稱(chēng)<script src="abc_2.js"></script> -
CDNbootcss - 懶加載

<script>
var img1 = document.getElementById('img1')
img1.src = img1.setAttribute('data-bigsrc')
</script>
- 緩存 DOM 查詢(xún)
//未緩存 DOM 查詢(xún)
var i
for (var i = 0; i < document.getElementByTagName('p').length; i++) {
// todo
}
//緩存了 DOM 查詢(xún)
var pList = document.getElementByTagName('p');
var i
for (var i = 0; i < pList.length; i++) {
// todo
}
- 合并DOM插入
var listNode = document.getElementById('list')
//插入10個(gè)li標(biāo)簽
var frag = document.createDocumentFragment();
var x, li
for (x = 0; x < 10; x++) {
li = document.createElement('li')
li.innerHTML = 'List item' + x
frag.appendChild(li)
}
listNode.appendChild(frag)
- 事件節(jié)流
//在快速操作時(shí)不執(zhí)行事件,在停頓時(shí)執(zhí)行,以減少計(jì)算次數(shù)
var textarea = document.getElementById('text')
var timeoutId
textarea.addEventListener('keyup', function() {
if (timeoutId) {
clearTimeout(timeoutId)
}
timeoutId = setTimeout(function() {
//觸發(fā)change事件
}, 100);
})
- 盡早執(zhí)行操作 (如 DOMContentLoaded)
window.onloadListener('load',function(){
//頁(yè)面的全部資源加載完后才會(huì)執(zhí)行,包括圖片視頻等
})
window.onloadListener('load',function(){
// DOM 渲染完即開(kāi)始執(zhí)行,此時(shí)的圖片,視頻可能還沒(méi)有加載完
})