天天看點

從JS引擎角度剖析DataFlux前端性能,多元度提升網站使用者體驗

性能與體驗一直都是前端開發中老生常談的話題,也是開發出一款優秀web應用必須要考慮的問題。随着google V8引擎的釋出,Node的誕生,前端能做的事情也越來越多,浏覽器的能力也被無限放大和利用。如何在能夠在完成疊代需求的基礎上,逐漸優化網站性能以及體驗,充分利用浏覽器的能力突破性能瓶頸,提升互動體驗,趨優網站親和性,則成為了一個前端開發必須逾越的鴻溝。

從JS引擎角度剖析DataFlux前端性能,多元度提升網站使用者體驗

這篇文章我們結合DataFlux前端應用,從浏覽器和Javascript引擎角度來剖析前端性能,指出DataFlux前端應用在性能優化這塊的優缺點。

在文章開始前,先大體聊聊 DataFlux 這款産品為什麼要注重性能以及互動體驗。DataFlux是一個實時大資料分析平台。看名稱我們可以扣到兩個字眼,“實時”、“分析”,小編認為“實時”應該對應及時、準确,而“分析”則應該對應直覺、參考、預測、趨勢。是以極緻優化網站目前性能,提升互動體驗更是成為了重中之重。

其實性能與互動問題可以簡單一句話描述“能夠在最短的時間内,讓使用者看到自己想看到的東西”。而能夠由前端去實作的無非就是降低互動延遲,減少頁面卡頓,美化頁面效果。

首先我們談談怎麼以前端的角度去降低互動延遲。

降低互動延遲我們可以從兩個方面去考慮,網絡請求、代碼邏輯,網絡請求可以細分成檔案請求以及 AJax異步請求。

我們可以用chrome打開Dataflux SaaS應用網站,然後打開開發者工具,如下圖:

從JS引擎角度剖析DataFlux前端性能,多元度提升網站使用者體驗

影響網絡請求延遲的原因可能是目前網絡環境因素、伺服器資料傳回的延遲、包内容過大等等因素造成,一般對于伺服器資料傳回所造成的延遲,前端開發很難對其進行優化,當然對于一些不常變更,及時性要求不是那麼高的資料,我們可以在前端做一個本地緩存處理,下次加載可以先加載本地緩存,然後再異步請求去更新資料。

如果是因為資料包過大也讓引起的延遲,我們可以采用分步加載資料包,優先加載使用者關注高的資料的方式去降低延遲。

對比dataflux下圖我們可以看出一些東西:同樣大小的資料包,「query_data」這個接口用了156ms的響應時間而另外一個接口隻用了73ms,也就排除了是由目前網絡環境的影響,可以确定是服務端在處理資料能力上的延遲。并且我們可以看出「query_data」是還是一個調用比較頻繁的請求,這裡面對互動體驗的影響還是蠻大的。

是以這裡我的建議是後端同學可以優化優化代碼

從JS引擎角度剖析DataFlux前端性能,多元度提升網站使用者體驗

從JS引擎角度剖析DataFlux前端性能,多元度提升網站使用者體驗

靜态檔案請求的優化點

聊完了ajax異步請求,我們聊聊靜态檔案請求的優化點,靜态檔案影響的延遲包括幾個方面:體積過大,數量過多,腳本同步執行阻塞渲染。

對于體積過大的問題,我們可以用各種工具對檔案壓縮,分子產品加載,設定響應緩存以及浏覽器緩存的方式減緩延遲,這裡面我着重提一下http緩存以及浏覽器緩存,因為其他因素都可以由各種前端架構的cli去配置實作,着實沒啥可說。http 緩存是 web 性能優化中非常重要的一種手段,把一些常用資源在首次加載時緩存到浏覽器本地,再次加載時可大大減少請求次數,緩存的資源越多,性能當然越好。

PS:緩存的規則主要有兩種,強制緩存和對比協商緩存,兩種緩存分别通過Http封包頭部不同的字段進行控制。

因為腳本的同步執行造成的阻塞渲染,我們都知道浏覽器解析渲染 DOM Tree 和 CSS Tree,解析執行 JavaScript,幾乎所有的操作都是在主線程中執行。因為 JavaScript 可以操作 DOM,影響渲染,是以 JavaScript 引擎線程和 UI 線程是互斥的。換句話說,JavaScript 代碼執行時會阻塞頁面的渲染。

解決這個問題無非是讓腳本加載執行的時候,不影響到渲染。是以我們可以把樣式檔案放到head頭部,而腳本檔案放到body尾部。或者在script标簽上加defer屬性,來表明腳本在執行的時候,不會影響頁面的結構。也就是說,腳本會被延遲到整個頁面都解析完畢後再運作。但采用這種方法,會有一種缺陷。在有些浏覽器中。并不會按照你自己檔案的順序執行下來。并且有的浏覽器還會忽略這種屬性。還有一種方式就是利用html5中一個很有用但是經常被忽略的特性,就是預加載(perfetch),他的原理是:利用浏覽器的空閑時間去先下載下傳使用者指定需要的内容,然後緩存起來,這樣使用者下次加載時,就直接從緩存中取出來,效率就加快了。當然這些新的特性,對浏覽器的版本要求還是比較高的,如果對相容性要求比較高的話,還是老老實實用尾部大法吧。

回到我們的應用,看下圖:從圖中我們可以看出,在靜态檔案緩存利用上我們做的還是比較好的

從JS引擎角度剖析DataFlux前端性能,多元度提升網站使用者體驗
從JS引擎角度剖析DataFlux前端性能,多元度提升網站使用者體驗

也用到了上面說到的prefetch特性。當然這也得益于vue-cli 的強大。。不足之處就是由的檔案體積過大,會導緻首次加載時間過長,執行效率降低。這裡我的建議是,能夠剔除檔案之中不需要的子產品,減少重複代碼來減小檔案體積。

代碼邏輯方面的優化

至于代碼邏輯方面的優化,我們可以從頁面渲染以及執行效率兩方面着手。

影響頁面渲染的因素有很多,總結下來也是一句話,dom元素不要過多,不要頻繁觸發”重排(reflow)”,同時盡量減少因為JavaScript 引擎線程和 UI 線程的互斥性阻塞頁面的渲染的影響。

dom元素不要過多:

調整頁面布局結構,去除不必要的dom節點

頻繁觸發”重排(reflow)”:

需要注意的是,"重繪"不一定需要"重排",比如改變某個網頁元素的顔色,就隻會觸發"重繪",不會觸發"重排",因為布局沒有改變。但是,"重排"必然導緻"重繪",比如改變一個網頁元素的位置,就會同時觸發"重排"和"重繪",因為布局改變了。是以我們可以從在腳本中減少例如增加、修改、删除 DOM元素或者對 DOM集合的操作。在css檔案中對于一下會觸發重排的元素放到class的開頭,觸發repaint的元素放到後面, 在周遊選擇某個元素樣式時不要嵌套太深..等的方式減少reflow次數。

從JS引擎角度剖析DataFlux前端性能,多元度提升網站使用者體驗

我看可以看dataflux應用的部分截圖:

可以看出平台是非常依賴浏覽器的GPU渲染能力,因為我們主要的方向都是在資料展示分析上,是以上面一些問題是目前我們必須要面對的問題,上圖中,因為一個節點要展示的圖表有可能十個,幾十個甚至還可能出現地圖類型的圖表。在這些圖表我們使用的svg元素,畢竟在處理大型渲染區域的環境上,svg優于canvas,但是這也衍生出一個問題,頁面的html元素會越來越多,導緻頁面結構越來越複雜,解析速度會越來越慢。是以在這個問題上我們的解決方案是,優先展示使用者關注的圖表,隻渲染螢幕區域内的元素,螢幕區域外的元素直接删除,資料緩存等方式去優化頁面卡頓,反應遲緩等問題。當然除了上面說的,在代碼風格上,因為我們用的是vue,是以也盡量遵循vue官方的風格指南以及cookbook。

以前端開發的方式去優化整個網站的使用者體驗

最後聊聊如何以前端開發的方式去優化整個網站的使用者體驗

其實我們比其他人的優勢是更懂得如何去設計網頁和增加網站實用性。舉幾個例子:

  1. 使用“for”屬性允許使用者點選标簽,就可以選擇到表單中整個的輸入區域,這對單選框和複選框擴大點選區域十分重要。但要注意選擇内容的比對
  2. 在連結上應該給使用者一個視覺上的提示,告訴他/她網頁中的哪些連結是已通路過的。
  3. 使用輸入框或輸入域時,選擇使用“focus”或其它方式,展示出哪一個區域在目前是處于激活狀态的,這一點對使用者很有幫助
  4. 圖檔标簽應該加上alt圖檔描述,另外當你的圖檔存在連結時,圖檔描述應該包括連結位址

    ….

篇幅有限,歡迎大家使用 Dataflux.cn~

當然上面都是小編的一些個人經驗總結,如有不妥之處還請多多包涵

從JS引擎角度剖析DataFlux前端性能,多元度提升網站使用者體驗

繼續閱讀