您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)WEB前端性能優(yōu)化的方法有哪些,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
如果不進(jìn)行文件合并,有如下3個(gè)隱患
1、文件與文件之間有插入的上行請(qǐng)求,增加了N-1個(gè)網(wǎng)絡(luò)延遲
2、受丟包問(wèn)題影響更嚴(yán)重
3、經(jīng)過(guò)代理服務(wù)器時(shí)可能會(huì)被斷開(kāi)
但是,文件合并本身也有自己的問(wèn)題
1、首屏渲染問(wèn)題
2、緩存失效問(wèn)題
所以,對(duì)于文件合并,有如下改進(jìn)建議
1、公共庫(kù)合并
2、不同頁(yè)面單獨(dú)合并
1、雪碧圖
CSS雪碧圖是以前非常流行的技術(shù),把網(wǎng)站上的一些圖片整合到一張單獨(dú)的圖片中,可以減少網(wǎng)站的HTTP請(qǐng)求數(shù)量,但是當(dāng)整合圖片比較大時(shí),一次加載比較慢。隨著字體圖片、SVG圖片的流行,該技術(shù)漸漸退出了歷史舞臺(tái)
2、Base64
將圖片的內(nèi)容以Base64格式內(nèi)嵌到HTML中,可以減少HTTP請(qǐng)求數(shù)量。但是,由于Base64編碼用8位字符表示信息中的6個(gè)位,所以編碼后大小大約比原始值擴(kuò)大了 33%
3、使用字體圖標(biāo)來(lái)代替圖片
盡量避免使用重定向,當(dāng)頁(yè)面發(fā)生了重定向,就會(huì)延遲整個(gè)HTML文檔的傳輸。在HTML文檔到達(dá)之前,頁(yè)面中不會(huì)呈現(xiàn)任何東西,也沒(méi)有任何組件會(huì)被下載,降低了用戶體驗(yàn)
如果一定要使用重定向,如http重定向到https,要使用301永久重定向,而不是302臨時(shí)重定向。因?yàn)?,如果使?02,則每一次訪問(wèn)http,都會(huì)被重定向到https的頁(yè)面。而永久重定向,在第一次從http重定向到https之后 ,每次訪問(wèn)http,會(huì)直接返回https的頁(yè)面
使用cach-control或expires這類(lèi)強(qiáng)緩存時(shí),緩存不過(guò)期的情況下,不向服務(wù)器發(fā)送請(qǐng)求。強(qiáng)緩存過(guò)期時(shí),會(huì)使用last-modified或etag這類(lèi)協(xié)商緩存,向服務(wù)器發(fā)送請(qǐng)求,如果資源沒(méi)有變化,則服務(wù)器返回304響應(yīng),瀏覽器繼續(xù)從本地緩存加載資源;如果資源更新了,則服務(wù)器將更新后的資源發(fā)送到瀏覽器,并返回200響應(yīng)
CSS的@import會(huì)造成額外的請(qǐng)求
a標(biāo)簽設(shè)置空的href,會(huì)重定向到當(dāng)前的頁(yè)面地址
form設(shè)置空的method,會(huì)提交表單到當(dāng)前的頁(yè)面地址
1、HTML壓縮
HTML代碼壓縮就是壓縮在文本文件中有意義,但是在HTML中不顯示的字符,包括空格,制表符,換行符等
2、CSS壓縮
CSS壓縮包括無(wú)效代碼刪除與CSS語(yǔ)義合并
3、JS壓縮與混亂
JS壓縮與混亂包括無(wú)效字符及注釋的刪除、代碼語(yǔ)義的縮減和優(yōu)化、降低代碼可讀性,實(shí)現(xiàn)代碼保護(hù)
4、圖片壓縮
針對(duì)真實(shí)圖片情況,舍棄一些相對(duì)無(wú)關(guān)緊要的色彩信息
在安卓下可以使用webp格式的圖片,它具有更優(yōu)的圖像數(shù)據(jù)壓縮算法,能帶來(lái)更小的圖片體積,同等畫(huà)面質(zhì)量下,體積比jpg、png少了25%以上,而且同時(shí)具備了無(wú)損和有損的壓縮模式、Alpha 透明以及動(dòng)畫(huà)的特性
HTTP協(xié)議上的GZIP編碼是一種用來(lái)改進(jìn)WEB應(yīng)用程序性能的技術(shù)。大流量的WEB站點(diǎn)常常使用GZIP壓縮技術(shù)來(lái)讓用戶感受更快的速度。這一般是指WWW服務(wù)器中安裝的一個(gè)功能,當(dāng)有人來(lái)訪問(wèn)這個(gè)服務(wù)器中的網(wǎng)站時(shí),服務(wù)器中的這個(gè)功能就將網(wǎng)頁(yè)內(nèi)容壓縮后傳輸?shù)絹?lái)訪的電腦瀏覽器中顯示出來(lái)。一般對(duì)純文本內(nèi)容可壓縮到原大小的40%
CDN全稱是Content Delivery Network,即內(nèi)容分發(fā)網(wǎng)絡(luò),它能夠?qū)崟r(shí)地根據(jù)網(wǎng)絡(luò)流量和各節(jié)點(diǎn)的連接、負(fù)載狀況以及到用戶的距離和響應(yīng)時(shí)間等綜合信息將用戶的請(qǐng)求重新導(dǎo)向離用戶最近的服務(wù)節(jié)點(diǎn)上。其目的是使用戶可就近取得所需內(nèi)容,解決 Internet網(wǎng)絡(luò)擁擠的狀況,提高用戶訪問(wèn)網(wǎng)站的響應(yīng)速度
當(dāng)瀏覽器訪問(wèn)一個(gè)域名的時(shí)候,需要解析一次DNS,獲得對(duì)應(yīng)域名的ip地址。在解析過(guò)程中,按照瀏覽器緩存、系統(tǒng)緩存、路由器緩存、ISP(運(yùn)營(yíng)商)DNS緩存、根域名服務(wù)器、頂級(jí)域名服務(wù)器、主域名服務(wù)器的順序,逐步讀取緩存,直到拿到IP地址
DNS Prefetch,即DNS預(yù)解析就是根據(jù)瀏覽器定義的規(guī)則,提前解析之后可能會(huì)用到的域名,使解析結(jié)果緩存到系統(tǒng)緩存中,縮短DNS解析時(shí)間,來(lái)提高網(wǎng)站的訪問(wèn)速度
方法是在 head 標(biāo)簽里面寫(xiě)上幾個(gè) link 標(biāo)簽
<link rel="dns-prefecth" href="https://www.jb51.net"> <link rel="dns-prefecth" href="https://www.jb51cs.net" rel="external nofollow" >
對(duì)以上幾個(gè)網(wǎng)站提前解析 DNS,由于它是并行的,不會(huì)堵塞頁(yè)面渲染,這樣可以縮短資源加載的時(shí)間
由于在HTTP1.1協(xié)議下,chrome每個(gè)域名的最大并發(fā)數(shù)是6個(gè)。使用多個(gè)域名,可以增加并發(fā)數(shù)
使用keep-alive或presistent來(lái)建立持久連接,持久連接降低了時(shí)延和連接建立的開(kāi)銷(xiāo),將連接保持在已調(diào)諧狀態(tài),而且減少了打開(kāi)連接的潛在數(shù)量
在HTTP2協(xié)議中,可以開(kāi)啟管道化連接,即單條連接的多路復(fù)用,每條連接中并發(fā)傳輸多個(gè)資源,這里就不需要添加域名來(lái)增加并發(fā)數(shù)了
通過(guò)優(yōu)化資源加載位置,更改資源加載時(shí)機(jī),使盡可能快地展示出頁(yè)面內(nèi)容,盡可能快地使功能可用
1、CSS文件放在head中,先外鏈,后本頁(yè)
2、JS文件放在body底部,先外鏈,后本頁(yè)
3、處理頁(yè)面、處理頁(yè)面布局的JS文件放在head中,如babel-polyfill.js文件、flexible.js文件
4、body中間盡量不寫(xiě)style標(biāo)簽和script標(biāo)簽
1、異步script標(biāo)簽
defer: 異步加載,在HTML解析完成后執(zhí)行。defer的實(shí)際效果與將代碼放在body底部類(lèi)似
async: 異步加載,加載完成后立即執(zhí)行
2、模塊按需加載
在SPA等業(yè)務(wù)邏輯比較復(fù)雜的系統(tǒng)中,需要根據(jù)路由來(lái)加載當(dāng)前頁(yè)面需要的業(yè)務(wù)模塊
按需加載,是一種很好的優(yōu)化網(wǎng)頁(yè)或應(yīng)用的方式。這種方式實(shí)際上是先把代碼在一些邏輯斷點(diǎn)處分離開(kāi),然后在一些代碼塊中完成某些操作后,立即引用或即將引用另外一些新的代碼塊。這樣加快了應(yīng)用的初始加載速度,減輕了它的總體體積,因?yàn)槟承┐a塊可能永遠(yuǎn)不會(huì)被加載
webpack 提供了兩個(gè)類(lèi)似的技術(shù),優(yōu)先選擇的方式是使用符合 ECMAScript 提案 的 import() 語(yǔ)法。第二種則是使用 webpack 特定的 require.ensure
3、使用資源預(yù)加載preload和資源預(yù)讀取prefetch
preload讓瀏覽器提前加載指定資源,需要執(zhí)行時(shí)再執(zhí)行,可以加速本頁(yè)面的加載速度
prefetch告訴瀏覽器加載下一頁(yè)面可能會(huì)用到的資源,可以加速下一個(gè)頁(yè)面的加載速度
4、資源懶加載與資源預(yù)加載
資源延遲加載也稱為懶加載,延遲加載資源或符合某些條件時(shí)才加載某些資源
資源預(yù)加載是提前加載用戶所需的資源,保證良好的用戶體驗(yàn)
資源懶加載和資源預(yù)加載都是一種錯(cuò)峰操作,在瀏覽器忙碌的時(shí)候不做操作,瀏覽器空間時(shí),再加載資源,優(yōu)化了網(wǎng)絡(luò)性能
1、避免使用層級(jí)較深的選擇器,或其他一些復(fù)雜的選擇器,以提高CSS渲染效率
2、避免使用CSS表達(dá)式,CSS表達(dá)式是動(dòng)態(tài)設(shè)置CSS屬性的強(qiáng)大但危險(xiǎn)方法,它的問(wèn)題就在于計(jì)算頻率很快。不僅僅是在頁(yè)面顯示和縮放時(shí),就是在頁(yè)面滾動(dòng)、乃至移動(dòng)鼠標(biāo)時(shí)都會(huì)要重新計(jì)算一次
3、元素適當(dāng)?shù)囟x高度或最小高度,否則元素的動(dòng)態(tài)內(nèi)容載入時(shí),會(huì)出現(xiàn)頁(yè)面元素的晃動(dòng)或位置,造成回流
4、給圖片設(shè)置尺寸。如果圖片不設(shè)置尺寸,首次載入時(shí),占據(jù)空間會(huì)從0到完全出現(xiàn),上下左右都可能位移,發(fā)生回流
5、不要使用table布局,因?yàn)橐粋€(gè)小改動(dòng)可能會(huì)造成整個(gè)table重新布局。而且table渲染通常要3倍于同等元素時(shí)間
6、能夠使用CSS實(shí)現(xiàn)的效果,盡量使用CSS而不使用JS實(shí)現(xiàn)
1、此外,將需要多次重繪的元素獨(dú)立為render layer渲染層,如設(shè)置absolute,可以減少重繪范圍
2、對(duì)于一些進(jìn)行動(dòng)畫(huà)的元素,使用硬件渲染,從而避免重繪和回流
1、緩存DOM
const div = document.getElementById('div')
由于查詢DOM比較耗時(shí),在同一個(gè)節(jié)點(diǎn)無(wú)需多次查詢的情況下,可以緩存DOM
2、減少DOM深度及DOM數(shù)量
HTML 中標(biāo)簽元素越多,標(biāo)簽的層級(jí)越深,瀏覽器解析DOM并繪制到瀏覽器中所花的時(shí)間就越長(zhǎng),所以應(yīng)盡可能保持 DOM 元素簡(jiǎn)潔和層級(jí)較少。
3、批量操作DOM
由于DOM操作比較耗時(shí),且可能會(huì)造成回流,因此要避免頻繁操作DOM,可以批量操作DOM,先用字符串拼接完畢,再用innerHTML更新DOM
4、批量操作CSS樣式
通過(guò)切換class或者使用元素的style.csstext屬性去批量操作元素樣式
5、在內(nèi)存中操作DOM
使用DocumentFragment對(duì)象,讓DOM操作發(fā)生在內(nèi)存中,而不是頁(yè)面上
6、DOM元素離線更新
對(duì)DOM進(jìn)行相關(guān)操作時(shí),例、appendChild等都可以使用Document Fragment對(duì)象進(jìn)行離線操作,帶元素“組裝”完成后再一次插入頁(yè)面,或者使用display:none 對(duì)元素隱藏,在元素“消失”后進(jìn)行相關(guān)操作
7、DOM讀寫(xiě)分離
瀏覽器具有惰性渲染機(jī)制,連接多次修改DOM可能只觸發(fā)瀏覽器的一次渲染。而如果修改DOM后,立即讀取DOM。為了保證讀取到正確的DOM值,會(huì)觸發(fā)瀏覽器的一次渲染。因此,修改DOM的操作要與訪問(wèn)DOM分開(kāi)進(jìn)行
8、事件代理
事件代理是指將事件監(jiān)聽(tīng)器注冊(cè)在父級(jí)元素上,由于子元素的事件會(huì)通過(guò)事件冒泡的方式向上傳播到父節(jié)點(diǎn),因此,可以由父節(jié)點(diǎn)的監(jiān)聽(tīng)函數(shù)統(tǒng)一處理多個(gè)子元素的事件
利用事件代理,可以減少內(nèi)存使用,提高性能及降低代碼復(fù)雜度
9、防抖和節(jié)流
使用函數(shù)節(jié)流(throttle)或函數(shù)去抖(debounce),限制某一個(gè)方法的頻繁觸發(fā)
10、及時(shí)清理環(huán)境
及時(shí)消除對(duì)象引用,清除定時(shí)器,清除事件監(jiān)聽(tīng)器,創(chuàng)建最小作用域變量,可以及時(shí)回收內(nèi)存
1、用對(duì)選擇器
選擇器的性能排序如下所示,盡量選擇性能更好的選擇器
id選擇器(#myid)
類(lèi)選擇器(.myclassname)
標(biāo)簽選擇器(div,h2,p)
相鄰選擇器(h2+p)
子選擇器(ul > li)
后代選擇器(li a)
通配符選擇器(*)
屬性選擇器(a[rel="external"])
偽類(lèi)選擇器(a:hover,li:nth-child)
2、使用requestAnimationFrame來(lái)替代setTimeout和setInterval
希望在每一幀剛開(kāi)始的時(shí)候?qū)?yè)面進(jìn)行更改,目前只有使用 requestAnimationFrame 能夠保證這一點(diǎn)。使用 setTimeout 或者 setInterval 來(lái)觸發(fā)更新頁(yè)面的函數(shù),該函數(shù)可能在一幀的中間或者結(jié)束的時(shí)間點(diǎn)上調(diào)用,進(jìn)而導(dǎo)致該幀后面需要進(jìn)行的事情沒(méi)有完成,引發(fā)丟幀
3、使用IntersectionObserver來(lái)實(shí)現(xiàn)圖片可視區(qū)域的懶加載
傳統(tǒng)的做法中,需要使用scroll事件,并調(diào)用getBoundingClientRect方法,來(lái)實(shí)現(xiàn)可視區(qū)域的判斷,即使使用了函數(shù)節(jié)流,也會(huì)造成頁(yè)面回流。使用IntersectionObserver,則沒(méi)有上述問(wèn)題
4、使用web worker
客戶端javascript一個(gè)基本的特性是單線程:比如,瀏覽器無(wú)法同時(shí)運(yùn)行兩個(gè)事件處理程序,它也無(wú)法在一個(gè)事件處理程序運(yùn)行的時(shí)候觸發(fā)一個(gè)計(jì)時(shí)器。Web Worker是HTML5提供的一個(gè)javascript多線程解決方案,可以將一些大計(jì)算量的代碼交由web Worker運(yùn)行,從而避免阻塞用戶界面,在執(zhí)行復(fù)雜計(jì)算和數(shù)據(jù)處理時(shí),這個(gè)API非常有用
但是,使用一些新的API的同時(shí),也要注意其瀏覽器兼容性
使用CommonsChunkPlugin插件,將公共模塊拆出來(lái),最終合成的文件能夠在最開(kāi)始的時(shí)候加載一次,便存到緩存中供后續(xù)使用。這會(huì)帶來(lái)速度上的提升,因?yàn)闉g覽器會(huì)迅速將公共的代碼從緩存中取出來(lái),而不是每次訪問(wèn)一個(gè)新頁(yè)面時(shí),再去加載一個(gè)更大的文件
webpack 4 將移除 CommonsChunkPlugin, 取而代之的是兩個(gè)新的配置項(xiàng) optimization.splitChunks 和 optimization.runtimeChunk
通過(guò)設(shè)置 optimization.splitChunks.chunks: "all" 來(lái)啟動(dòng)默認(rèn)的代碼分割配置項(xiàng)
webpack提供了兩種技術(shù)通過(guò)模塊的內(nèi)聯(lián)函數(shù)調(diào)用來(lái)分離代碼,優(yōu)先選擇的方式是,使用符合 ECMAScript 提案 的 import() 語(yǔ)法。第二種,則是使用 webpack 特定的 require.ensure
tree shaking 是一個(gè)術(shù)語(yǔ),通常用于描述移除 JavaScript 上下文中的未引用代碼(dead-code)。它依賴于 ES2015 模塊系統(tǒng)中的靜態(tài)結(jié)構(gòu)特性,例如 import 和 export。這個(gè)術(shù)語(yǔ)和概念實(shí)際上是興起于 ES2015 模塊打包工具 rollup
JS的tree shaking主要通過(guò)uglifyjs插件來(lái)完成,CSS的tree shaking主要通過(guò)purify CSS來(lái)實(shí)現(xiàn)的
1、將hash替換為chunkhash,這樣當(dāng)chunk不變時(shí),緩存依然有效
2、使用Name而不是id
每個(gè) module.id 會(huì)基于默認(rèn)的解析順序(resolve order)進(jìn)行增量。也就是說(shuō),當(dāng)解析順序發(fā)生變化,ID 也會(huì)隨之改變
下面來(lái)使用兩個(gè)插件解決這個(gè)問(wèn)題。第一個(gè)插件是 NamedModulesPlugin,將使用模塊的路徑,而不是數(shù)字標(biāo)識(shí)符。雖然此插件有助于在開(kāi)發(fā)過(guò)程中輸出結(jié)果的可讀性,然而執(zhí)行時(shí)間會(huì)長(zhǎng)一些。第二個(gè)選擇是使用 HashedModuleIdsPlugin,推薦用于生產(chǎn)環(huán)境構(gòu)建
使用html-webpack-inline-chunk-plugin插件將mainfest.js內(nèi)聯(lián)到html文件中
關(guān)于“WEB前端性能優(yōu)化的方法有哪些”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。