前端面試中常常問到的問題:如何提升網站性能 總結

1. 使用dns預解析css

DNS 請求須要的帶寬很是小,可是延遲卻有點高,這點在手機網絡上特別明顯。預讀取 DNS 能讓延遲明顯減小一些,例如用戶點擊連接時。在某些狀況下,延遲能減小一秒鐘。
在某些瀏覽器中這個預讀取的行爲將會與頁面實際內容並行發生(而不是串行)。正因如此,某些高延遲的域名的解析過程纔不會卡住資源的加載。
這樣能夠極大的加速(尤爲是移動網絡環境下)頁面的加載。在某些圖片較多的頁面中,在發起圖片加載請求以前預先把域名解析好將會有至少 5%的圖片加載速度提高。
你能夠經過在服務器端發送 X-DNS-Prefetch-Control 報頭,或是在文檔中使用值爲 http-equiv 的 <meta>標籤:

打開和關閉 DNS 預讀取前端

在高級瀏覽器中a標籤是默認打開預解析的,可是在https協議中是默認關閉的,此句話是強制打開a img script等 標籤的預解析
<meta http-equiv="x-dns-prefetch-control" content="off">
link標籤的dns預解析
<link rel="dns-prefetch" href="//host_name_to_prefetch.com">
您能夠經過將 content 的參數設置爲「on」來改變設置。

強制查詢特定主機名webpack

你能夠經過使用 rel 屬性值爲 link type 中的 dns-prefetch 的 <link> 標籤來對特定域名進行預讀取:
<link rel="dns-prefetch" href="http://www.spreadfirefox.com/">
在這個例子中,Firefox將預解析域名"www.spreadfirefox.com"。

並且,<link> 元素也可使用不完整的 URL 的主機名來標記預解析,但這些主機名前必須要有雙斜線:web

<link rel="dns-prefetch" href="//www.spreadfirefox.com">
強制對域名進行預讀取在有的狀況下頗有用, 好比,
在網站的主頁上,強制在整個網站上頻繁引用的域名的預解析,即便它們不在主頁自己上使用。即便主頁的性能可能不受影響,這將提升總體站點性能

2.資源壓縮合並,減小HTTP請求後端

經過webpack,grunt等打包工具,對於js,css文件進行打包成單個的js以及css,使用gzip進行代碼壓縮,從而減小請求文件的大小以及數量,每一個js,css文件的加載都要發送一次http請求,因此經過合併js,css文件從而減小http請求次數。

3.瀏覽器緩存瀏覽器

1.強緩存緩存

  • Expire(絕對時間,下發的服務器時間,有可能客戶端和服務端時間不一致。Expire:Thu,21 Jan 2017 23:39:02
    GMT);
//在前端<head>標籤中設置
<meta http-equiv="expires" content="0">  

//在後端設置
response.setDateHeader("Expires",date.getTime()+20000); //Expires:過期期限值 
response.setDateHeader("Expires", 0);//不容許瀏覽器端或緩存服務器緩存當前頁面信息。
  • Cache-Control(相對時間,按照客戶端時間,3600秒內使用緩存。Cache-Control:max-age=3600)
//在前端<head>標籤中設置
<meta http-equiv="cache-control" content="no-cache">

//在後端設置
response.addHeader( "Cache-Control", "no-cache" );//瀏覽器和緩存服務器都不該該緩存頁面信息

在http響應頭中,若是兩個時間都有,以Cache-Control爲準服務器

2.協商緩存(問一下服務器)網絡

Last-Modified(服務器下發的響應頭中加,Last-Modified:Thu,21 Jan 2017 23:39:02 GMT)
If-Modified-Since,(http請求頭中加,時間和Last-Modified下發的一致,缺點:文件沒變但時間過時,會再次加載
//在後端設置
response.setDateHeader("Last-Modified",date.getTime()); //Last-Modified:頁面的最後生成時間
Etag (哈希值,服務器下發的響應頭中加,文件沒改變可繼續使用緩存) If-None-Match(http請求頭中加,時間和Etag下發的一致)
//響應消息頭
Etag:"a030f020ac7c01:1e9f"

關於下面這些HTTP請求頭部字段以及相關的http知識,能夠去閱讀 《圖解http》一書,對此有詳細的文字跟圖解異步

  • Expire
  • Cache-Control
  • Last-Modified
  • If-Modified-Since
  • If-Modified-Since
  • If-None-Match

4.異步加載

異步加載的方式:

1.動態腳本加載(動態建立節點:document.createElement("/script/"),用js建立一個標籤,再加到文檔中);
2.defer(在script標籤中加上此屬性);
3.async(在script標籤中加上此屬性)。
異步加載的區別:
1.defer是在HTML 解析完 以後纔會執行,defer屬性規定是否對腳本執行進行延遲,直到頁面加載爲止,若是是多個,按照加載的順序依次執行 ;
2.async是在加載完以後 當即執行 ,async屬性規定一旦腳本可用,則會異步執行,若是是多個,執行順序和加載順序無關。
這裏來一張defer跟async,仍是用圖解比較明瞭

clipboard.png

clipboard.png

此圖告訴咱們如下幾個要點:

defer 和 async 在網絡讀取(下載)這塊兒是同樣的,都是異步的(相較於 HTML 解析)它倆的差異在於腳本下載完以後什麼時候執行,顯然 defer 是最接近咱們對於應用腳本加載和執行的要求的 關於defer,此圖未盡之處在於它是按照加載順序執行腳本的,這一點要善加利用 async則是一個亂序執行的主,反正對它來講腳本的加載和執行是牢牢挨着的,因此無論你聲明的順序如何,只要它加載完了就會馬上執行 仔細想一想,async對於應用腳本的用處不大,由於它徹底不考慮依賴(哪怕是最低級的順序執行),不過它對於那些能夠不依賴任何腳本或不被任何腳本依賴的腳原本說倒是很是合適的,最典型的例子:GoogleAnalytics

相關文章
相關標籤/搜索