本文目錄:
- 1.網(wǎng)站整體優(yōu)化思路
- 2.前端性能優(yōu)化思路
- 3.如何理解回流和重繪殴蹄?
- 4.CDN 是什么臀蛛?
1.網(wǎng)站整體優(yōu)化思路
1.1.減少 HTTP 請(qǐng)求數(shù)量
在瀏覽器與服務(wù)器進(jìn)行通信時(shí)粪滤,主要是通過 HTTP 進(jìn)行通信缎谷。瀏覽器與服務(wù)器需要經(jīng)過三次握手派撕,每次握手需要花費(fèi)大量時(shí)間。而且不同瀏覽器對(duì)資源文件并發(fā)請(qǐng)求數(shù)量有限(不同瀏覽器允許并發(fā)數(shù))片挂,一旦 HTTP 請(qǐng)求數(shù)量達(dá)到一定數(shù)量邦马,資源請(qǐng)求就存在等待狀態(tài),這是很致命的宴卖,因此減少 HTTP 的請(qǐng)求數(shù)量可以很大程度上對(duì)網(wǎng)站性能進(jìn)行優(yōu)化。
1.1.1.CSS Sprites
國(guó)內(nèi)俗稱CSS精靈邻悬,這是將多張圖片合并成一張圖片達(dá)到減少HTTP請(qǐng)求的一種解決方案症昏,可以通過CSS的background屬性來訪問圖片內(nèi)容纳猪。這種方案同時(shí)還可以減少圖片總字節(jié)數(shù)臼予,需要注意的是片林,在現(xiàn)代化前端開發(fā)框架中筋现,小的圖片會(huì)被自動(dòng)轉(zhuǎn)換為base64格式的數(shù)據(jù)战惊,同時(shí)因?yàn)榫`圖高昂的維護(hù)成本咧织,導(dǎo)致精靈圖的應(yīng)用越來越少了
1.1.2.合并 CSS 和 JS 文件
現(xiàn)在前端有很多工程化打包工具舶赔,如:grunt评抚、gulp镀首、webpack等坟漱。為了減少 HTTP 請(qǐng)求數(shù)量,可以通過這些工具再發(fā)布前將多個(gè)CSS或者多個(gè)JS合并成一個(gè)文件更哄。
1.1.3.采用 lazyLoad
俗稱懶加載芋齿,可以控制網(wǎng)頁(yè)上的內(nèi)容在一開始無需加載,不需要發(fā)請(qǐng)求成翩,等到用戶操作真正需要的時(shí)候立即加載出內(nèi)容觅捆。這樣就控制了網(wǎng)頁(yè)資源一次性請(qǐng)求數(shù)量。
1.1.4.圖標(biāo)使用 IconFont 替換
IconFont可以很方便的自定義圖標(biāo)麻敌,同時(shí)圖標(biāo)庫(kù)非常的豐富栅炒,強(qiáng)烈推薦使用
1.2.控制資源文件加載優(yōu)先級(jí)
瀏覽器在加載HTML內(nèi)容時(shí),是將HTML內(nèi)容從上至下依次解析,解析到link或者script標(biāo)簽就會(huì)加載href或者src對(duì)應(yīng)鏈接內(nèi)容赢赊,為了第一時(shí)間展示頁(yè)面給用戶乙漓,就需要將CSS提前加載,不要受 JS 加載影響域携。
一般情況下都是CSS在頭部簇秒,JS在底部。
1.3.利用瀏覽器緩存
瀏覽器緩存是將網(wǎng)絡(luò)資源存儲(chǔ)在本地秀鞭,等待下次請(qǐng)求該資源時(shí)趋观,如果資源已經(jīng)存在就不需要到服務(wù)器重新請(qǐng)求該資源,直接在本地讀取該資源锋边。
1.4.減少重排(Reflow)
基本原理:重排是DOM的變化影響到了元素的幾何屬性(寬和高)皱坛,瀏覽器會(huì)重新計(jì)算元素的幾何屬性,會(huì)使渲染樹中受到影響的部分失效豆巨,瀏覽器會(huì)驗(yàn)證 DOM 樹上的所有其它結(jié)點(diǎn)的visibility屬性剩辟,這也是Reflow低效的原因。如果Reflow的過于頻繁往扔,CPU使用率就會(huì)急劇上升贩猎。
減少Reflow,如果需要在DOM操作時(shí)添加樣式萍膛,盡量使用 增加class屬性吭服,而不是通過style操作樣式。
1.5.針對(duì)老版本瀏覽器的優(yōu)化
- IE9以下瀏覽器無法識(shí)別HTML5新標(biāo)簽
引用html5shiv蝗罗,通過cdn的方式引用<script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js">
- IE6-IE8以及一些其他老版本瀏覽器不支持CSS3的媒體查詢
引用respond.js艇棕,通過cdn的方式引用<script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.js"></script>
1.6.預(yù)解析DNS
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="http://host_name_to_prefetch.com">
http協(xié)議下的頁(yè)面的所有a標(biāo)簽在瀏覽器中是默認(rèn)會(huì)進(jìn)行預(yù)解析的,但是https協(xié)議下很多瀏覽器不會(huì)預(yù)解析串塑,圖中的meta標(biāo)簽可以強(qiáng)制讓瀏覽器打開預(yù)解析
2.前端性能優(yōu)化思路
- HTML層級(jí)優(yōu)化
減少HTML的層級(jí)嵌套
減少空標(biāo)簽沼琉、無用標(biāo)簽的濫用
標(biāo)簽的Style屬性
標(biāo)簽的自定義屬性
合理利用模板引擎
link標(biāo)簽妙用
<img>標(biāo)簽
標(biāo)簽的src屬性及href屬性 - CSS層級(jí)優(yōu)化
樣式繼承與復(fù)用
盡量避免同一類名多次渲染
少用高優(yōu)先級(jí)選擇器,慎用!important
偽選擇器的妙用
忌層級(jí)過深的CSS選擇器
不用曾經(jīng)的CSS表達(dá)式
避免使用*通配符 - JavaScript層級(jí)優(yōu)化
如何及時(shí)清除定時(shí)器
合理使用CSS3動(dòng)畫
多利用事件代理委托桩匪,避免重復(fù)的事件監(jiān)聽
事件冒泡機(jī)制 - 資源加載優(yōu)化
DNS優(yōu)化
CDN部署與緩存
HTTP緩存
懶加載打瘪,分頁(yè)加載,區(qū)域無刷Aiax加載
CSS預(yù)處理及壓縮
JavaScript代碼壓縮處理
Base64的妙用
大吸祟、中瑟慈、小圖片方案及圖片壓縮
屏蔽開發(fā)時(shí)的調(diào)用、日志代碼 - 其他層級(jí)優(yōu)化
頁(yè)面渲染過程
控制交互請(qǐng)求
合理的數(shù)據(jù)結(jié)構(gòu)
有趣的異步
充分利用硬件GPU加速 - 建立完善的開發(fā)規(guī)范屋匕,提高代碼的渲染效率及可維護(hù)性葛碧。
- 壓縮代碼,合并代碼过吻,減少文件體積
- 減少圖片等靜態(tài)資源的體積进泼,并使用雪碧圖蔗衡,圖片懶加載等技術(shù)
- 可以使用url-loader把小圖片轉(zhuǎn)換成base64嵌入到JS或CSS中,減少加載次數(shù)
- 使用多域名負(fù)載網(wǎng)頁(yè)內(nèi)的多個(gè)文件乳绕、圖片
- 注意阻塞绞惦,將CSS樣式定義放置在文件頭部,JS腳本放在文件末尾
- 盡量減少頁(yè)面中重復(fù)的HTTP請(qǐng)求數(shù)量
- 服務(wù)器開啟gzip壓縮功能洋措,對(duì)用戶請(qǐng)求的頁(yè)面進(jìn)行壓縮處理
上面的這些回答太過籠統(tǒng)济蝉,并且大多數(shù)的前端都會(huì)這樣說,其實(shí)這個(gè)問題的拓展性非常強(qiáng)菠发,特別能體現(xiàn)出對(duì)前端領(lǐng)域的掌握深度王滤,網(wǎng)絡(luò)層面?瀏覽器渲染層面滓鸠?css雁乡、js執(zhí)行層面?框架層面糜俗?詳細(xì)說踱稍,越詳細(xì)越好
css:盡量使用id和class選擇器關(guān)聯(lián)所有樣式,盡量不使用行內(nèi)樣式和屬性選擇器悠抹,避免選擇器層級(jí)嵌套太深珠月,深入理解樣式繼承(font、color等文字類的樣式可繼承)楔敌。
3.如何理解回流和重繪桥温?
回流:
當(dāng)我們對(duì) DOM 的修改引發(fā)了 DOM 幾何尺寸的變化(比如修改元素的寬、高或隱藏元素等)時(shí)梁丘,瀏覽器需要重新計(jì)算元素的幾何屬性(其他元素的幾何屬性和位置也會(huì)因此受到影響),然后再將計(jì)算的結(jié)果繪制出來旺韭。這個(gè)過程就是回流(也叫重排)氛谜。
每次重排,必然會(huì)導(dǎo)致重繪区端,那么值漫,重排會(huì)在哪些情況下發(fā)生?
- 添加或者刪除可見的DOM元素
- 元素位置改變
- 元素尺寸改變
- 元素內(nèi)容改變(例如:一個(gè)文本被另一個(gè)不同尺寸的圖片替代)
- 頁(yè)面渲染初始化(這個(gè)無法避免)
- 瀏覽器窗口尺寸改變
重繪:
當(dāng)我們對(duì) DOM 的修改導(dǎo)致了樣式的變化织盼、卻并未影響其幾何屬性(比如修改了顏色或背景色)時(shí)杨何,瀏覽器不需重新計(jì)算元素的幾何屬性、直接為該元素繪制新的樣式(跳過了上圖所示的回流環(huán)節(jié))沥邻。這個(gè)過程叫做重繪危虱。由此我們可以看出,重繪不一定導(dǎo)致回流唐全,回流一定會(huì)導(dǎo)致重繪埃跷。
避免方法
1.減少使用行內(nèi)樣式蕊玷,使用clas關(guān)聯(lián)樣式
2.盡量不要在布局信息改變時(shí)做查詢(會(huì)導(dǎo)致渲染隊(duì)列強(qiáng)制刷新)
3.同一個(gè)DOM的多個(gè)屬性改變可以寫在一起(減少DOM訪問,同時(shí)把強(qiáng)制渲染隊(duì)列刷新的風(fēng)險(xiǎn)降為0)
4.如果要批量添加DOM弥雹,可以先讓元素脫離文檔流垃帅,操作完后再帶入文檔流,這樣只會(huì)觸發(fā)一次重排(fragment元素的應(yīng)用)
var fragment = document.createDocumentFragment();
var li = document.createElement('li');
li.innerHTML = 'apple';
fragment.appendChild(li);
var li = document.createElement('li');
li.innerHTML = 'watermelon';
fragment.appendChild(li);
document.getElementById('fruit').appendChild(fragment);
5.將需要多次重排的元素剪勿,position屬性設(shè)為absolute或fixed贸诚,這樣此元素就脫離了文檔流,它的變化不會(huì)影響到其他元素厕吉。例如有動(dòng)畫效果的元素就最好設(shè)置為絕對(duì)定位酱固。
2.對(duì)于需要經(jīng)常隱藏和顯示的內(nèi)容在頁(yè)面布局寫入后使用display:none;屬性進(jìn)行操作,這樣不會(huì)引發(fā)頁(yè)面的回流重繪赴涵,盡量減少DOM操作媒怯。
3.避免頻繁讀取會(huì)引發(fā)回流重繪的元素,如果需要最好是緩存起來
5.減少table布局以及css表達(dá)式(如calc())的使用髓窜。
4.CDN 是什么扇苞?
CDN,中文名叫做「內(nèi)容分發(fā)網(wǎng)絡(luò)」寄纵,它的作用是減少傳播時(shí)延鳖敷,找最近的節(jié)點(diǎn),實(shí)際上程拭,盡管互聯(lián)網(wǎng)幫助我們實(shí)現(xiàn)了地球村定踱,但是從中國(guó)到日本和從中國(guó)到中國(guó)臺(tái)灣的時(shí)延仍舊是不一樣的,
CDN 的優(yōu)點(diǎn)
1.訪問加速
2.減輕源站(服務(wù)器)負(fù)載
一個(gè)非常簡(jiǎn)單就能想明白的問題恃鞋,如果 CDN 已經(jīng)能幫我返回?cái)?shù)據(jù)了崖媚,那么請(qǐng)求就不會(huì)到達(dá)源站,源站(服務(wù)器)的負(fù)載就減輕了恤浪。
3.抗住攻擊
既然源站的負(fù)載被減輕了畅哑,那么在受到 DDOS 攻擊的時(shí)候,也能談笑風(fēng)生水由。
**CDN 的缺點(diǎn)荠呐?
1.首先可控性差,比如某個(gè)依賴節(jié)點(diǎn)掛了砂客,導(dǎo)致項(xiàng)目無法正常運(yùn)行泥张,會(huì)直接導(dǎo)致用戶的損失,尤其是體量大的公司依賴 CDN 進(jìn)行靜態(tài)資源管理的時(shí)候鞠值,發(fā)生這樣的事情后果會(huì)非常嚴(yán)重媚创。
2.其次,便宜沒好貨:本來在只有網(wǎng)宿而沒有阿里云的時(shí)代彤恶,CDN 是很昂貴的筝野,阿里騰訊在拉低 CDN 價(jià)格的同時(shí)晌姚,也拉低了 CDN 的質(zhì)量,部分節(jié)點(diǎn)的訪問質(zhì)量不太高會(huì)導(dǎo)致有些用戶訪問的網(wǎng)絡(luò)質(zhì)量非常差歇竟。
然后挥唠,一個(gè)微小的科普:什么是混合 CDN——混合 CDN 這個(gè)名詞看著很高端,實(shí)際上就是焕议,我們用了多家廠商的 CDN宝磨,可能也包括自己建的,然后誰好的選誰盅安,但是有的時(shí)候反而會(huì)造成服務(wù)不可控唤锉,進(jìn)一步劣化 CDN 的質(zhì)量。
CDN 這個(gè)東西本質(zhì)就是一個(gè)緩存别瞭,只是這個(gè)緩存離你特別特別的近窿祥,作為用戶還是開發(fā)都能從中享受到一點(diǎn)福利,但作為一個(gè)服務(wù)于企業(yè)的開發(fā)人員蝙寨,不僅要考慮 CDN 的優(yōu)點(diǎn)晒衩,也要知道 CDN 給我們帶來的坑,這樣才能成為靠譜的 CDN 使用者墙歪。