JavaScript 踩坑心得— 爲了高速(下)

一.前言

本文的上一篇 JavaScript 踩坑心得— 爲了高速(上) 主要和你們分享的是 JavaScript 使用過程當中的基本原則以及編寫過程當中的心得分享,本文主要和你們聊聊在各個使用場景下的 JavaScript 使用,以及在性能優化方面的優化經驗等javascript

二.各類場景下的 JavaScript
1.用於 UI 應用的 JavaScript

與大多數服務器端語言同樣,用於客戶端應用的 JavaScript 框架歷來就不缺乏。然而,和用在後端應用與服務中同樣,筆者偏好使用較小的模塊,將這些小模塊組合爲框架,從而實現可擴展性,可維護性以及較高的重用度。css

而且,因爲小模塊的特性,後期拍錯或者進行性能優化的時候也會很是方便,如今國內外針對前端 JavaScript 的性能行爲分析工具也比較成熟了,例如 Browser InsightAPPdynamicRuxit,都是不錯的選擇html

2.構建 Web 應用的 JavaScript

對於 Web 應用,筆者發現將 React 用於實現 UI,Redux 用於狀態管理,Joi 用於數據驗證,是創建可擴展客戶端應用的最有效技術基礎。這樣創建起來的應用,每每易於操縱,測試以及調試前端

筆者很是喜好該組合的一點,是他們使得遵循「 JavaScript 的兩大支柱」變得更加簡單。從 0.14 版本開始,React 增長了對純函數的支持,Redux 也使用了純函數與可組合的 reducers。看來,使用典型面向對象模式的脆弱應用已經一去不復返了。java

該組合的另外一大優勢是可用的工具不少。React 與 Redux 都有 Chrome 開發者工具插件,使得調試與操做應用變得極爲簡單。而諸多支持模塊,好比 React Hot Loader 與 Webpack 也使得反饋更加及時。筆者建議你仔細瞭解一下這兩個模塊。ios

3.構建移動應用

顯而易見,若是是構建移動平臺的應用,筆者確定會推薦 React Native。目前,React Native 僅支持 iOS 與 Android 平臺,所以,除非你真的須要 Windows 支持,筆者會統一推薦 React Native。git

還有一個值得一說的就是,如今不管安卓仍是 ios 的 APP 性能優化 也很是重要,可是不少公司只注重後端架構、代碼質量等問題,卻忽視了前端編寫時可能存在的影響因素。而且,儘管 JS 測試對於確保應用如期運行很是重要,但人們卻也經常在測試中花去太多時間,並非說不該該編寫測試代碼,只是,要當心過分測試與過分模擬,因此上文提到過的 Browser InsightnewrelicAPPdynamic 等真心都是優化前端不錯的選擇。github

三.測試用 JavaScript
1.僅測試公共 APIs

經過不專一於內部程序,只要不破壞模塊內的公共 API,咱們就能爲所欲爲地改變他們。這意味着,測試的變化無需那麼頻繁,並且你能夠確保本身接收的數據正是應該收到的數據。web

2.創建測試框架

說到實際應用的測試模塊,筆者最近迷上了 tapenock。有了這兩個模塊,筆者就能覆蓋 99% 的測試(有時候,筆者必須自行監控一些數據,並使用 Sinon)。Browser Insight 這款產品不管是線上仍是線下,針對前端頁面的 JS 錯誤都能準確的定位到,精確到代碼行,很是方便。ajax

3.測試用戶體驗(UX)

若是你在打造 Web 應用,可能會想在儘量多的設備與瀏覽環境下測試用戶體驗。爲了得到更爲直接的反饋,筆者採用了 Browser Insight,這個工具的好處就是基於真實的用戶體驗,多維度的定位分析網站的性能問題,例如腳本錯誤、ajax調用、響應時間分佈等板塊,並且,這個工具支持 PC 端、移動瀏覽器、移動微信頁面、APP 等多個使用場景,基本上能知足絕大多數場景的使用需求。

四.JavaScript 性能優化誤區
1.JavaScript 模塊化使用誤區

加快 JavaScript 加載和執行的速度,一直是前端優化的一個熱點。所以咱們先來講下 JavaScript 模塊化技術的相關知識,但願經過實踐來體現模塊化技術在使用時的注意事項,避免濫用。

爲何會有模塊化技術?

長久以來,編寫 JavaScript 一直以文件爲單位,通常一個類型的 JavaScript 功能代碼會被放在同一個文件裏。在一個頁面裏,引用的文件通常是寫死的,也就是無論頁面用不用,只要你引入了這個文件,這個文件就會被加載。

舉個例子,咱們開發了一個內容複雜、功能強大的頁面,JavaScript 文件大到 500K,當頁面費勁的把這 500K 加載下來,然而用戶真正只使用了這 500K 裏極少的一部分功能,但咱們又不得不把這 500K 加載下來,由於不一樣的用戶使用的功能點可能不同,咱們必須知足全部需求。

而模塊化技術提出 按需加載,也就是當用戶觸發該功能的時候,那個功能才真正的被加載。比如 500K 被拆成了 50 個模塊,每一個模塊 10K,當用戶觸發一個功能時,加載 10K,再觸發再加載,以這樣懶加載的方式來加載模塊,能夠很大的提升響應速度。這樣,管理模塊懶加載的技術也隨之誕生。

模塊化技術並不是處處靠譜!!

以前筆者在網上搜索到了一個模塊化技術:SeaJS。它是一個遵循 CommonJS 規範的 JavaScript 模塊加載框架,能夠實現 JavaScript 的模塊化開發及加載機制。與 JQuery 等 JavaScript 框架不一樣,SeaJS 不會擴展封裝語言特性,而只是實現 JavaScript 的模塊化及按模塊加載。

SeaJS 的主要目的是令 JavaScript 開發模塊化並能夠輕鬆愉悅進行加載,將前端工程師從繁重的 JavaScript 文件及對象依賴處理中解放出來,能夠專一於代碼自己的邏輯。說白了就是有 Lazy Load 的特性,用到某模塊時,SeaJS 纔會去加載模塊的 JS 文件。咱們能夠按功能劃分多個模塊,觸發模塊功能時,SeaJS 先加載功能模塊的文件,而後執行相應的功能。

這個 SeaJS 擁有的特性,初看很是吸引人,它能夠說是新定義了一種開發和管理 JavaScript 文件的模式。遵循這個模式,你會享受起 JavaScript 的開發。

實踐證實,它也的確可使 JavaScript 模塊化,根據功能劃分模塊,每一個模塊對應一個 JavaScript 文件,當執行到模塊的功能,或者你須要加載模塊時,模塊纔會被下載,同時不會形成重複下載。這一切看起來如此的合理,如此的順暢。。。。。

可是在使用後發現了一些 問題:因爲當時開發的網站功能相對簡單,JavaScript 文件並非很是大,過多的模塊,反而會致使總加載的時間變多了。

因爲是 Lazy Load 特性,不適合的模塊劃分致使網站出現反應慢的現象,緣由是得先加載模塊的文件,才能執行模塊的功能。當網絡狀況很差時,該現象表現的更爲嚴重!!!

能夠說,問題出在了對新技術的不瞭解上,從而出現了問題,預期是 SeaJS 能夠處理 JavaScript 優化的問題,由於它具備避免加載沒必要要模塊的功能,結果反而南轅北轍。

根據 大功能來劃分模塊 也是一個不錯的嘗試。

筆者嘗試將全部模塊劃分爲 基礎模塊功能模塊 ,基礎模塊包括頁面頭部,尾部相關的公共部分,功能模塊則根據先後臺劃分,前臺部分,又根據具體的頁面來劃分,能合併到一塊兒的,就合併成一個模塊,增長粒度。結果 JavaScript 文件減小,也達到了預期的效果。

從實際體驗來看,對於流量不大的網站來講,沒有必要使用懶加載 JavaScript 的相關技術,由於自己 JavaScript 文件就不是很是大。所以在網頁加載時,就能夠先加載所須要的模塊。避免沒必要要的延遲。

2.JavaScript 的位置問題

這一部分,咱們來講說 JavaScript 的位置問題對網頁網站性能的影響。

爲何要考慮位置問題?

其實無論是 CSS 仍是 JavaScript,都須要考慮位置的問題,由於 HTML 的渲染和加載順序是從上往下,也就是若是前面插入了 JavaScript 的引用,那麼必須等到這個 JavaScript 下載完畢纔會渲染後續的部分。

所以 JavaScript 的插入位置就成爲一個值得考慮的問題,由於不適合的位置可能引發渲染的延遲等,形成很差的用戶體驗。

傳統方案帶來的問題和思考

CSS 放在頭部,JavaScript 放在尾部,這是傳統的經驗,它的好處是可讓頁面優先渲染, 從而頁面能夠快速顯示。

但有事實每每沒有咱們預想的那麼美好。

有的時候會出現這麼一種狀況:當頁面已經渲染完畢時,咱們馬上去使用網站的功能,但不少時候 功能按鈕會沒有反應。緣由也很簡單,就是 JavaScript 放在頁面的尾部,還沒來得及加載。。。。

這就糾結了。。。。

兩種 JavaScript 放置方式,一種放在頭部,一種放在尾部(暫時忽略部分放在頭部,部分放在尾部的方式),一個犧牲了渲染速度,一個犧牲了用戶體驗。因此不少時候 js 的問題咱們須要作權衡。

對通常的小型網站來講,用戶體驗問題要遠遠大於頁面渲染的問題,就好比上文提到的那種功能按鈕不可用的狀況。並且,若是 JavaScript 不是很大的話,放在頭部就很好,既不會有過久的頁面空白,也能讓其優先加載,兩者獲得了很好的平衡。

所以,不少經驗上的東西並非絕對的,必定要根據實際的狀況,包括功能特色、服務器網絡狀況等來綜合考慮。

爲此,筆者寫下一個自認爲較爲合理的位置選擇方案,僅供參考。

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

從上面的分類介紹,咱們也能夠看出,將功能代碼按類型歸類到不一樣的 JavaScript 文件是多麼的重要,好比應該放頭部和應該放尾部的代碼,最好不要合併在一塊兒,不要等到出問題要優化的時候再去整理和重構,這樣會增長不少沒必要要的工做量。

這不只僅是爲本身工做負責,也是爲後面要讀你代碼的新人負責。養成好的設計編碼習慣,也是技術積累的一部分。最後再根據 JavaScript 文件的功能類型,來決定是放在頁面的頭部仍是尾部。

五.怎樣肯定是否是 JavaScript 的問題?

這個問題筆者在以前看過的的前端高性能優化(一)(二)中 get 到了新的技能點,在這裏分享給你們。

隨着信息爆炸時代的到來,網站自己性能也深入影響着公司的形象、利益等問題。可是大多數前端測試工具都太碎片化,沒有辦法針對多個使用場景,並且不少都是像 yslow 這樣簡單打個分,也不是真實的用戶體驗。前一段時間在網上找到了一款前端性能優化分析工具——Browser Insight,裏面的功能至關全面,並且能夠針對多個使用場景,包括:PC端,移動微信,移動瀏覽器,移動webview,仍是 真實的用戶體驗,也就是說,用戶訪問你的網頁是什麼樣的,從這個工具中體現出的就是什麼樣子的。

基於 JavaScript 這個維度 Bi 作的也是至關豐富了。

首先是 腳本錯誤 板塊。Bi 裏面能夠從不一樣的時間維度查看被監控頁面出現過的腳本錯誤,具體信息包括:發生時間、設備類型、報錯的瀏覽器及其版本號、錯誤堆棧信息均可以看到,不管是 線上仍是線下測試或者頁面維護 都是夠用了。

不但能看到時間、系統、瀏覽器等,還能夠具體定位到出錯的代碼行,這個確實很方便。

圖 2.Bi 腳本錯誤

其次是頁面響應時間板塊,這個算是意外的收穫了。經過響應時間板塊裏面的慢加載追蹤,能夠看到本次慢加載的頁面資源加載狀況,而後咱們就知道該優化哪一個頁面的哪些 js 、css、img等。

圖 3.Bi 資源列表-時序圖

六.結語

JavaScript 具有許多獨特的優點,筆者甚至敢說,JavaScript 極可能是目前最重要的語言,由於它能在幾乎全部平臺上運行,並且能夠經過高度可重用、可組合的方式實現。

然而,不熟悉 JavaScript 性能與問題的開發者可能很快就會發現,對其代碼庫進行更改變得愈加困難,並且這些改變可能會致使出其不意的逆反效果。

筆者建議,不要像用其餘語言寫程序那樣編寫 JavaScript 程序。儘量利用 JavaScript 獨有的性能,建立小而簡單的模塊。這有助於你保持冷靜,並愛上 JavaScript 的強大功能。

Happy JavaScripting!

注:本文翻譯自 Kurtis Kemple 的一篇文章,由小編加了一些本身的意見和見解。

原文地址:https://labs.mlssoccer.com/javascript-at-scale-achieving-high-velocity-160c7d78af03#.egfwqqz0a

Browser Insight 是一個基於真實用戶的 Web 前端性能監控平臺,可以幫你們定位網站性能瓶頸,網站加速效果可視化;支持瀏覽器、微信、App 瀏覽 HTML 和 HTML5 頁面。想閱讀更多技術文章,請訪問OneAPM 官方技術博客

本文轉自 OneAPM 官方博客

相關文章
相關標籤/搜索