前端性能優(yōu)化(三)——傳統(tǒng) JavaScript 優(yōu)化的誤區(qū)

注:本文是純技術(shù)探討文鸦致,無圖無笑點(diǎn)潮剪,希望您喜歡

一.前言

軟件行業(yè)極其缺乏前端人才這是圈內(nèi)的共識了涣楷,某種程度上講,同等水平前端的工資都要比后端高上不少抗碰,而圈內(nèi)的另一項(xiàng)共識則是——網(wǎng)頁是公司的臉面狮斗!

幾年前,谷歌的一項(xiàng)統(tǒng)計(jì)表明弧蝇,如果亞馬遜頁面加載每慢 100ms碳褒,將影響他們 1% 的收入;如果谷歌頁面加載慢 500ms看疗,流量將銳減 20%沙峻,這個(gè)數(shù)據(jù)現(xiàn)在必將更加恐怖!

前端高性能優(yōu)化(一)两芳、(二)中摔寨,筆者介紹了一些關(guān)于前端優(yōu)化的技術(shù),這些技術(shù)都依賴于前人的辛苦努力怖辆,但我們?nèi)砸靼椎氖鞘歉矗岸说那闆r十分復(fù)雜,優(yōu)化前端性能是必須因地制宜疗隶、因時(shí)制宜佑笋。

在本篇文章中翼闹,主要介紹的就是在一些條件下斑鼻,傳統(tǒng)優(yōu)化 JavaScript 的技術(shù)并不像我們認(rèn)為的那樣適用。

二.JavaScript 模塊化誤區(qū)

加快 JavaScript 加載和執(zhí)行的速度猎荠,一直是前端優(yōu)化的一個(gè)熱點(diǎn)坚弱。因此我們先來說下 JavaScript 模塊化技術(shù)的相關(guān)知識,希望通過實(shí)踐來體現(xiàn)模塊化技術(shù)在使用時(shí)的注意事項(xiàng)关摇,避免濫用荒叶。

為什么會有模塊化技術(shù)?

長久以來输虱,編寫 JavaScript 一直以文件為單位些楣,一般一個(gè)類型的 JavaScript 功能代碼會被放在同一個(gè)文件里。在一個(gè)頁面里宪睹,引用的文件一般是寫死的愁茁,也就是不管頁面用不用,只要你引入了這個(gè)文件亭病,這個(gè)文件就會被加載鹅很。

舉個(gè)例子,我們開發(fā)了一個(gè)內(nèi)容復(fù)雜罪帖、功能強(qiáng)大的頁面促煮,JavaScript 文件大到 500K邮屁,當(dāng)頁面費(fèi)勁的把這 500K 加載下來,然而用戶真正只使用了這 500K 里極少的一部分功能菠齿,但我們又不得不把這 500K 加載下來佑吝,因?yàn)椴煌挠脩羰褂玫墓δ茳c(diǎn)可能不一樣,我們必須滿足所有需求绳匀。

而模塊化技術(shù)提出 按需加載迹蛤,也就是當(dāng)用戶觸發(fā)該功能的時(shí)候,那個(gè)功能才真正的被加載襟士。好比 500K 被拆成了 50 個(gè)模塊盗飒,每個(gè)模塊 10K,當(dāng)用戶觸發(fā)一個(gè)功能時(shí)陋桂,加載 10K逆趣,再觸發(fā)再加載,以這樣懶加載的方式來加載模塊嗜历,可以很大的提高響應(yīng)速度宣渗。這樣,管理模塊懶加載的技術(shù)也隨之誕生梨州。

模塊化技術(shù)并非到處靠譜!!

之前筆者在網(wǎng)上搜索到了一個(gè)模塊化技術(shù):SeaJS痕囱。它是一個(gè)遵循 CommonJS 規(guī)范的 JavaScript 模塊加載框架,可以實(shí)現(xiàn) JavaScript 的模塊化開發(fā)及加載機(jī)制暴匠。與 JQuery 等 JavaScript 框架不同鞍恢,SeaJS 不會擴(kuò)展封裝語言特性,而只是實(shí)現(xiàn) JavaScript 的模塊化及按模塊加載每窖。

SeaJS 的主要目的是令 JavaScript 開發(fā)模塊化并可以輕松愉悅進(jìn)行加載帮掉,將前端工程師從繁重的 JavaScript 文件及對象依賴處理中解放出來,可以專注于代碼本身的邏輯窒典。說白了就是有 Lazy Load 的特性蟆炊,用到某模塊時(shí),SeaJS 才會去加載模塊的 JS 文件瀑志。我們可以按功能劃分多個(gè)模塊涩搓,觸發(fā)模塊功能時(shí),SeaJS 先加載功能模塊的文件劈猪,然后執(zhí)行相應(yīng)的功能昧甘。

這個(gè) SeaJS 擁有的特性,初看非常吸引人岸霹,它可以說是新定義了一種開發(fā)和管理 JavaScript 文件的模式疾层。遵循這個(gè)模式,你會享受起 JavaScript 的開發(fā)贡避。

實(shí)踐證明痛黎,它也的確可以使 JavaScript 模塊化予弧,根據(jù)功能劃分模塊,每個(gè)模塊對應(yīng)一個(gè) JavaScript 文件湖饱,當(dāng)執(zhí)行到模塊的功能掖蛤,或者你需要加載模塊時(shí),模塊才會被下載井厌,同時(shí)不會造成重復(fù)下載蚓庭。這一切看起來如此的合理,如此的順暢仅仆。器赞。。墓拜。港柜。

但是在使用后發(fā)現(xiàn)了一些 問題:由于當(dāng)時(shí)開發(fā)的網(wǎng)站功能相對簡單,JavaScript 文件并不是非常大咳榜,過多的模塊夏醉,反而會導(dǎo)致總加載的時(shí)間變多了。

由于是 Lazy Load 特性涌韩,不適合的模塊劃分導(dǎo)致網(wǎng)站出現(xiàn)反應(yīng)慢的現(xiàn)象畔柔,原因是得先加載模塊的文件,才能執(zhí)行模塊的功能臣樱。當(dāng)網(wǎng)絡(luò)情況不好時(shí)靶擦,該現(xiàn)象表現(xiàn)的更為嚴(yán)重!G嬗佟奢啥!

可以說秸仙,問題出在了對新技術(shù)的不了解上嘴拢,從而出現(xiàn)了問題,預(yù)期是 SeaJS 可以處理 JavaScript 優(yōu)化的問題寂纪,因?yàn)樗哂斜苊饧虞d不必要模塊的功能席吴,結(jié)果反而南轅北轍。

總結(jié)

雖然嘗試出現(xiàn)了問題捞蛋,但是孝冒,收獲也是巨大的,簡單來說就是以下兩點(diǎn):

1)因地制宜拟杉,根據(jù)實(shí)際需要使用模塊化技術(shù)庄涡,切勿跟風(fēng)技術(shù),在自己沒有完全掌握時(shí)搬设,謹(jǐn)慎用于產(chǎn)品中穴店。

2)模塊如果是懶加載的撕捍,粒度不能太小,也就是模塊不能太小泣洞。

根據(jù) 大功能來劃分模塊 也是一個(gè)不錯(cuò)的嘗試忧风。

筆者嘗試將所有模塊劃分為 基礎(chǔ)模塊功能模塊 ,基礎(chǔ)模塊包括頁面頭部球凰,尾部相關(guān)的公共部分狮腿,功能模塊則根據(jù)前后臺劃分,前臺部分呕诉,又根據(jù)具體的頁面來劃分缘厢,能合并到一起的,就合并成一個(gè)模塊甩挫,增加粒度昧绣。結(jié)果 JavaScript 文件減少,也達(dá)到了預(yù)期的效果。

從實(shí)際體驗(yàn)來看,對于流量不大的網(wǎng)站來說嗡靡,沒有必要使用懶加載 JavaScript 的相關(guān)技術(shù)凌净,因?yàn)楸旧?JavaScript 文件就不是非常大。因此在網(wǎng)頁加載時(shí)秧了,就可以先加載所需要的模塊。避免不必要的延遲。

三.JavaScript 的位置問題

這一部分税灌,我們來說說 JavaScript 的位置問題對網(wǎng)頁網(wǎng)站性能的影響。

為什么要考慮位置問題亿虽?

其實(shí)不管是 CSS 還是 JavaScript菱涤,都需要考慮位置的問題,因?yàn)?HTML 的渲染和加載順序是從上往下洛勉,也就是如果前面插入了 JavaScript 的引用粘秆,那么必須等到這個(gè) JavaScript 下載完畢才會渲染后續(xù)的部分。

因此 JavaScript 的插入位置就成為一個(gè)值得考慮的問題收毫,因?yàn)椴贿m合的位置可能引起渲染的延遲等攻走,造成不好的用戶體驗(yàn)。

傳統(tǒng)方案帶來的問題和思考

CSS 放在頭部此再,JavaScript 放在尾部昔搂,這是傳統(tǒng)的經(jīng)驗(yàn),它的好處是可以讓頁面優(yōu)先渲染, 從而頁面可以快速顯示输拇。

但有事實(shí)往往沒有我們預(yù)想的那么美好摘符。

有的時(shí)候會出現(xiàn)這么一種情況:當(dāng)頁面已經(jīng)渲染完畢時(shí),我們立刻去使用網(wǎng)站的功能,但很多時(shí)候 功能按鈕會沒有反應(yīng)逛裤。原因也很簡單蠢古,就是 JavaScript 放在頁面的尾部,還沒來得及加載别凹。草讶。。炉菲。

這就糾結(jié)了堕战。。拍霜。嘱丢。

兩種 JavaScript 放置方式,一種放在頭部祠饺,一種放在尾部(暫時(shí)忽略部分放在頭部越驻,部分放在尾部的方式),一個(gè)犧牲了渲染速度道偷,一個(gè)犧牲了用戶體驗(yàn)缀旁。所以很多時(shí)候 js 的問題我們需要做權(quán)衡。

對一般的小型網(wǎng)站來說勺鸦,用戶體驗(yàn)問題要遠(yuǎn)遠(yuǎn)大于頁面渲染的問題并巍,就比如上文提到的那種功能按鈕不可用的情況。而且换途,如果 JavaScript 不是很大的話懊渡,放在頭部就很好,既不會有太久的頁面空白军拟,也能讓其優(yōu)先加載剃执,二者得到了很好的平衡。

因此懈息,很多經(jīng)驗(yàn)上的東西并不是絕對的肾档,一定要根據(jù)實(shí)際的情況,包括功能特點(diǎn)漓拾、服務(wù)器網(wǎng)絡(luò)情況等來綜合考慮阁最。

為此,筆者寫下一個(gè)自認(rèn)為較為合理的位置選擇方案骇两,僅供參考。

圖 1. 判斷 JavaScript 放置位置決策表


從上面的分類介紹姜盈,我們也可以看出低千,將功能代碼按類型歸類到不同的 JavaScript 文件是多么的重要,比如應(yīng)該放頭部和應(yīng)該放尾部的代碼,最好不要合并在一起,不要等到出問題要優(yōu)化的時(shí)候再去整理和重構(gòu)示血,這樣會增加很多不必要的工作量棋傍。

這不僅僅是為自己工作負(fù)責(zé),也是為后面要讀你代碼的新人負(fù)責(zé)难审。養(yǎng)成好的設(shè)計(jì)編碼習(xí)慣瘫拣,也是技術(shù)積累的一部分。最后再根據(jù) JavaScript 文件的功能類型告喊,來決定是放在頁面的頭部還是尾部麸拄。

四.怎樣確定是不是 JavaScript 的問題?

這個(gè)問題在之前的前端高性能優(yōu)化(一)黔姜、(二)中也都簡單的說過拢切,之所以在這再次提及是因?yàn)榇_實(shí)覺得這個(gè)工具用著很舒服。

沒錯(cuò)秆吵,就是舒服淮椰。

隨著信息爆炸時(shí)代的到來,網(wǎng)站本身性能也深刻影響著公司的形象纳寂、利益等問題主穗。但是大多數(shù)前端測試工具都太碎片化,沒有辦法針對多個(gè)使用場景毙芜,而且很多都是像 yslow 這樣簡單打個(gè)分黔牵,也不是真實(shí)的用戶體驗(yàn)。前一段時(shí)間在網(wǎng)上找到了一款前端性能優(yōu)化分析工具——Browser Insight爷肝,里面的功能相當(dāng)全面猾浦,而且可以針對多個(gè)使用場景,包括:PC端灯抛,移動(dòng)微信金赦,移動(dòng)瀏覽器,移動(dòng)webview对嚼,還是 真實(shí)的用戶體驗(yàn)夹抗,也就是說,用戶訪問你的網(wǎng)頁是什么樣的纵竖,從這個(gè)工具中體現(xiàn)出的就是什么樣子的漠烧。

基于 JavaScript 這個(gè)維度 Bi 做的也是相當(dāng)豐富了。

首先是 腳本錯(cuò)誤 板塊靡砌。Bi 里面可以從不同的時(shí)間維度查看被監(jiān)控頁面出現(xiàn)過的腳本錯(cuò)誤已脓,具體信息包括:發(fā)生時(shí)間、設(shè)備類型通殃、報(bào)錯(cuò)的瀏覽器及其版本號度液、錯(cuò)誤堆棧信息都可以看到,不論是 線上還是線下測試或者頁面維護(hù) 都是夠用了。

不但能看到時(shí)間堕担、系統(tǒng)已慢、瀏覽器等,還可以具體定位到出錯(cuò)的代碼行霹购,這個(gè)確實(shí)很方便佑惠。

圖 2.Bi 腳本錯(cuò)誤


其次是頁面響應(yīng)時(shí)間板塊,這個(gè)算是意外的收獲了齐疙。通過響應(yīng)時(shí)間板塊里面的慢加載追蹤膜楷,可以看到本次慢加載的頁面資源加載情況,然后我們就知道該優(yōu)化哪個(gè)頁面的哪些 js 剂碴、css把将、img等。

圖 3.Bi 資源列表-時(shí)序圖


五.前端優(yōu)化忆矛?用戶體驗(yàn)察蹲?

各位看客,如果你真能堅(jiān)持看到這里催训,是否會覺得這篇更像解決用戶體驗(yàn)問題的文章?但是講心里話洽议,前端優(yōu)化的最終目的,難道不是為了改善用戶體驗(yàn)嗎漫拭?

任何基于用戶體驗(yàn)的方案亚兄,都可以叫前端優(yōu)化技術(shù)。

不管使用多么好的機(jī)器采驻、多么高的技術(shù)审胚,響應(yīng)速度問題總是避免不了的,因此糾結(jié)于什么技術(shù)來解決是不實(shí)際的礼旅。但是有一款好的工具膳叨,使用一些小技巧,也可以改善用戶等待的體驗(yàn)痘系。

比如菲嘴,我們?yōu)槊總€(gè)非 _target 的超鏈接或者表單的點(diǎn)擊,添加點(diǎn)擊事件處理汰翠,處理邏輯也很簡單龄坪,就是設(shè)置 3 秒超時(shí),顯示等待對話框复唤。如果在 3 秒內(nèi)頁面發(fā)生跳轉(zhuǎn)健田,那么這個(gè)等待對話框就不會出現(xiàn),否則會彈出提示用戶等待苟穆,從而及時(shí)的將響應(yīng)反饋給用戶抄课,減少用戶空白等待時(shí)間唱星。

這并不是什么高深的技術(shù)雳旅,但是運(yùn)用這個(gè)技巧跟磨,卻可以大大的改善用戶體驗(yàn)。

各位攒盈,我們優(yōu)化的目的抵拘,就是不要讓用戶一直得不到響應(yīng),避免空白等待型豁,讓用戶體驗(yàn)越來越好僵蛛。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市迎变,隨后出現(xiàn)的幾起案子充尉,更是在濱河造成了極大的恐慌,老刑警劉巖衣形,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驼侠,死亡現(xiàn)場離奇詭異,居然都是意外死亡谆吴,警方通過查閱死者的電腦和手機(jī)倒源,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來句狼,“玉大人笋熬,你說我怎么就攤上這事∧骞剑” “怎么了胳螟?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長筹吐。 經(jīng)常有香客問我糖耸,道長,這世上最難降的妖魔是什么骏令? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任蔬捷,我火速辦了婚禮,結(jié)果婚禮上榔袋,老公的妹妹穿的比我還像新娘周拐。我一直安慰自己,他們只是感情好凰兑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吏够,像睡著了一般。 火紅的嫁衣襯著肌膚如雪脓钾。 梳的紋絲不亂的頭發(fā)上可训,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天握截,我揣著相機(jī)與錄音谨胞,去河邊找鬼蒜鸡。 笑死术瓮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的恬汁。 我是一名探鬼主播辜伟,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼约巷,長吁一口氣:“原來是場噩夢啊……” “哼旱捧!你這毒婦竟也來了枚赡?” 一聲冷哼從身側(cè)響起贫橙,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤卢肃,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后尤蒿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體优质,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年避乏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拍皮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片铆帽。...
    茶點(diǎn)故事閱讀 38,654評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡爹橱,死狀恐怖窄做,靈堂內(nèi)的尸體忽然破棺而出椭盏,到底是詐尸還是另有隱情掏颊,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布盆偿,位于F島的核電站陈肛,受9級特大地震影響兄裂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜腥泥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一蛔外、第九天 我趴在偏房一處隱蔽的房頂上張望夹厌。 院中可真熱鬧裆悄,春花似錦光稼、人聲如沸艾君。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽写烤。三九已至,卻和暖如春感局,著一層夾襖步出監(jiān)牢的瞬間询微,已是汗流浹背狂巢。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工唧领, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人驯杜。 一個(gè)月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像顽频,于是被迫代替她去往敵國和親冲九。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評論 2 349

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,787評論 25 707
  • 一.前言 軟件行業(yè)極其缺乏前端人才這是圈內(nèi)的共識了温学,某種程度上講仗岖,同等水平前端的工資都要比后端高上不少轧拄,而圈內(nèi)的另...
    DavieKong閱讀 198評論 0 1
  • ——文/小字公子 “在每一個(gè)女神身邊檩电,是不是都有一個(gè)豬哥俐末?”身邊的一名高富帥卓箫,曾在一段不順暢的感情中這樣問道烹卒。 至...
    小字公子閱讀 480評論 2 3
  • 沿著開通的山路 我們從石巖方向停下了腳步 當(dāng)所有的氣墊打開門 你坐的速度就好像坐上了飛機(jī) 當(dāng)彌天大霧漫上了山頭的時(shí)...
    隔著玻璃親嘴閱讀 201評論 1 1
  • 作為一個(gè)基礎(chǔ)教育的老師辖众,小白會不停地面對各式各樣的家長。 有的家長的話小白其實(shí)很無語戏阅。 “老師奕筐,我們家XX學(xué)習(xí)很認(rèn)...
    白發(fā)漁樵江渚閱讀 756評論 11 6