web前端性能優(yōu)化面試題(一)

一、瀏覽器訪問優(yōu)化

瀏覽器請求處理流程圖

1涮毫、減少HTTP請求
http協(xié)議是無狀態(tài)的應(yīng)用層協(xié)議翘魄,意味著每次http請求都需要建立通信鏈路、進行數(shù)據(jù)傳輸,而在服務(wù)器端谋币,每個http都需要啟動獨立的線程去處理仗扬。這些通信和服務(wù)的開銷都很昂貴,減少http請求的數(shù)目可有效提高訪問性能蕾额。
1)合并CSS建炫、合并javascript听怕、合并圖片。將瀏覽器一次訪問需要的javascript和CSS合并成一個文件,這樣瀏覽器就只需要一次請求赠法。圖片也可以合并,多張圖片合并成一張陶舞,如果每張圖片都有不同的超鏈接捡多,可通過CSS偏移響應(yīng)鼠標(biāo)點擊操作,構(gòu)造不同的URL筐眷。
2)合理設(shè)置緩存黎烈。很少變化的圖片資源可以直接通過 HTTP Header中的Expires設(shè)置一個很長的過期頭 ;變化不頻繁而又可能會變的資源可以使用 Last-Modifed來做請求驗證。盡可能的讓資源能夠在緩存中待得更久匀谣。
2照棋、使用瀏覽器緩存
1) 將更新頻率比較低的CSS、javascript武翎、logo烈炭、圖標(biāo)等靜態(tài)資源文件緩存在瀏覽器中,避免頻繁的http請求宝恶。通過設(shè)置http頭中的cache-control和expires的屬性符隙,可設(shè)定瀏覽器緩存,緩存時間可以是數(shù)天垫毙,甚至是幾個月霹疫。
2)當(dāng)靜態(tài)資源文件發(fā)生變化時,通過生成一個新的JS文件并更新HTML文件中的引用來更新js文件综芥,避免直接更新js文件中的內(nèi)容丽蝎。
3)使用瀏覽器緩存策略的網(wǎng)站在更新靜態(tài)資源時,應(yīng)采用逐量更新的方法膀藐,比如需要更新10個圖標(biāo)文件屠阻,不宜把10個文件一次全部更新,而是應(yīng)該一個文件一個文件逐步更新额各,并有一定的間隔時間国觉,避免用戶瀏覽器忽然大量緩存失效集中更新緩存虾啦,造成服務(wù)器負載驟增蛉加、網(wǎng)絡(luò)堵塞的情況蚜枢。
3、啟用壓縮
在服務(wù)器端對文件進行壓縮针饥,在瀏覽器端對文件解壓縮可有效減少通信傳輸?shù)臄?shù)據(jù)量厂抽。如果可以的話,盡可能的將外部的腳本丁眼、樣式進行合并筷凤,多個合為一個。文本文件的壓縮效率可達到80%以上苞七,因此HTML藐守、CSS、javascript文件啟用GZip壓縮可達到較好的效果蹂风。但是壓縮對服務(wù)器和瀏覽器產(chǎn)生一定的壓力卢厂,在通信帶寬良好,而服務(wù)器資源不足的情況下要權(quán)衡考慮惠啄。
4慎恒、CSS Sprites
合并CSS圖片,減少HTTP請求數(shù)撵渡。
5融柬、LazyLoad Images
這條策略實際上并不一定能減少 HTTP請求數(shù),但是卻能在某些條件下或者頁面剛加載時減少 HTTP請求數(shù)趋距。對于圖片而言粒氧,在頁面剛加載的時候可以只加載第一屏,當(dāng)用戶繼續(xù)往后滾屏的時候才加載后續(xù)的圖片节腐。這樣一來外盯,假如用戶只對第一屏的內(nèi)容感興趣時,那剩余的圖片請求就都節(jié)省了翼雀。
6饱苟、CSS放在頁面最上部,javascript放在頁面最下面
瀏覽器會在下載完成全部CSS之后才對整個頁面進行渲染锅纺,因此最好的做法是將CSS放在頁面最上面,讓瀏覽器盡快下載CSS肋殴。如果將 CSS放在其他地方比如 BODY中囤锉,則瀏覽器有可能還未下載和解析到 CSS就已經(jīng)開始渲染頁面了,這就導(dǎo)致頁面由無 CSS狀態(tài)跳轉(zhuǎn)到 CSS狀態(tài)护锤,用戶體驗比較糟糕官地,所以可以考慮將CSS放在HEAD中。
Javascript則相反烙懦,瀏覽器在加載javascript后立即執(zhí)行驱入,有可能會阻塞整個頁面,造成頁面顯示緩慢,因此javascript最好放在頁面最下面亏较。但如果頁面解析時就需要用到j(luò)avascript莺褒,這時放到底部就不合適了。
7雪情、Lazy Load Javascript(只有在需要加載的時候加載遵岩,在一般情況下并不加載信息內(nèi)容。)
隨著 Javascript框架的流行巡通,越來越多的站點也使用起了框架尘执。不過,一個框架往往包括了很多的功能實現(xiàn)宴凉,這些功能并不是每一個頁面都需要的誊锭,如果下載了不需要的腳本則算得上是一種資源浪費
-既浪費了帶寬又浪費了執(zhí)行花費的時間。目前的做法大概有兩種弥锄,一種是為那些流量特別大的頁面專門定制一個專用的 mini版框架丧靡,另一種則是 Lazy Load。
8叉讥、異步請求Callback(就是將一些行為樣式提取出來窘行,慢慢的加載信息的內(nèi)容)
在某些頁面中可能存在這樣一種需求,需要使用 script標(biāo)簽來異步的請求數(shù)據(jù)图仓。類似:

<span style="font-size:14px;">/*Callback 函數(shù)*/  
    function myCallback(info){   
        //do something here   
    }   
 HTML:  
  Callback返回的內(nèi)容 :  
   myCallback('Hello world!');  
</span>  

像以上這種方式直接在頁面上寫 <script> 對頁面的性能也是有影響的罐盔,即增加了頁面首次加載的負擔(dān),推遲了 DOMLoaded和window.onload 事件的觸發(fā)時機救崔。如果時效性允許的話惶看,可以考慮在 DOMLoaded事件觸發(fā)的時候加載,或者使用 setTimeout方式來靈活的控制加載的時機六孵。
9纬黎、減少cookie傳輸
一方面,cookie包含在每次請求和響應(yīng)中劫窒,太大的cookie會嚴重影響數(shù)據(jù)傳輸本今,因此哪些數(shù)據(jù)需要寫入cookie需要慎重考慮,盡量減少cookie中傳輸?shù)臄?shù)據(jù)量主巍。另一方面冠息,對于某些靜態(tài)資源的訪問,如CSS孕索、script等逛艰,發(fā)送cookie沒有意義,可以考慮靜態(tài)資源使用獨立域名訪問搞旭,避免請求靜態(tài)資源時發(fā)送cookie散怖,減少cookie傳輸次數(shù)菇绵。
10、Javascript代碼優(yōu)化
(1). DOM  
a.HTML Collection(HTML收集器镇眷,返回的是一個數(shù)組內(nèi)容信息)

在腳本中 document.images咬最、document.forms、getElementsByTagName()返回的都是HTMLCollection類型的集合偏灿,在平時使用的時候大多將它作為數(shù)組來使用丹诀,因為它有 length屬性,也可以使用索引訪問每一個元素翁垂。不過在訪問性能上則比數(shù)組要差很多铆遭,原因是這個集合并不是一個靜態(tài)的結(jié)果,它表示的僅僅是一個特定的查詢沿猜,每次訪問該集合時都會重新執(zhí)行這個查詢從而更新查詢結(jié)果枚荣。所謂的“訪問集合” 包括讀取集合的 length屬性、訪問集合中的元素啼肩。

因此橄妆,當(dāng)你需要遍歷 HTML Collection的時候,盡量將它轉(zhuǎn)為數(shù)組后再訪問祈坠,以提高性能害碾。即使不轉(zhuǎn)換為數(shù)組,也請盡可能少的訪問它赦拘,例如在遍歷的時候可以將 length屬性慌随、成員保存到局部變量后再使用局部變量

b. Reflow & Repaint

除了上面一點之外躺同, DOM操作還需要考慮瀏覽器的Reflow和Repaint 阁猜,因為這些都是需要消耗資源的。
(2). 慎用 with 
with(obj){ p = 1};
代碼塊的行為實際上是修改了代碼塊中的執(zhí)行環(huán)境 蹋艺,將obj放在了其作用域鏈的最前端剃袍,在 with代碼塊中訪問非局部變量是都是先從 obj上開始查找,如果沒有再依次按作用域鏈向上查找捎谨,因此使用 with相當(dāng)于增加了作用域鏈長度民效。而每次查找作用域鏈都是要消耗時間的,過長的作用域鏈會導(dǎo)致查找性能下降涛救。

因此畏邢,除非你能肯定在 with代碼中只訪問 obj中的屬性,否則慎用 with州叠,替代的可以使用局部變量緩存需要訪問的屬性棵红。
(3). 避免使用 eval和 Function
每次 eval
或Function 構(gòu)造函數(shù)作用于字符串表示的源代碼時凶赁,腳本引擎都需要將源代碼轉(zhuǎn)換成可執(zhí)行代碼咧栗。這是很消耗資源的操作 —— 通常比簡單的函數(shù)調(diào)用慢 100倍以上逆甜。

eval 函數(shù)效率特別低,由于事先無法知曉傳給 eval 的字符串中的內(nèi)容致板,eval在其上下文中解釋要處理的代碼交煞,也就是說編譯器無法優(yōu)化上下文,因此只能有瀏覽器在運行時解釋代碼斟或。這對性能影響很大素征。

Function 構(gòu)造函數(shù)比 eval略好,因為使用此代碼不會影響周圍代碼 ;但其速度仍很慢萝挤。

此外御毅,使用 eval和 Function也不利于Javascript 壓縮工具執(zhí)行壓縮。
(4). 減少作用域鏈查找
前文談到了作用域鏈查找問題怜珍,這一點在循環(huán)中是尤其需要注意的問題端蛆。如果在循環(huán)中需要訪問非本作用域下的變量時請在遍歷之前用局部變量緩存該變量,并在遍歷結(jié)束后再重寫那個變量酥泛,這一點對全局變量尤其重要今豆,因為全局變量處于作用域鏈的最頂端,訪問時的查找次數(shù)是最多的柔袁。

低效率的寫法:

<span style="font-size:14px;">// 全局變量   
var globalVar = 1;   
function myCallback(info){   
    for( var i = 100000; i--;){   
        //每次訪問 globalVar 都需要查找到作用域鏈最頂端呆躲,本例中需要訪問 100000 次   
        globalVar += i;   
    }  
}   
</span> 
<span style="font-size:14px;">// 全局變量   
var globalVar = 1;   
function myCallback(info){   
    //局部變量緩存全局變量   
    var localVar = globalVar;   
    for( var i = 100000; i--;){   
    //訪問局部變量是最快的   
    localVar += i;   
    }   
    //本例中只需要訪問 2次全局變量  
    在函數(shù)中只需要將 globalVar中內(nèi)容的值賦給localVar 中  
    globalVar = localVar;   
}  
</span>

此外,要減少作用域鏈查找還應(yīng)該減少閉包的使用捶索。
(5). 數(shù)據(jù)訪問
  Javascript中的數(shù)據(jù)訪問包括直接量 (字符串插掂、正則表達式 )、變量情组、對象屬性以及數(shù)組燥筷,其中對直接量和局部變量的訪問是最快的,對對象屬性以及數(shù)組的訪問需要更大的開銷院崇。當(dāng)出現(xiàn)以下情況時肆氓,建議將數(shù)據(jù)放入局部變量:

a. 對任何對象屬性的訪問超過 1次

b. 對任何數(shù)組成員的訪問次數(shù)超過 1次

另外,還應(yīng)當(dāng)盡可能的減少對對象以及數(shù)組深度查找底瓣。
(6). 字符串拼接
在 Javascript中使用”+”號來拼接字符串效率是比較低的谢揪,因為每次運行都會開辟新的內(nèi)存并生成新的字符串變量,然后將拼接結(jié)果賦值給新變量捐凭。與之相比更為高效的做法是使用數(shù)組的 join方法拨扶,即將需要拼接的字符串放在數(shù)組中最后調(diào)用其 join方法得到結(jié)果。不過由于使用數(shù)組也有一定的開銷茁肠,因此當(dāng)需要拼接的字符串較多的時候可以考慮用此方法患民。
10、CSS選擇符優(yōu)化
在大多數(shù)人的觀念中垦梆,都覺得瀏覽器對 CSS選擇符的解析式從左往右進行的匹颤,例如

#toc A { color: #444; }這樣一個選擇符仅孩,如果是從右往左解析則效率會很高,因為第一個 ID選擇基本上就把查找的范圍限定了印蓖,但實際上瀏覽器對選擇符的解析是從右往左進行的辽慕。如上面的選擇符,瀏覽器必須遍歷查找每一個 A標(biāo)簽的祖先節(jié)點赦肃,效率并不像之前想象的那樣高溅蛉。根據(jù)瀏覽器的這一行為特點,在寫選擇符的時候需要注意很多事項他宛。
11船侧、CDN加速
CDN(contentdistribute network,內(nèi)容分發(fā)網(wǎng)絡(luò))的本質(zhì)仍然是一個緩存厅各,而且將數(shù)據(jù)緩存在離用戶最近的地方勺爱,使用戶以最快速度獲取數(shù)據(jù),即所謂網(wǎng)絡(luò)訪問第一跳讯检,如下圖琐鲁。

Paste_Image.png

由于CDN部署在網(wǎng)絡(luò)運營商的機房,這些運營商又是終端用戶的網(wǎng)絡(luò)服務(wù)提供商人灼,因此用戶請求路由的第一跳就到達了CDN服務(wù)器围段,當(dāng)CDN中存在瀏覽器請求的資源時投放,從CDN直接返回給瀏覽器灸芳,最短路徑返回響應(yīng)烙样,加快用戶訪問速度,減少數(shù)據(jù)中心負載壓力蛤肌。

CDN緩存的一般是靜態(tài)資源裸准,如圖片炒俱、文件权悟、CSS僵芹、script腳本小槐、靜態(tài)網(wǎng)頁等,但是這些文件訪問頻度很高件豌,將其緩存在CDN可極大改善網(wǎng)頁的打開速度茧彤。
2疆栏、反向代理
傳統(tǒng)代理服務(wù)器位于瀏覽器一側(cè),代理瀏覽器將http請求發(fā)送到互聯(lián)網(wǎng)上珠洗,而反向代理服務(wù)器位于網(wǎng)站機房一側(cè)许蓖,代理網(wǎng)站web服務(wù)器接收http請求膊爪。如下圖所示:

Paste_Image.png

論壇網(wǎng)站米酬,把熱門詞條淮逻、帖子爬早、博客緩存在反向代理服務(wù)器上加速用戶訪問速度,當(dāng)這些動態(tài)內(nèi)容有變化時饶米,通過內(nèi)部通知機制通知反向代理緩存失效,反向代理會重新加載最新的動態(tài)內(nèi)容再次緩存起來照瘾。
此外匈棘,反向代理也可以實現(xiàn)負載均衡的功能析命,而通過負載均衡構(gòu)建的應(yīng)用集群可以提高系統(tǒng)總體處理能力,進而改善網(wǎng)站高并發(fā)情況下的性能鹃愤。

參考博文:web前端性能優(yōu)化總結(jié)

二簇搅、湃硗拢客網(wǎng)Flappy Bird是風(fēng)靡一時的手機游戲瘩将,玩家要操作一只小鳥穿過無窮無盡的由鋼管組成的障礙。如果要你在HTML前端開發(fā)這個游戲凹耙,為了保證游戲的流暢運行,并長時間運行也不會崩潰肖抱,請列舉開發(fā)要注意的性能問題和解決的方法虐沥。

①背景的卷軸效果優(yōu)化欲险。背景不能是無限長的圖片拼接天试,必須及時釋放掉不在畫面中的DOM元素
將復(fù)雜運算從主UI線程中解耦。比如場景中小鳥的運動軌跡带兜、碰撞算法等枫笛,不能和UI動畫同時進行「照眨可以使用webworker開啟單獨的線程處理復(fù)雜運算刑巧。
③注意內(nèi)存泄漏和回收。使用對象池管理內(nèi)存,提高內(nèi)存檢測和垃圾回收啊楚。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吠冤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子恭理,更是在濱河造成了極大的恐慌拯辙,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颜价,死亡現(xiàn)場離奇詭異涯保,居然都是意外死亡,警方通過查閱死者的電腦和手機拍嵌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來循诉,“玉大人横辆,你說我怎么就攤上這事∏衙ǎ” “怎么了狈蚤?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長划纽。 經(jīng)常有香客問我脆侮,道長,這世上最難降的妖魔是什么勇劣? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任靖避,我火速辦了婚禮,結(jié)果婚禮上比默,老公的妹妹穿的比我還像新娘幻捏。我一直安慰自己,他們只是感情好命咐,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布篡九。 她就那樣靜靜地躺著,像睡著了一般醋奠。 火紅的嫁衣襯著肌膚如雪榛臼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天窜司,我揣著相機與錄音沛善,去河邊找鬼。 笑死塞祈,一個胖子當(dāng)著我的面吹牛路呜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼胀葱,長吁一口氣:“原來是場噩夢啊……” “哼漠秋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起抵屿,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤庆锦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后轧葛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體搂抒,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年尿扯,在試婚紗的時候發(fā)現(xiàn)自己被綠了求晶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡衷笋,死狀恐怖芳杏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情辟宗,我是刑警寧澤爵赵,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站泊脐,受9級特大地震影響空幻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜容客,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一秕铛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧缩挑,春花似錦如捅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至士袄,卻和暖如春悲关,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背娄柳。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工寓辱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赤拒。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓秫筏,卻偏偏與公主長得像诱鞠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子这敬,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 網(wǎng)站的劃分一般為二:前端和后臺航夺。我們可以理解成后臺是用來實現(xiàn)網(wǎng)站的功能的,比如:實現(xiàn)用戶注冊崔涂,用戶能夠為文章發(fā)表評...
    ConRon閱讀 790評論 0 0
  • AJax 優(yōu)化 緩存 Ajax 請求盡量使用GET, 僅取決于cookie數(shù)量 Cookie 優(yōu)化 減少Cooki...
    KeKeMars閱讀 9,361評論 5 89
  • <a name='html'>HTML</a> Doctype作用阳掐?標(biāo)準(zhǔn)模式與兼容模式各有什么區(qū)別? (1)、<...
    clark124閱讀 3,497評論 1 19
  • 大學(xué)畢業(yè)后我經(jīng)過考試被分配到了一所偏遠的農(nóng)村學(xué)校任教冷蚂,當(dāng)時我去的時候?qū)W校有一百多個學(xué)生缭保,十幾個老師。 也許我是新老...
    孤影作伴閱讀 1,567評論 0 2
  • 首先要有一種"雙贏思維"。 一山不是只能容二虎隆夯,不要把自己的利益建立在損害他人的利益上钳恕,而是需要建立利己利人的人際...
    許CC閱讀 1,120評論 0 4