一次移動優化之旅

在這裏介紹移動App中嵌入網頁,優化頁面顯示速度。javascript

前言

最近在Boss的要求下,寫組件模式的移動頁面。這裏選擇的庫是react。(爲何? 入門簡單 + JSX)。css

在通過愉快的編寫組件後,打包組件造成組件庫文件,而後被頁面引用。配置到 App 中後,run···,發現界面顯示出來很慢,2s左右纔會出現界面和數據。html

不開心了,速度太慢。因此準備分析慢的緣由。因此有了這篇筆記,新手,輕噴。java

工具:Chrome developer tools

爲何2s左右纔會出現,使用工具測試了下。chrome dev tools 下的 timeline 分析工具很贊。react

具體操做方法:jquery

  1. chrome 瀏覽器地址欄輸入 chrome://inspect 這個是遠程調試工具,調試 App 應用中的 html 神器。webpack

  2. 選擇 chrome 下檢查到的你的網頁,點擊 inspect 進入就行。web

    這裏你的手機應該是連着電腦的。
  3. 選中 timeline 工具,打開分析,刷新網頁。 結果就出來了chrome

效果如圖:segmentfault

圖片描述

分析

1. 根據 url 加載 html 文件

圖片描述

讀取 url 後,webkit 調用資源加載器加載 html 資源。在上圖中能夠看到觸發了6個操做。

咱們從時序上開始分析。

  1. Send Request 根據url取資源文件,請求發送

  2. Receive Response 應答返回時,觸發這個

  3. Receive Data 接受資源文件內容,若是文件比較大的話,會觸發屢次

  4. Recaculate Style 從新計算樣式,根據html返回的內容,計算樣式

  5. Finish Loading 文件處理完成

  6. Parse HTML 顯示頁面???

步驟6在手機瀏覽器中,是會提早顯示出來的,可是在 App 中怎麼會不顯示呢?(這個求大神解決下)

2. html文件弄好後,開始作裏面的資源文件了

附上 html 代碼:

<!doctype html>
<html>
<head>
    <title>Test</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
    <meta name="format-detection" content="telephone=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="white" />
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <link rel="stylesheet" type="text/css" href="../../tlibs/style.css">
</head>
<body style="overflow: hidden;margin:0;">
<div id="app"><p style="color: red;">Hello World</p></div>
<div id="mask"></div>
</body>
<script type="text/javascript" src="../../libs/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="../../libs/highcharts.js"></script>
<script type="text/javascript" src="../../tlibs/connect.js"></script>
<script type="text/javascript" src="../../tlibs/__tdx_vendor.js"></script>
<script type="text/javascript" src="../../tlibs/__tdx_client.js"></script>
<script type="text/javascript" src="./index_config.js"></script>
<script type="text/javascript" src="./index_func.js"></script>
</html>

html頁面中有節點 script, link 遇到這些 Webkit 又要調用資源加載器來加載資源了。效果圖以下:

圖片描述

能夠看到,這些資源請求是異步的,就是說請求資源的請求是同時發出去的,沒有等上個資源返回後再發送。

資源的加載重複上面加載 html 頁面的過程: send request -> receive data -> caculate (scripting 部分) -> finish

在當前情形下,jquery 回來後,開始 scripting, 接着是 highcharts, ···

scriping 這個部分是線性的,javascript 的特性。

3. css,js文件解析過程當中

css, js文件解析過程當中,又有 url 連接圖片什麼的,又是請求發送。

4. 在App中出現頁面的最後時刻

在 App 中出現頁面的最後一刻,有個 scriping 的過程,這裏的觸發事件在左側顯示爲 GC Event, 這個是什麼東西???

優化思路

經過上面的分析,優化頁面顯示的時間,我的認爲主要有幾個方向:

  1. Send Request <--> Receive Response, Receive Data

    這個過程當中,若是你的頁面是遠程服務器上,那麼這個就和網絡有關了,網絡要好,文件要壓縮變小。
    
    對於多個文件是否要合併爲一個文件,從 `timeline` 時序上看,請求是並行的,若是帶寬和請求連接數沒有限制的話,我的感受分開請求比較好。
    
    固然也不能太多了,每一個文件幾k,這樣就合併就沒有天理了。
  2. scripting 階段,這個是讀js代碼邏輯,就是把js文件執行一遍。 這裏的優化就看你的業務邏輯了。

  3. 圖片資源,動態圖下載,圖片請求的 Send Request <--> Receive Response 之間的響應太長了,

    中間還涉及了一個 `GC Event`, 這個有什麼用???
    
    如圖:

圖片描述

對於目前我的的需求,文件放在本地,因此

優化1,這裏合併文件效果不大。

優化2,

對於外部引用,能夠去掉外部引用組件邏輯,例如 jquery, highcharts 這些,或者找個好點的庫。

對於自身的邏輯,最好分析下流程,看看哪裏耗時

優化3,那個 GC Event 的做用還不怎麼清楚,研究中。

還有一個想法是調用 ReactserverrenderToString 方法,先生成靜態頁面,顯示內容。這裏就是在載入 html 頁面後,直接顯示。

設想的結果:

  1. 載入html,顯示出來

  2. 如今js,css,圖片等資源文件,準備好後更新頁面

這樣能夠消除頁面準備過程當中,空白的問題。想法很好,可是現實很骨感。 在 App 中載入 html 頁面盡然沒有顯示出來,非要等js準備好後,才顯示界面,

這是爲何???(設想結果1沒有)

在手機的瀏覽器中就麼有這個問題??? why ???

我的代碼部分分析

手機App中,看到有2個js文件耗時很大: __tdx_vendor.js, __tdx_client.js

這是2個什麼文件,總的來講,我這邊文件引入的庫是 React,全部的文件經過 webpack 打包造成這2個文件。

具體的時序圖,在 chrome://inspect 中看不到,咱們直接在瀏覽器中打開分析:

圖片描述

先不考慮外部文件的效率。

webpack 打包後的文件,須要讀取的時候,每一個都要花費這麼長的時間???

在 __tdx_vendor.js 中只有 react 和 react-dom 的 dist 文件。內容以下:

圖片描述

這裏只是貼了前面的部分,全部的module都在這個自執行函數的參數中。一個個的參數開始執行並緩存下來。

問題

感受說的有點亂,目前存在的問題:

  1. html加載完成,js,css等文件沒有finish的時候,在瀏覽器中會先顯示html原有的內容,而後再更新。可是在 App 中的 WebView 組件爲何沒有這樣的顯示邏輯。

測試代碼:

// index.html
<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
    <meta name="format-detection" content="telephone=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="white" />
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
</head>
<body>

<h1 id="page">This is a static page</h1>

</body>
<script type="text/javascript" src="./index.js"></script>
</html>

// index.js
!function() {

    var date = new Date();
    var curDate = null;
    do {
        curDate = new Date();
    } while (curDate - date < 5000);

    setTimeout(function() {
        var el = document.getElementById("page");
        el.innerHTML = "This is a second page";
    }, 5000)
}()

若是後面找到解決方案,會更新到後面。


20160602-2002

個人問題,這個地方瀏覽器和移動App的顯示效果是同樣的。初次加載的時候,都會卡頓5s,等 index.js 執行完成後頁面纔會出來。

Sorry

今天又測試了下,這個地方仍是有時是卡頓 5s 出現界面,有時不會卡頓 5s 就出現了界面。(這裏的刷新界面不夠穩定,帶有隨機性。)

一次移動優化之旅(二)

參考

使用Chrome DevTools的Timeline分析頁面性能

Webkit技術筆記(2):詳解 webkit 網頁渲染過程

相關文章
相關標籤/搜索