Front-end 在 Android 手機瀏覽器的 performance issue

最近公司產品遇到了client-side 的 performance issue,在經過這三個禮拜的努力,大致上做了以下的處理,記錄一下,也可以提供參考。

要解決的問題

User 回報產品在 Android 的瀏覽器上運作非常的緩慢,甚至慢到無法使用,試問單兵該如何處置?

解法

  1. 由於我們產品使用 React 做為前端 framework 來開發,有些 DOM 物件平常會被隱藏起來看不到(例如:side-bar, menu … 等等),這時候我們可以利用 React 的 state 跟 props 來控制,當這個 Component 是看不見的,那麼這個 Component 就不要 redner。

code 大概會像是:

import React from 'react';
const A = () => {
const { isHidden } = this.props;
if(isHidden) return <div></div>
else return (
<div>
<innerComponent />
</div>
)}
這個解法可以省 HTML 的 DOM 元件,讓畫面東西減少,來增加效能。

2. 把一些有可能會需要 render 出很多畫面的 Link 隱藏掉

這其實算是一個 workaround … 由於當初還沒有找到真正的原因,我們的 PM 決定先以這個方法來作為一個 “暫時” 的解決方案。

主要是利用 userAgent 的方法判斷瀏覽器:

const isAndroid = /Android/.test(window.navigator.userAgent);

3. 最後追 code 追到一個非常有可能的地方,就是經常性的讀寫 cookie (非常感謝 shiningjason1989的幫忙)

如何找到:

利用 Chrome 的 devTool 開 timeline 看 callstack,找到跑最花時間的方法(也有可能是時間不長,但次數很多)

測試結果與推測:

讀寫 cookie 的行為,在電腦或是 iPhone 這樣硬體規格比較好的裝置上跑,讀寫 cookie 的行為其實感覺不出來效能很差,但在 Android 硬體規格較差的裝置上,的確有非常大的差別,也許瀏覽器對於 cookie 的處理效能本來就不好,但這件事情再 Android 上特別明顯。

問題點:

寫入 cookie 的時間點我們沒辦法控制,大多數時間其實都是在【讀取】 cookie 的時間,而我們產品裡面的確有會直接去拿 $.cookie 的 key value 的部分,也是真正導致 performance 的問題點所在。

解決方法:

既然找到問題點在於讀取 cookie,那麼我們在取得 cookie 的時候做一個 Js cache 的機制,讓他在 read 的時候會先取 Js cache 而不是每次都直接拿 cookie。

const jsCache = {};
const cookie = {
write: function(key, value){
$.cookie(key, value);
jsCache[key] = value;
},
read: function(key){
return jsCache[key] || $.cookie(key);
}
}

以上,大致上是我們在這次 performance issue 所做的一些 solution。

其餘也許可行的解法

  1. 用 React-addons-Perf lib 來檢查 render 的情況
  2. UI 上的 lazy-loading
  3. 換 cookie 的 lib,或是用原生的 JavaScript 處理 cookie (不知道有沒有用,也許換個比 jQuery 輕量的 lib 來處理這件事?)