這篇文章主要介紹了js和css文件位置對頁面性能的影響有哪些,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。
超過10年行業(yè)經(jīng)驗,技術(shù)領(lǐng)先,服務(wù)至上的經(jīng)營模式,全靠網(wǎng)絡(luò)和口碑獲得客戶,為自己降低成本,也就是為客戶降低成本。到目前業(yè)務(wù)范圍包括了:網(wǎng)站設(shè)計制作、成都網(wǎng)站制作,成都網(wǎng)站推廣,成都網(wǎng)站優(yōu)化,整體網(wǎng)絡(luò)托管,微信小程序定制開發(fā),微信開發(fā),重慶APP軟件開發(fā),同時也可以讓客戶的網(wǎng)站和網(wǎng)絡(luò)營銷和我們一樣獲得訂單和生意!CSS和JS文件的位置會影響頁面效率。js腳本應(yīng)放在底部,如果放在首部,當(dāng)下載執(zhí)行js時,會影響渲染行程繪制頁面;而CSS應(yīng)放在頂部,如果放在底部,頁面可以逐步呈現(xiàn),但在CSS下載并解析完畢后,已經(jīng)呈現(xiàn)的文字和圖片就要需要根據(jù)新的樣式重繪。
js腳本文件的位置
js腳本應(yīng)該放在底部,原因在于js線程與GUI渲染線程是互斥的關(guān)系,如果js放在首部,當(dāng)下載執(zhí)行js的時候,會影響渲染行程繪制頁面,js的作用主要是處理交互,而交互必須得先讓頁面呈現(xiàn)才能進行,所以為了保證用戶體驗,盡量讓頁面先繪制出來。
CSS文件的位置
CSS 是頁面渲染的關(guān)鍵因素之一,(當(dāng)頁面存在外鏈 CSS 時,)瀏覽器會等待全部的 CSS 下載及解析完成后再渲染頁面。關(guān)鍵路徑上的任何延遲都會影響首屏?xí)r間,因而我們需要盡快地將 CSS 傳輸?shù)接脩舻脑O(shè)備,否則,(在頁面渲染之前,)用戶只能看到一個空白的屏幕。
CSS文件放在頂部一方面是因為放置順序決定了下載的優(yōu)先級,更關(guān)鍵的是瀏覽器的渲染機制。
css在加載過程中不會影響到DOM樹的生成,但是會影響到Render樹的生成,進而影響到layout,所以一般來說,style的link標(biāo)簽需要盡量放在head里面,因為在解析DOM樹的時候是自上而下的,而css樣式又是通過異步加載的,這樣的話,解析DOM樹下的body節(jié)點和加載css樣式能盡可能的并行,加快Render樹的生成的速度。
將CSS放在底部,頁面可以逐步呈現(xiàn),但在CSS下載并解析完畢后,已經(jīng)呈現(xiàn)的文字和圖片就要需要根據(jù)新的樣式重繪,這是一種不好的用戶體驗。
js、css等腳本位置對性能的影響
用一句話概括就是: JS 全阻塞,CSS 半阻塞。(詞是我發(fā)明的,方便記憶而已)
JS 會阻塞后續(xù) DOM 解析以及其它資源(如 CSS,JS 或圖片資源)的加載。
CSS 不會阻塞后續(xù) DOM 結(jié)構(gòu)的解析,不會阻塞其它資源(如圖片)的加載,但是會阻塞 JS 文件的加載。
現(xiàn)代瀏覽器很聰明,會進行 prefetch 優(yōu)化,瀏覽器在獲得 html 文檔之后會對頁面上引用的資源進行提前下載。(注意僅僅只是提前下載)
下面開始我就一邊測試,一邊解釋上述測試的結(jié)果:
測試的瀏覽器是 Chrome,版本號為 55.0.2883.95 (64-bit)
先用 Nodejs 搭建一個簡單 http 服務(wù)器:
//test.jsconst http = require('http');const fs = require('fs');const hostname = '127.0.0.1';const port = 9000;http.createServer((req, res) => { if(req.url === "/") { fs.readFile("index.html", "utf-8", function(err, data) { res.writeHead(200, { 'Content-Type': 'text/html' }); res.write(data); res.end(); }) }else if(req.url === "/yellow.js") { //延遲 5s fs.readFile("yellow.js", "utf-8", function(err, data) { res.writeHead(200, { 'Content-Type': 'text/plain' }); setTimeout(function () { res.write(data); res.end(); }, 5000); }) }else if(req.url === "/blue.js") { //延遲 10s fs.readFile("blue.js", "utf-8", function(err, data) { res.writeHead(200, { 'Content-Type': 'text/plain' }); setTimeout(function () { res.write(data); res.end(); }, 10000); }) }else if(req.url === "/red.css") { //延遲 15s fs.readFile("red.css", "utf-8", function(err, data) { res.writeHead(200, { 'Content-Type': 'text/css' }); setTimeout(function () { res.write(data); res.end(); }, 15000); }) }else if(req.url === "/green.css") { //延遲 20s fs.readFile("green.css", "utf-8", function(err, data) { res.writeHead(200, { 'Content-Type': 'text/css' }); setTimeout(function () { res.write(data); res.end(); }, 20000); }) }}).listen(port, hostname, () => { console.log('Server running at ' + hostname);});
首頁的代碼結(jié)構(gòu):
//index.html測試瀏覽器渲染 First Line
Second Line
Third Line
Fourth Line
Fifth Line
以及其它 CSS 和 JS 文件:
//yellow.js document.body.style.cssText = "background: yellow !important"; //blue.js document.body.style.cssText = "background: blue !important";
//red.css body { background:red !important; } //green.css body { background: green !important; }
說明下:yellow.js 和 blue.js 下載時間分別為 5s 和 10s,red.css 和 green.css 下載時間分別為 15s 和 20s。
之后將所有文件放到同個目錄下,在控制臺輸入 node test.js,打開瀏覽器訪問 127.0.0.1:9000 就可以訪問。
先來看第三點結(jié)論:現(xiàn)代瀏覽器很聰明,會進行 prefetch 優(yōu)化,瀏覽器在獲得 html 文檔之后會對頁面上引用的資源進行提前下載。(注意僅僅只是提前下載)
很好理解,從圖中可以看出:CSS、JS、圖片在瀏覽器在拿到 html 文檔之后會將頁面上引用資源幾乎同時下載,但具體什么時候執(zhí)行要看 html 的結(jié)構(gòu),注意我這里使用的是 Chrome 瀏覽器,其它瀏覽器可能會有差別。
還有就是一個奇怪的現(xiàn)象,Chrome 瀏覽器有時會對 img 進行 prefetch,有時則不會。
接著是第一點規(guī)則:
JS 會阻塞后續(xù) DOM 解析以及其它資源(如 CSS,JS 或圖片資源)的加載。
從上圖可以看出,當(dāng)瀏覽器解析到 yellow.js 這行時候會等待 yellow.js 加載,阻塞后續(xù) DOM 結(jié)構(gòu)的解析(包括 DOM 結(jié)構(gòu),其他所有資源(CSS, JS, 圖片))。
這個很好理解:
JS 運行在瀏覽器中,是單線程的,每個 window 一個 JS 線程,所以當(dāng)然會阻塞后續(xù) DOM 樹的解析咯。
JS 有可能會修改 DOM 結(jié)構(gòu),給 DOM 添加樣式等等,所以這就意味著在當(dāng)前 JS 加載執(zhí)行完成前,后續(xù)資源的加載可能是沒有意義的。
其次第二點:
CSS 不會阻塞后續(xù) DOM 結(jié)構(gòu)的解析,不會阻塞其它資源(如圖片)的加載,但是會阻塞 JS 文件的加載。
這個就相對比較復(fù)雜點,讓我先上測試結(jié)果的圖:
從圖中可以得出以下總結(jié):
在加載完 yellow.js 后,當(dāng)在下載 red.css 時候并不會阻塞 DOM 解析,并且由于第一點規(guī)則,當(dāng)解析到 blue.js 這行的時候,同樣會阻塞后續(xù) DOM 解析。
由于我們設(shè)置的 red.css 下載時間為 15s 而 blue.js 為 10s,而從前面第三條規(guī)則的圖中也可以看到,blue.js 在 10s 左右下載完而 red.css 在 15s 左右下載完畢。
最后在 15s 時候頁面變?yōu)榱怂{色,這說明了 CSS 阻塞了 JS 的加載,后續(xù)的 JS 文件雖然提前下載完畢了,但還是要等前面 CSS 文件加載完后才能執(zhí)行。
后續(xù)當(dāng) blue.js 加載完之后可以看到,green.css 的下載并不會影響到后續(xù) img 的加載,所以說明 CSS 文件下載并不會影響后續(xù)圖片等其它資源以及 DOM 的加載。
這個也好理解:JS 代碼在執(zhí)行前,瀏覽器必須保證在 JS 之前的所有 CSS 樣式都解析完成,不然不就亂套了,前面的 CSS 樣式可能會覆蓋 JS 文件中定義的元素樣式,這是 CSS 阻塞后續(xù) JS 執(zhí)行的根本原因。
最后這里說明下為什么最后 body 的背景色沒有變成綠色:因為 js 定義的樣式在內(nèi)聯(lián)樣式,優(yōu)先級高于在 CSS 文件中定義的樣式,所以不是 green.css 沒有加載,而是沒有生效??聪聢D就知道了:(green 和 red 樣式都被劃掉了)
所以知道了上述的結(jié)論之后,我們在開發(fā)的時候應(yīng)該盡可能地:
將樣式或 CSS 文件定義在 head 中,并且在處理此類請求的時候應(yīng)該盡快能夠響應(yīng)(CDN 什么的),如果像上面請求一個 CSS 文件都要 10s 的話,那你這頁面估計沒多少人有耐心等下去。
將 JS 腳本文件放在 body 底部,讓 DOM 結(jié)構(gòu)能優(yōu)先渲染出來,避免 DOM 被阻塞。
當(dāng)編寫比較耗時的 JS 代碼時候盡可能使用異步的方式進行加載,比如 setTimeout, ajax 等等,同樣也是為了避免頁面渲染耗時過長,影響用戶體驗。
上面介紹了 JS 會阻塞后續(xù) DOM 解析以及其它資源(如 CSS,JS 或圖片資源)的加載,這是在沒有考慮到 defer, async 的情況下。
當(dāng)瀏覽器碰到 script 腳本的時候:(不考慮瀏覽器的 prefetch)
從使用的角度來看,首先把腳本丟到 body 底部是比較好的優(yōu)化選擇,此法可保證非腳本的其他一切元素能夠以最快的速度得到加載和解析。
上述的三點用圖可表示為:
藍色線代表網(wǎng)絡(luò)讀取,紅色線代表執(zhí)行時間,這倆都是針對腳本的;綠色線代表 HTML 解析。
總結(jié):
由于現(xiàn)代瀏覽器都存在 prefetch,所以 defer, async 可能并沒有太多的用途,可以作為了解擴展知識,僅僅將腳本文件放到 body 底部就可以起到很不錯的優(yōu)化效果。
defer 和 async 都是異步加載腳本文件。
慎用 async,因為它完全不考慮依賴關(guān)系,只要下載完后就加載,不考慮此時頁面樣式先后的加載順序,不過它對于那些可以不依賴任何腳本或不被任何腳本依賴的腳本來說卻是非常合適的,最典型的例子:Google Analytics。
耗時較長的腳本代碼可以使用 defer 來推遲執(zhí)行。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享js和css文件位置對頁面性能的影響有哪些內(nèi)容對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司,,關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,遇到問題就找創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司,,詳細的解決方法等著你來學(xué)習(xí)!