全部放在head標籤裏的JS和CSS都會阻塞頁面渲染。若是這些CSS和JS須要記在時間比較久,中間頁面會存在一個空白期,嚴重影響到用戶體驗。javascript
例如如下代碼:在head標籤內加載jquery的js文件,css
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>demo</title> <script src="https://code.jquery.com/jquery-3.3.1.js"></script> </head>
jquery.js腳本文件加載了1.2s的時間,以下圖:html
相比之下,html加載的時間只有2ms,因此這個JS文件至少頁面停留了1.2s的空白狀態。java
解決方法:1.使用script標籤將js腳本文件放在body後面jquery
2.使用HTML5的新增屬性defer,給script標籤價上defer屬性,一旦加上該屬性,script將會異步加載,但不是立刻執行,而是等readystatechange變爲Interactive後按照順序執行。web
(1)不要放太多base64放在CSS裏面瀏覽器
放太多base64在CSS裏面,會致使CSS急速膨脹,把一張3k的圖片轉換爲base64,體積將變爲4k;若是你的css文件中放了10張3k的base64圖片,CSS文件的體積將變爲40k,可想而知,圖片放的越多,越會增大css文件大小,加載時間就會變長。緩存
以下圖:服務器
從上圖能夠發現,轉base64後,圖片體積增大了接近1/3,咱們的目的是爲了減少CSS、JS加載時間的,而非增長時間(不考慮不一樣網速環境)。異步
(2)把CSS寫成內聯的
爲何這樣說呢,咱們寫CSS的時候,老是被告誡少些內聯樣式,易於維護。可是若是你的CSS只有10K或者30-40k,把它寫成內聯的何嘗不可,吧項目的CSS文件gzip以後若是很小,徹底能夠把全部的CSS都寫成style標籤放到HTML裏面。
若是你把CSS放到CDN上,瀏覽器爲了獲得這個CSS文件,須要進行域名解析,而後創建http/https連接,其次纔是下載此文件。而用來作域名解析和創建鏈接的時間早已經把CSS下載下來了。
爲了不時間開銷,更好的用戶瀏覽速度,能夠把CSS直接嵌到HTML裏面。
若是你的CSS文件不是太大,加上gzip壓縮,放到HTML中會是一個不錯的選擇。
(1)使用響應式圖片
響應式圖片的優勢就是可以根據瀏覽器的屏幕大小、設備像素比dpr、橫豎屏自動加載合適的圖片
<img srcset='phtoto_w350.jpg 1x,photo_w640.jpg 2x' src='photo_w350.jpg' alt=''>
上述代碼實現若是屏幕的dpr=1的話加載1倍圖,而dpr=2則加載2倍圖。而且,若是瀏覽器不支持srcset屬性,會默認加載src裏面的圖片。
網上說,在MAC上的CHorme會加載srcset裏面的2x圖片的同時,還會去加載src裏面的那張,加載兩張圖片。哈哈,因爲本人比較窮,無mac,不能驗證了。有的小夥伴能夠驗證下
另外HTML5新增的picture標籤,對實現響應式圖片作了不少擴展。不想敲了,借用MDN說明
須要注意的是,使用picture標籤時必須使用img標籤,不然沒法顯示。對picture的操做最後都是在img標籤上體現,例如onload事件是在img標籤出發的,picture和source是不會被瀏覽器layout的,他們的寬和高都是0.
在栗子2中,可使用type=‘image/webp’,從而使用webp格式的圖片,webp圖片在保持同等清晰度的狀況下,體積能夠減小一半,可是兼容性不太好,目前只有chorme支持。可是若是檢查到不支持此格式,會默認選擇img標籤內的圖片。
(2)延遲加載圖片
這個是大衆常談的,基本上都很熟悉,簡單說一下
頁面內圖片過多的狀況下,若是一口氣加載完,會致使頁面的loaded時間較長,而且因爲下載並行的資源有限制的,圖片太多會致使放在body後的JS解析會比較慢,頁面會較長時間處在不可交互的狀態。
懶加載圖片這時就排上用場了,初始加載的時候只加載首屏圖片,不在視口內的圖片,只有在用戶下滑至相應位置纔去加載。
具體作法:渲染圖片的時候 把圖片地址放到標籤的一個data屬性上,別放到src上。以下:
<picture> <source data-srcset="mdn-logo.svg" type="image/svg+xml"> <img src="about:blank" data-src='mdn-logo.png' alt="MDN"> </picture
src裏不能寫一個不存在的地址,不然瀏覽器控制檯會報錯。加載失敗,若是寫成空或者不寫,那麼src會默認當前頁面。寫成about:blank,不會報錯,瀏覽器兼容性也很好。
監聽scroll事件,回調函數以下:
showImage(leftSpace = 500){ var scrollTop = $window.scrollTop(); var $containers = this.$imgContainers, scrollPosition = $window.scrollTop() + $window.height(); for(var i =0;i<$containers.length;i++){ var $container = $containers.eq(i); if($container.ofset().top() - scrollPosition < leftSpace){ this.ensureImgSrc($container) } } }
使用ensureImgSrc函數把圖片放出來
ensureImgSrc($container){ var $source = $cotainer.find("source"); if($source.length && !$source.attr('srcset')){ $source.attr('srcset',$source.data('srcset')); } var $img= $cotainer.find("img:not(.loading)"); if($img.length && !$img.attr('src').indexOf('//')<0》){ $img.attr('src',$source.data('src')); this.shownCount++; } }
另外當圖片被加載完畢後,要清楚監聽事件,不然會形成內存泄漏。
int(){ //初始化 var leftSpace = 0; this.showImage(leftSpace); //監聽事件 $window.on("scroll",this,this.throttleShow); } ensureImgSrc($container){
//若是所有顯示,off掉scroll if(this.showCount>=this.allCount){ $window.off("scroll",this.throttleShow) } }
(3) 壓縮和緩存
gzip壓縮和服務器設置緩存。須要後臺Nginx配置。接觸不深,不作看法
(1)升級到HTTP/2
http2的有點在於對於一個域只創建一次TCP鏈接,使用多路複用,傳輸多個資源,這樣就不用使用注入雪碧圖、合併js/css文件等技術減小請求數,它能夠同時加載多個資源,不用進行資源排隊。
(2)DNS預讀取
<link rel="dns-prefetch" href="https://www.google.com/">
提早解析DNS,多個並行,不會堵塞頁面渲染,能夠減小資源加載時間
(3)HTML優化
remove掉多餘註釋,刪除行前縮進,都會減小HTML的體積
(4)代碼優化