互聯(lián)網(wǎng)有一項著名的8秒原則。用戶在訪問Web網(wǎng)頁時,如果時間超過8秒就會感到不耐煩,如果加載需要太長時間,他們就會放棄訪問。大部分用戶希望網(wǎng)頁能在2秒之內(nèi)就完成加載。事實上,加載時間每多1秒,你就會流失7%的用戶。8秒并不是準確的8秒鐘,只是向網(wǎng)站開發(fā)者表明了加載時間的重要性。那我們?nèi)绾蝺?yōu)化頁面性能,提高頁面加載速度呢? 這是本文主要要探討的問題,然而性能優(yōu)化是個綜合性問題,沒有標準答案,想要面面俱到羅列出來,并非易事。本文只關(guān)注一些核心要點,以下是我總結(jié)性能優(yōu)化常見的辦法。 資源壓縮與合并 主要包括這些方面:html壓縮、css 壓縮、js的壓縮和混亂和文件合并。 資源壓縮可以從文件中去掉多余的字符,比如回車、空格。你在編輯器中寫代碼的時候,會使用縮進和注釋,這些方法無疑會讓你的代碼簡潔而且易讀,但它們也會在文檔中添加多余的字節(jié)。 1.html壓縮html代碼壓縮就是壓縮這些在文本文件中有意義,但是在HTML中不顯示的字符,包括空格,制表符,換行符等,還有一些其他意義的字符,如HTML注釋也可以被壓縮。 如何進行html壓縮:
2.css代碼壓縮css代碼壓縮簡單來說就是無效代碼刪除和css語義合并。 如何進行css壓縮:
3.js的壓縮和混亂js的壓縮和混亂主要包括以下這幾部分:
如何進行js的壓縮和混亂:
其實css壓縮與js的壓縮和混亂比html壓縮收益要大得多,同時css代碼和js代碼比html代碼多得多,通過css壓縮和js壓縮帶來流量的減少,會非常明顯。所以對大公司來說,html壓縮可有可無,但css壓縮與js的壓縮和混亂必須要有! 4.文件合并從上圖可以看出不合并請求有以下缺點:
壓縮合并css和js可以減少網(wǎng)站http請求的次數(shù),但合并文件可能會帶來問題:首屏渲染和緩存失效問題。 那該如何處理這問題呢?——公共庫合并和不同頁面的合并。 如何進行文件合并:
非核心代碼異步加載異步加載的方式 1、異步加載的方式異步加載的三種方式——async和defer、動態(tài)腳本創(chuàng)建。 ① async方式
② defer方式
③動態(tài)創(chuàng)建script標簽 在還沒定義defer和async前,異步加載的方式是動態(tài)創(chuàng)建script,通過window.onload方法確保頁面加載完畢再將script標簽插入到DOM中。 具體代碼如下:
2、異步加載的區(qū)別1)defer是在HTML解析完之后才會執(zhí)行,如果是多個,按照加載的順序依次執(zhí)行; 2)async是在加載完之后立即執(zhí)行,如果是多個,執(zhí)行順序和加載順序無關(guān); 其中藍色線代表網(wǎng)絡(luò)讀取,紅色線代表執(zhí)行時間,這倆都是針對腳本的;綠色線代表 HTML 解析。 利用瀏覽器緩存 對于web應(yīng)用來說,緩存是提升頁面性能同時減少服務(wù)器壓力的利器。 瀏覽器緩存類型1.強緩存:不會向服務(wù)器發(fā)送請求,直接從緩存中讀取資源,在chrome控制臺的network選項中可以看到該請求返回200的狀態(tài)碼,并且size顯示from disk cache或from memory cache; 相關(guān)的header:Expires :response header里的過期時間,瀏覽器再次加載資源時,如果在這個過期時間內(nèi),則命中強緩存。它的值為一個絕對時間的GMT格式的時間字符串, 比如Expires:Thu,21 Jan 2018 23:39:02 GMT Cache-Control :這是一個相對時間,在配置緩存的時候,以秒為單位,用數(shù)值表示。當值設(shè)為max-age=300時,則代表在這個請求正確返回時間(瀏覽器也會記錄下來)的5分鐘內(nèi)再次加載資源,就會命中強緩存。比如Cache-Control:max-age=300, 簡單概括:其實這兩者差別不大,區(qū)別就在于 Expires 是http1.0的產(chǎn)物,Cache-Control是http1.1的產(chǎn)物,兩者同時存在的話,Cache-Control優(yōu)先級高于Expires;在某些不支持HTTP1.1的環(huán)境下,Expires就會發(fā)揮用處。所以Expires其實是過時的產(chǎn)物,現(xiàn)階段它的存在只是一種兼容性的寫法。強緩存判斷是否緩存的依據(jù)來自于是否超出某個時間或者某個時間段,而不關(guān)心服務(wù)器端文件是否已經(jīng)更新,這可能會導致加載文件不是服務(wù)器端最新的內(nèi)容,那我們?nèi)绾潍@知服務(wù)器端內(nèi)容較客戶端是否已經(jīng)發(fā)生了更新呢?此時我們需要協(xié)商緩存策略。 2.協(xié)商緩存:向服務(wù)器發(fā)送請求,服務(wù)器會根據(jù)這個請求的request header的一些參數(shù)來判斷是否命中協(xié)商緩存,如果命中,則返回304狀態(tài)碼并帶上新的response header通知瀏覽器從緩存中讀取資源;另外協(xié)商緩存需要與cache-control共同使用。 相關(guān)的header:①Last-Modified和If-Modified-Since:當?shù)谝淮握埱筚Y源時,服務(wù)器將資源傳遞給客戶端時,會將資源最后更改的時間以“Last-Modified: GMT”的形式加在實體首部上一起返回給客戶端。
客戶端會為資源標記上該信息,下次再次請求時,會把該信息附帶在請求報文中一并帶給服務(wù)器去做檢查,若傳遞的時間值與服務(wù)器上該資源最終修改時間是一致的,則說明該資源沒有被修改過,直接返回304狀態(tài)碼,內(nèi)容為空,這樣就節(jié)省了傳輸數(shù)據(jù)量 。如果兩個時間不一致,則服務(wù)器會發(fā)回該資源并返回200狀態(tài)碼,和第一次請求時類似。 這樣保證不向客戶端重復發(fā)出資源,也保證當服務(wù)器有變化時,客戶端能夠得到最新的資源。一個304響應(yīng)比一個靜態(tài)資源通常小得多,這樣就節(jié)省了網(wǎng)絡(luò)帶寬。 但last-modified 存在一些缺點: Ⅰ.某些服務(wù)端不能獲取精確的修改時間; Ⅱ.文件修改時間改了,但文件內(nèi)容卻沒有變; 既然根據(jù)文件修改時間來決定是否緩存尚有不足,能否可以直接根據(jù)文件內(nèi)容是否修改來決定緩存策略?——ETag和If-None-Match ②ETag和If-None-Match:Etag是上一次加載資源時,服務(wù)器返回的response header,是對該資源的一種唯一標識,只要資源有變化,Etag就會重新生成。瀏覽器在下一次加載資源向服務(wù)器發(fā)送請求時,會將上一次返回的Etag值放到request header里的If-None-Match里,服務(wù)器只需要比較客戶端傳來的If-None-Match跟自己服務(wù)器上該資源的ETag是否一致,就能很好地判斷資源相對客戶端而言是否被修改過了。 如果服務(wù)器發(fā)現(xiàn)ETag匹配不上,那么直接以常規(guī)GET 200回包形式將新的資源(當然也包括了新的ETag)發(fā)給客戶端;如果ETag是一致的,則直接返回304知會客戶端直接使用本地緩存即可。 兩者之間對比:首先在精確度上,Etag要優(yōu)于Last-Modified。Last-Modified的時間單位是秒,如果某個文件在1秒內(nèi)改變了多次,那么他們的Last-Modified其實并沒有體現(xiàn)出來修改,但是Etag每次都會改變確保了精度;如果是負載均衡的服務(wù)器,各個服務(wù)器生成的Last-Modified也有可能不一致。第二在性能上,Etag要遜于Last-Modified,畢竟Last-Modified只需要記錄時間,而Etag需要服務(wù)器通過算法來計算出一個hash值。第三在優(yōu)先級上,服務(wù)器校驗優(yōu)先考慮Etag 緩存的機制強制緩存優(yōu)先于協(xié)商緩存進行,若強制緩存(Expires和Cache-Control)生效則直接使用緩存,若不生效則進行協(xié)商緩存(Last-Modified / If-Modified-Since和Etag / If-None-Match),協(xié)商緩存由服務(wù)器決定是否使用緩存,若協(xié)商緩存失效,那么代表該請求的緩存失效,重新獲取請求結(jié)果,再存入瀏覽器緩存中;生效則返回304,繼續(xù)使用緩存。 主要過程如下: 用戶行為對瀏覽器緩存的影響
使用CDN 大型Web應(yīng)用對速度的追求并沒有止步于僅僅利用瀏覽器緩存,因為瀏覽器緩存始終只是為了提升二次訪問的速度,對于首次訪問的加速,我們需要從網(wǎng)絡(luò)層面進行優(yōu)化,最常見的手段就是CDN(Content Delivery Network,內(nèi)容分發(fā)網(wǎng)絡(luò))加速。 通過將靜態(tài)資源(例如javascript,css,圖片等等)緩存到離用戶很近的相同網(wǎng)絡(luò)運營商的CDN節(jié)點上,不但能提升用戶的訪問速度,還能節(jié)省服務(wù)器的帶寬消耗,降低負載。 CDN是怎么做到加速的呢?其實這是CDN服務(wù)商在全國各個省份部署計算節(jié)點,CDN加速將網(wǎng)站的內(nèi)容緩存在網(wǎng)絡(luò)邊緣,不同地區(qū)的用戶就會訪問到離自己最近的相同網(wǎng)絡(luò)線路上的CDN節(jié)點,當請求達到CDN節(jié)點后,節(jié)點會判斷自己的內(nèi)容緩存是否有效,如果有效,則立即響應(yīng)緩存內(nèi)容給用戶,從而加快響應(yīng)速度。如果CDN節(jié)點的緩存失效,它會根據(jù)服務(wù)配置去我們的內(nèi)容源服務(wù)器獲取最新的資源響應(yīng)給用戶,并將內(nèi)容緩存下來以便響應(yīng)給后續(xù)訪問的用戶。 因此,一個地區(qū)內(nèi)只要有一個用戶先加載資源,在CDN中建立了緩存,該地區(qū)的其他后續(xù)用戶都能因此而受益。 預解析DNS 資源預加載是另一個性能優(yōu)化技術(shù),我們可以使用該技術(shù)來預先告知瀏覽器某些資源可能在將來會被使用到。通過 DNS 預解析來告訴瀏覽器未來我們可能從某個特定的 URL 獲取資源,當瀏覽器真正使用到該域中的某個資源時就可以盡快地完成 DNS 解析。例如,我們將來可從 example.com 獲取圖片或音頻資源,那么可以在文檔頂部的 標簽中加入以下內(nèi)容:
當我們從該 URL 請求一個資源時,就不再需要等待 DNS 的解析過程。該技術(shù)對使用第三方資源特別有用。通過簡單的一行代碼就可以告知那些兼容的瀏覽器進行 DNS 預解析,這意味著當瀏覽器真正請求該域中的某個資源時,DNS 的解析就已經(jīng)完成了,從而節(jié)省了寶貴的時間。 另外需要注意的是,瀏覽器會對a標簽的href自動啟用DNS Prefetching,所以a標簽里包含的域名不需要在head中手動設(shè)置link。但是在HTTPS下不起作用,需要meta來強制開啟功能。這個限制的原因是防止竊聽者根據(jù)DNS Prefetching推斷顯示在HTTPS頁面中超鏈接的主機名。 下面這句話作用是強制打開a標簽域名解析:
作者:浪里行舟,碩士研究生,專注于前端,運營有個人公眾號前端工匠,致力于打造適合初中級工程師能夠快速吸收的一系列優(yōu)質(zhì)文章。 |
|
來自: 長沙7喜 > 《網(wǎng)絡(luò)》