在同樣的網(wǎng)絡(luò)環(huán)境下,兩個(gè)同樣能滿足你的需求的網(wǎng)站,一個(gè)“Duang”的一下就加載出來(lái)了,一個(gè)糾結(jié)了半天才出來(lái),你會(huì)選擇哪個(gè)?研究表明:用戶最滿意的打開(kāi)網(wǎng)頁(yè)時(shí)間是2-5秒,如果等待超過(guò)10秒,99%的用戶會(huì)關(guān)閉這個(gè)網(wǎng)頁(yè)。
許多研究發(fā)現(xiàn),頁(yè)面速度和訪客的滯留時(shí)間,跳出率以及收入都有直接的關(guān)系。另外,谷歌的排名算法中也把頁(yè)面加載速度作為其中一項(xiàng)考慮因素。因此,你網(wǎng)站的頁(yè)面加載時(shí)間是至關(guān)重要的。
小于3秒的頁(yè)載入時(shí)間被認(rèn)為是優(yōu)良的,而且高達(dá)5秒是可接受的。而大于6秒的頁(yè)面載入時(shí)間不僅影響你網(wǎng)站的搜索引擎排名,還會(huì)嚴(yán)重影響用戶體驗(yàn)。
在四月份下旬的時(shí)候,就有一個(gè)老客戶的反應(yīng)他們的網(wǎng)站打開(kāi)速度過(guò)慢,導(dǎo)致跳出率過(guò)高,尋求解決辦法。

經(jīng)過(guò)對(duì)網(wǎng)站的實(shí)測(cè)分析:網(wǎng)站服務(wù)器基礎(chǔ)設(shè)施一般般+服務(wù)軟件有很大的改進(jìn)空間+程序代碼和前端需要升級(jí)改進(jìn)。針對(duì)這位老客戶的需求,提出如下解決方案:網(wǎng)站前端改版+服務(wù)端優(yōu)化升級(jí)。
下面我們就分享一下如何提高前端網(wǎng)頁(yè)加速度
進(jìn)行前端優(yōu)化的時(shí)候,我們首先需要明白網(wǎng)頁(yè)加載順序:
加載順序:1.DNS查找 > 2.下載并渲染HTML文件 > 3.下載并執(zhí)行css及js組件 > 4.下載圖片 > 5.渲染展示
1.html文檔優(yōu)化
1.1. 避免使用空請(qǐng)求,包括空的href鏈接、空src鏈接??真溄颖旧頍o(wú)法請(qǐng)求成功,因此會(huì)把一個(gè)HTTP請(qǐng)求拖到超時(shí),而且空鏈接會(huì)阻塞頁(yè)面中其他資源的下載進(jìn)程,會(huì)拖慢頁(yè)面加載速度。
1.2. 根據(jù)項(xiàng)目大小,選擇主要使用class還是id。id選擇器優(yōu)先級(jí)最高,訪問(wèn)速度最快。但是在html中每聲明一個(gè)id,就會(huì)在JS底層聲明一個(gè)全局變量,而全局變量的增多,將會(huì)拖慢JS中變量遍歷的效率,若變量遍歷達(dá)到十萬(wàn)次以上,就會(huì)出現(xiàn)較顯著的延遲,而且容易造成全局變量污染。對(duì)于小項(xiàng)目,并無(wú)影響,但是對(duì)中大型項(xiàng)目來(lái)說(shuō),尤其是游戲項(xiàng)目,影響很大。個(gè)人推薦,當(dāng)項(xiàng)目較小時(shí),靈活使用class和id,當(dāng)項(xiàng)目較大時(shí),盡量少使用id。
1.3. 預(yù)先設(shè)定圖片大小。在頁(yè)面加載過(guò)程中,圖片最后加載,若不對(duì)圖片預(yù)設(shè)大小,當(dāng)圖片加載完成后,將會(huì)引起大量的重排,將會(huì)浪費(fèi)瀏覽器資源及拖慢頁(yè)面加載速度。
1.4. 盡量減少DOM元素的數(shù)量與層級(jí)。解析HTML時(shí),標(biāo)簽的數(shù)量越多,標(biāo)簽的層級(jí)越深,瀏覽器解析構(gòu)建DOM樹(shù)的時(shí)間就越長(zhǎng),應(yīng)盡可能的減少DOM元素的數(shù)量和層級(jí)。
1.5. 盡量避免使用table標(biāo)簽。瀏覽器對(duì)table標(biāo)簽的解析是全部生成后再一次性繪制的,因此會(huì)造成表格位置較長(zhǎng)時(shí)間的空白,推薦使用ul及l(fā)i標(biāo)簽繪制表格。
1.6. 使用異步加載iframe標(biāo)簽。瀏覽器加載iframe標(biāo)簽時(shí),會(huì)阻塞父頁(yè)面渲染樹(shù)的構(gòu)建及HTTP請(qǐng)求,因此盡量使用異步加載iframe。
2.減少DNS查找 增加DNS預(yù)解析
2.1 DNS查找,即瀏覽器根據(jù)url中域名,查找該域名對(duì)應(yīng)的服務(wù)器IP地址,然后才能根據(jù)服務(wù)器IP地址,下載到文件。在DNS查找完成之前,所有的文件下載都無(wú)法執(zhí)行。每一次DNS查找時(shí)間約20-120ms。
一般而言,電腦會(huì)進(jìn)行DNS緩存,包括瀏覽器緩存、系統(tǒng)緩存、路由器緩存、ISP DNS緩存。所以,瀏覽器DNS查找順序一般是這樣的:瀏覽器緩存→系統(tǒng)緩存→路由器緩存→ISP DNS 緩存→遞歸搜索。
遞歸搜索,即ISP的DNS服務(wù)器從根域名開(kāi)始進(jìn)行遞歸查詢,查找時(shí)間一般為20-120ms。
若沒(méi)有DNS緩存,才會(huì)執(zhí)行DNS遞歸搜索。但是顯而易見(jiàn),第一次訪問(wèn)網(wǎng)站首頁(yè)時(shí),是不會(huì)有DNS緩存的,必然會(huì)執(zhí)行DNS查找。而每一個(gè)DNS查找,需要耗時(shí)20-120ms。因此,減少DNS查找能加快網(wǎng)頁(yè)加載速度。
2.2 DNS預(yù)獲取,是前端優(yōu)化的一部分。一般來(lái)說(shuō),在前端優(yōu)化中與 DNS 有關(guān)的有兩點(diǎn): 一個(gè)是減少DNS的請(qǐng)求次數(shù),另一個(gè)就是進(jìn)行DNS預(yù)獲取 。
DNS Prefetch 應(yīng)該盡量的放在網(wǎng)頁(yè)的前面,推薦放在 <meta charset="UTF-8"> 后面。具體使用方法如下:
< meta http-equiv="x-dns-prefetch-control" content="on"> < link rel="dns-prefetch" href="//www.654884.com">
特別說(shuō)明:減少dns請(qǐng)求是說(shuō)盡量不要引用外站文件,dns預(yù)獲取是在引用外站文件的時(shí)候使用,比如說(shuō)使用cdn的時(shí)候,使用這個(gè)就可以減少dns請(qǐng)求數(shù)和加快下載速度。
3.避免重定向
重定向增加了額外的HTTP請(qǐng)求,因此也增加了頁(yè)面加載時(shí)間。然而有時(shí)重定向卻是不可避免的,如鏈接網(wǎng)站的不同部分、保存多個(gè)域名、或者從不存在的頁(yè)面跳轉(zhuǎn)到新頁(yè)面。
重定向增加了延遲時(shí)間,因此要盡量避免使用它。檢查是否有損壞的鏈接,并立即修復(fù)。
4.減少http請(qǐng)求
HTTP請(qǐng)求需從客戶端發(fā)起請(qǐng)求,然后由服務(wù)器端進(jìn)行數(shù)據(jù)處理,然后再返回?cái)?shù)據(jù)或資源。一般而言,耗時(shí)據(jù)請(qǐng)求資源的大小,服務(wù)器網(wǎng)速,約數(shù)ms-數(shù)百ms之間。請(qǐng)求資源越大,所花費(fèi)的時(shí)間越長(zhǎng),服務(wù)器網(wǎng)速越慢,所花費(fèi)的時(shí)間也越長(zhǎng)。
一般而言,完成了DNS查找后,接下來(lái)便是進(jìn)行HTTP請(qǐng)求,獲取資源。首先下載HTML文件,然后解析HTML文件,根據(jù)HTML內(nèi)容,獲取CSS、JS及圖片文件。每一個(gè)CSS鏈接、JS鏈接以及圖片鏈接都是一個(gè)HTTP請(qǐng)求。
4.1 合并圖片等小文件,使用 CSS Sprites 整合圖像。多圖像的網(wǎng)站加載時(shí)間比較久。其中一個(gè)解決方法就是把多個(gè)圖像整合到少數(shù)幾個(gè)輸出文件中。你可以使用 CSS Sprites 來(lái)整合圖像文件。這樣就減少了在下載其他資源時(shí)的往返次數(shù)和延遲,從而提高了站點(diǎn)的速度。
4.2 合并css/js文件。盡量減少css或是js文件的數(shù)量,有些css文件代碼比較少,可以多個(gè)合并成為一個(gè)。
5.壓縮/縮小文件
5.1 壓縮CSS和JavaScript. 壓縮是通過(guò)移除不必要的字符(如TAB、空格、回車(chē)、代碼注釋等),以幫助減少其大小和網(wǎng)頁(yè)的后續(xù)加載時(shí)間的過(guò)程。這是非常重要的,但是,你還需要保存JS和CSS的原文件,以便更新和修改代碼。
5.2 啟用GZIP壓縮. 在服務(wù)器上壓縮網(wǎng)站的頁(yè)面是提升網(wǎng)站訪問(wèn)速度非常有效的一種方法。你可以用gzip壓縮做到這一點(diǎn)。Gzip是一個(gè)減小發(fā)送給訪客的HTML文件、JS和CSS體積的工具。壓縮的文件減少了HTTP響應(yīng)時(shí)間。
5.3 圖片文件盡量滿足需要就好,圖片格式上盡量選擇壓縮比較高的格式。同一張圖片,jpg格式比png格式小約5倍,加載速度快約3倍;推薦使用webp圖片格式,更快更好哦。什么是webp圖片格式
6.CSS優(yōu)先加載,JS延遲加載
在解析HTML文件,構(gòu)建DOM樹(shù)時(shí),一旦遇到link標(biāo)記時(shí),即遇到了CSS樣式表,將之下載,便可立即構(gòu)建渲染樹(shù),從而立即呈現(xiàn)頁(yè)面效果。
而一旦遇到script 標(biāo)記時(shí),即遇到了JS腳本,將立即阻塞DOM樹(shù)的構(gòu)建,將控制權(quán)移交給 JavaScript 引擎,等到 JavaScript 引擎運(yùn)行完畢,瀏覽器才會(huì)從中斷的地方恢復(fù)渲染樹(shù)的構(gòu)建。
若將引入JS腳本的鏈接放到HTML頁(yè)面頂部,那么在加載該頁(yè)面時(shí),一旦遇到JS,頁(yè)面渲染就會(huì)停滯,出現(xiàn)一段時(shí)間的灰色空白,直到JS加載完成,才會(huì)出現(xiàn)頁(yè)面內(nèi)容,這對(duì)用戶體驗(yàn)是不友好的。因此,我們需要將JS腳本放置到頁(yè)面底部,或者讓JS腳本異步或是延遲加載。(說(shuō)白了就是css文件可以放到</head>標(biāo)簽之前,js文件放到</html>之前)
7.合理利用緩存
避免在HTML文件中使用style標(biāo)簽插入CSS樣式,及使用script標(biāo)簽插入JS腳本。若在HTML文件中插入CSS及JS,那么它們無(wú)法進(jìn)入緩存,每次刷新頁(yè)面,都要重新加載,不但浪費(fèi)了瀏覽器資源,拖慢了頁(yè)面加載速度,而且顯得冗余且復(fù)用性低,不利于日后的維護(hù)。因此,將CSS樣式與JS腳本分離出來(lái),形成CSS文件及JS文件,就能進(jìn)入緩存,進(jìn)而提高頁(yè)面加載速度。這就要求好好規(guī)劃文件內(nèi)容了,緩存公共部分能有效提升加載渲染速度哦!
8.css代碼優(yōu)化及js代碼優(yōu)化
8.1 CSS樣式代碼優(yōu)化
8.1.1. 禁止使用樣式表達(dá)式。CSS表達(dá)式從IE5起開(kāi)始支持,但僅有IE支持。它的解析速度較慢,而且運(yùn)算次數(shù)遠(yuǎn)比我們想象的要大,隨意動(dòng)動(dòng)鼠標(biāo)就能輕松達(dá)到上萬(wàn)次運(yùn)算,會(huì)對(duì)頁(yè)面性能造成影響。譬如:"#myDiv{width:expression(document.body.offsetWidth - 110 + "px"); }"
8.1.2. 優(yōu)化關(guān)鍵選擇器,去掉無(wú)效的父級(jí)選擇器,盡量少在選擇器末尾使用通配符。大多數(shù)人都認(rèn)為,瀏覽器對(duì)CSS選擇器的解析式從左往右進(jìn)行的,譬如選擇器:"#myDiv ul li a",大多數(shù)人會(huì)認(rèn)為這個(gè)選擇器效率極高,畢竟第一個(gè)ID #myDiv 就已經(jīng)把范圍限定了,先選擇 #myDiv ,再在 #myDiv 下尋找 ul ,再一級(jí)一級(jí)往下,直到找到 a 標(biāo)簽,效率很高。事實(shí)上這是錯(cuò)的,瀏覽器對(duì)CSS選擇器的解析式從右往左進(jìn)行的。在上述選擇器中,瀏覽器會(huì)先去尋找 a 標(biāo)簽,范圍為全局,再在 a 標(biāo)簽的列表中,尋找父級(jí)標(biāo)簽是 li 標(biāo)簽的 a 標(biāo)簽,一直向上,直到最后,找到父級(jí)標(biāo)簽是 #myDiv ul li 的a標(biāo)簽。因此,效率并不像想象中那么高。顯而易見(jiàn),"#myDi a"選擇器比"#myDiv ul li a"選擇器效率要高得多。而通配符 a 的效率遠(yuǎn)比類(lèi)選擇器及id選擇器低,若給 a 標(biāo)簽添加一個(gè)class myA ,構(gòu)造新選擇器:"#myDiv .myA",它的效率又遠(yuǎn)比"#myDi a"要高了。瀏覽器對(duì)CSS選擇器的解析式從右往左進(jìn)行,因此在選擇器末尾最好使用類(lèi)選擇器,而不是通配符。
8.2 JS代碼優(yōu)化
8.2.1. ajax請(qǐng)求方法按需求選擇get或是post,訪問(wèn)接口所花費(fèi)的時(shí)間在頁(yè)面加載時(shí)間中占很大的比重,而接口訪問(wèn)方法中,get方法遠(yuǎn)比post方法要快,因此按需選擇接口訪問(wèn)方法很重要。
8.2.2. 減少全局變量,盡量使用局部變量。js中,全局變量運(yùn)算速率遠(yuǎn)低于局部變量,速度差異達(dá)到上百倍,且全局變量越多,全局變量的查找速率便越慢。
8.2.3. 減少對(duì)DOM的操作。js操作DOM將會(huì)引起頁(yè)面的重繪及重排,需要花費(fèi)時(shí)間及耗費(fèi)瀏覽器資源。
9.去掉不必要的插件
一個(gè)非常值得關(guān)注但經(jīng)常被忽略的因素是你網(wǎng)站安裝的插件。如今,大量免費(fèi)的插件誘導(dǎo)網(wǎng)站開(kāi)發(fā)者添加很多不必要的功能。您安裝的每個(gè)插件都需要服務(wù)器處理,從而增加了頁(yè)面加載時(shí)間。所以禁用和刪除不必要的插件。然而,有些插件是必須的,如社交分享插件,你可以選擇CMS內(nèi)置的社交分享功能來(lái)代替安裝插件。
10.服務(wù)端輸出優(yōu)化
10.1 啟用GZIP壓縮
在服務(wù)器上壓縮網(wǎng)站的頁(yè)面是提升網(wǎng)站訪問(wèn)速度非常有效的一種方法。你可以用gzip壓縮做到這一點(diǎn)。Gzip是一個(gè)減小發(fā)送給訪客的HTML文件、JS和CSS體積的工具。壓縮的文件減少了HTTP響應(yīng)時(shí)間。據(jù)Yahoo報(bào)道,這大概可以減少70%的下載時(shí)間。而目前90%的通過(guò)瀏覽器的流量都支持Gzip壓縮,因此,這是一個(gè)提示網(wǎng)站性能有效的選項(xiàng)。
10.2 添加Expires頭
頁(yè)面的初次訪問(wèn)者會(huì)進(jìn)行很多HTTP請(qǐng)求,但是通過(guò)使用一個(gè)長(zhǎng)久的Expires頭,可以使這些組件被緩存,下次訪問(wèn)的時(shí)候,就可以減少不必要的HTPP請(qǐng)求,從而提高加載速度。
Web服務(wù)器通過(guò)Expires頭告訴客戶端可以使用一個(gè)組件的當(dāng)前副本,直到指定的時(shí)間為止。若同時(shí)制定Cache-Control和Expires,則max-age將覆蓋Expires頭(本方法對(duì)初次訪問(wèn)無(wú)效,作用在于可以加快其它頁(yè)面的加載速度)
11 使用CDN服務(wù)
有些時(shí)候,技術(shù)手段搞到無(wú)能為力的時(shí)候,只需要使用CDN服務(wù)就可以將加載速度提升一個(gè)級(jí)別。如果應(yīng)用程序web服務(wù)器離用戶更近,那么一個(gè)HTTP請(qǐng)求的響應(yīng)時(shí)間將縮短。另一方面,如果組件web服務(wù)器離用戶更近,則多個(gè)HTTP請(qǐng)求的響應(yīng)時(shí)間將縮短。
CDN(內(nèi)容發(fā)布網(wǎng)絡(luò))是一組分布在多個(gè)不同地理位置的Web服務(wù)器,用于更加有效地向用戶發(fā)布內(nèi)容。在優(yōu)化性能時(shí),向特定用戶發(fā)布內(nèi)容的服務(wù)器的選擇基于對(duì)網(wǎng)絡(luò)慕課擁堵的測(cè)量。例如,CDN可能選擇網(wǎng)絡(luò)階躍數(shù)最小的服務(wù)器,或者具有最短響應(yīng)時(shí)間的服務(wù)器。
其實(shí)大部分網(wǎng)站都是一般的網(wǎng)站,改善一下服務(wù)器設(shè)置,或是開(kāi)啟CDN服務(wù)就能滿足用戶打開(kāi)的速度要求了。記得有句話說(shuō)的是:大部分網(wǎng)站web項(xiàng)目的性能瓶頸都可以通過(guò)人民幣快速找到解決辦法,若是還不能,那就再加一點(diǎn)。

