最近看了本書,叫《web 高效編程與優化實踐》,看的過程當中激發了我對 Chrome Devtools 的興趣,剛好看到了關於性能優化和網頁渲染的那部分,又想起了以前看過各大論壇你們對於瀏覽器渲染的理解,因此打算本身再看看這部分的知識點,解決一些疑問。css
本文的試驗都是基於 Chrome 瀏覽器,版本:75.0.3770.100(正式版本)(64 位)html
先上連接:前端
這幾篇部分是在這個過程當中看到的感受比較細緻且靠譜的文章,雖然文章的寫做時間都不算早,可是原理基本不會有太大變化,你們若是看完個人文章以爲不過癮的話,能夠看看這些文章。html5
先簡單歸納一下瀏覽器渲染的步驟:node
以上步驟說的比較簡略,並且沒有帶上 reflow 和 repaint,主要是幫你們梳理一下這個過程,便於後面的閱讀。web
終於說到文章正題,想必標題你們也看到了,是想研究一下 link 標籤和 script 標籤對頁面渲染的影響,既然是影響,確定是不理想的狀況。至於對頁面渲染的影響,這裏主要討論的是對頁面首次繪製時的影響。chrome
下面讓咱們先整理一下不理想的狀況,而後一個一個來試驗下:express
這就是本文試驗的一些狀況,正常位置固然是咱們平時總說的 link 標籤要放在首部 head 中,script 標籤放在 body 底部,加載時間過長經過服務器端延時 5000 毫秒來處理。編程
本次爲了快速開發,用到了一些快速搭建的工具,先推薦給你們:瀏覽器
行了,就用到這些東西,廢話很少說,咱們開始吧。
先來看看咱們用到的文件:
html:
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="IE=edge, chrome=1">
<title>debounce</title>
<style> img { width: 500px; } .block { width: 300px; height: 200px; border: 1px solid #000; } </style>
<link href="http://127.0.0.1:3000/public/css/common.css" rel="stylesheet">
</head>
<body>
<div class="block">
<h2 class="title">我是一段沒有感情的測試文案</h2>
</div>
<div class="pic">
<img src="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4215863670,261223381&fm=26&gp=0.jpg">
</div>
<script src="http://127.0.0.1:3000/public/js/test.js"></script>
</body>
</html>
複製代碼
common.css:
.block {
width: 500px;
background-color: red;
border: none;
}
複製代碼
test.js:
document.querySelector('.title').innerHTML = '我被修改了';
複製代碼
app.js:
const express = require('express')
const app = express()
const fs = require('fs')
const path = require('path');
app.use('*',function(req, res){
if (req.params[0] === '/public/css/common.css') {
// setTimeout(() => {
res.setHeader('content-type', 'text/css');
res.send(fs.readFileSync(path.join(__dirname, req.params[0])));
// }, 5000)
} else if(req.params[0] === '/public/js/test.js') {
// setTimeout(() => {
res.send(fs.readFileSync(path.join(__dirname, req.params[0])));
// }, 5000)
} else {
res.send('success');
}
})
app.listen(3000, () => console.log('working'))
複製代碼
這個頁面打開之後是這個樣子的:
讓咱們先把 js 標籤放到 head 的底部,也就是 link 標籤下面(這裏爲了避免把每次改完標籤位置的html都帖出來,我每次說的位置都是以初始位置爲基準),並把服務器端延時的代碼加上來看看效果:
能夠看到頁面由於 js 腳本的延遲加載,致使頁面白屏長達數秒,這確定不是咱們平時開發中想要的,還有由於腳本位置過前致使操做的 dom 元素也沒法找到。
再讓咱們看看控制檯中這個頁面具體經歷了什麼:
經過 performance 咱們能夠看到頁面的在 5s 後纔開始首次繪製,timeline 上也很容易看出前面頁面一直處於白屏階段。
如今讓咱們把 js 放到初始的位置,一樣加上延遲,再看下效果:
此次咱們能夠看到雖然 js 文件延遲加載了,可是 js 文件以前的元素很快就渲染出來了,再看下控制檯:
此次就很快了,頁面沒有由於 js 的加載阻塞前面元素的渲染,js 文件加載後由於修改了 dom 元素又繪製了一次。因此說把 js 文件放在頁面底部這個作法仍是比較合理的,可是也須要分狀況討論,好比有些頁面較長,圖片較多,可能首屏只展示了部分 dom,這時若是把全部的 js 都放在頁面底部,反而可能會影響 js 腳本對 dom 操做的實時性。
看完了 script 標籤,如今讓咱們看下 link 標籤的表現,首先把 script 標籤的延遲去掉,讓 link 標籤待在它原來的位置,在服務端加上延遲試一下:
很差意思,這裏沒有動圖。。。
此次的狀況動圖能夠參考動圖一,由於第一次正經寫文章,因此 gif 圖是先錄屏,而後截視頻,再上傳視頻作 gif。有點麻煩,就懶得再搞一個了,小夥伴有好的軟件或者方法歡迎評論區推薦。 至於網頁的 performance 和第一種狀況也是基本無差,我們直接進入到下一種狀況吧。
此次咱們把 link 標籤放到 body 的底部,其實前三種的狀況和我想象中的基本沒差,我試這個就是想看看最後一種狀況,來直接看圖吧:
誒,貌似和我預想的不太同樣,咱們先來看下控制檯確認下:
咱們能夠看到瀏覽器此次並無像 script 腳本延遲時同樣,等到 css 加載完纔開始繪製,而是很早就把 dom 畫出來了,等 css 加載完後,又再次繪製了一遍。後來我多試了幾回,若是把css文件放到dom中間位置,發現css文件的延遲一樣會阻塞後面元素的渲染,這個是我以前沒有想到的。
其實,若是網速足夠快,在資源的加載這一塊,咱們根本無需考慮優化,由於腳本自己不會大的離譜,因此在網速超快的狀況下,固然是想放哪裏放哪裏。可能在5年、10年之後的開發者回過頭來我這篇文章,沒準會對我如今考慮的這些問題不屑一顧,hhh。