成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

讓老板虎軀一震的前端技術(shù),KPI殺手

PiscesYE / 1977人閱讀

摘要:我們的目標(biāo)是讓的頁面也能夠擁有般的體驗,如果你還在尋求什么技術(shù)能夠讓老板虎軀一震拯救你的,那么這篇文章或許能夠幫助到你。這是一個使用編寫的頁面,運行于多端,包括企鵝輔導(dǎo)手機手機瀏覽器。經(jīng)過我們的測試發(fā)現(xiàn)安卓基本上都是支持的,需要以上才支持。

本文由云+社區(qū)發(fā)表

作者:思衍Jax

天下武功,唯 (wei) 快(fu) 不(bu) 破(po)。

隨著近幾年的前端技術(shù)的高速發(fā)展,越來越多的團隊使用 React、Vue 等 SPA 框架作為其主要的技術(shù)棧。以 React 應(yīng)用為例,從性能角度,其最重要的指標(biāo)可能就是首屏渲染所花費的時間了。那么今天,我們要給大家分享的一個把優(yōu)化做到極致的故事。

我們的目標(biāo)是讓 H5 的頁面也能夠擁有 Native 般的體驗,如果你還在尋求什么技術(shù)能夠讓老板虎軀一震(拯救你的KPI),那么這篇文章或許能夠幫助到你。

企鵝輔導(dǎo)課程詳情頁是什么

企鵝輔導(dǎo)詳情頁

課程詳情頁是騰訊旗下企鵝輔導(dǎo) APP 中最重要頁面之一,也是流量最大的頁面之一,所以它的打開速度也是至關(guān)重要的。

這是一個使用 React 編寫的 H5 頁面,運行于多端,包括: 企鵝輔導(dǎo)APP、手機 QQ手機瀏覽器。

架構(gòu)演變
純異步渲染

我們知道當(dāng)前主流的 SPA 的應(yīng)用的默認渲染方式都是這樣的:

在這種情況下,從加載頁面到用戶看到頁面(首屏渲染所花費的時間)就是上圖中灰色邊框區(qū)域所包括的時間。

這是最慢的一種方式,就算 CGI 夠快,最少要花費 1S2S 左右的時間了。

接著我們簡單優(yōu)化一下:

把靜態(tài)資源緩存起來,這樣下次用戶打開的時候就不用從網(wǎng)絡(luò)請求了。

步拉取 CGI 這個動作是否可以提前呢?我們可以在請求 HTML 之后,先通過一段 JS 腳本去請求 CGI 數(shù)據(jù),后面第 步的時候,就可以直接拿到數(shù)據(jù)了,這就是 CGI 預(yù)加載。

怎么做到呢?我們的方案是統(tǒng)一封裝 Request 請求工具,在用 Webpack 打包的時候,會往頁面頂部注入一段 預(yù)加載 CGI 的 JS 代碼,維護一個CGI 與 DATA 對應(yīng) MAP,后面發(fā)請求的時候,先去 MAP 里取值,如果有值的話直接拿出來,沒有的話則發(fā)起HTTP 請求。(具體請查閱我們團隊開源的 Preload 工具)

這種模式還有一些其他的優(yōu)化的方法:

在 HTML 內(nèi)實現(xiàn) Loading 態(tài)或者骨架屏;

去掉外聯(lián) css;

使用動態(tài) polyfill;

使用 SplitChunksPlugin 拆分公共代碼;

正確地使用 Webpack 4.0 的 Tree Shaking;

使用動態(tài) import,切分頁面代碼,減小首屏 JS 體積;

編譯到 ES2015+,提高代碼運行效率,減小體積;

使用 lazyload 和 placeholder 提升加載體驗。

效果如下圖所示:

異步渲染

直出同構(gòu)

在異步的模式下,除了上述優(yōu)化,我們還在端內(nèi)(企鵝輔導(dǎo) APP、手機 QQ)內(nèi)做了離線包緩存(騰訊手Q方面獨立研發(fā)出來的針對手機端優(yōu)化的方案,簡而言之就是將靜態(tài)資源緩存在手機 APP 內(nèi)),經(jīng)過我們的數(shù)據(jù)測試,首屏渲染大概能夠達到秒開(1s左右) 的效果。

-w300

但對有著性能極致追求的我們來說,肯定是不會滿意的。

繼續(xù)優(yōu)化,最容易、最大眾的套路肯定就是直出(服務(wù)端渲染)了。

現(xiàn)在直出的方案已經(jīng)有很多很多種,這里也不多做介紹了,如果您想了解更多關(guān)于服務(wù)端渲染的方案,請參考這篇文章。

直出針對首屏?xí)r間的優(yōu)化效果是非常明顯的,經(jīng)過我們的測試,數(shù)據(jù)大概能夠提升25%左右。

直出之后的效果如下圖:

直出同構(gòu)

可以看到對于首屏來說,沒有了【加載中...】的等待時間,視覺體驗提升了不少。

PWA 直出

PWA

針對上述、常見的直出應(yīng)用來說,我們能夠優(yōu)化的點在哪里呢?讓我們來詳細分析一波,這也是今天我們要給大家分享的重點。

首先看看直出應(yīng)用各個環(huán)節(jié)的耗時表 (本地環(huán)境 2018款 iMac):

過程名稱 過程花費
Node 內(nèi) CGI 拉取 300 ms
RenderToString 20 ms
網(wǎng)絡(luò)耗時 10 ms
前端HTML渲染 30 ms

從上面的表中我們看出,直出渲染的耗時的大頭還是在 CGI 接口的拉取上。

我們現(xiàn)在提出兩個問題

CGI 接口的數(shù)據(jù)是否可以緩存 ?

HTML 又是否可以緩存 ?

一、接口的動靜分離

動態(tài)信息

這個頁面的接口數(shù)據(jù)中,有一些數(shù)據(jù),是實時變動的, 比如:當(dāng)前還剩多少個名額、此時此刻課程的價格、用戶是否購買過這個課程等。

這些數(shù)據(jù)的特性決定了這個數(shù)據(jù)接口不能夠被緩存。(假設(shè)將其緩存,那么就會存在可能用戶進來看到當(dāng)前還剩下10個名額,其實課程已經(jīng)賣光了的情況)

為了這個時間耗時的大頭,我們做了CGI接口的動靜分離。

將與用戶態(tài)、當(dāng)前時間沒有關(guān)聯(lián)的數(shù)據(jù)(比如課程標(biāo)題、課程上課的時間試聽模塊的地址等)放在一個接口(靜態(tài)接口),其他變化的數(shù)據(jù)放在另一個接口(動態(tài)接口)。

那么可以使用靜態(tài)的接口來做服務(wù)端渲染,好處是第一比較快(少了動態(tài)的信息,而且后臺也可以做緩存),第二 Node 直出可以做緩存了。

二、直出 Redis 緩存

這樣我們就可以將那部分靜態(tài)的、不會經(jīng)常變動的數(shù)據(jù)用來直出 HTML,然后將這個 HTML 文件緩存到 Redis 中。

客戶端請求此網(wǎng)頁,Node 端接受到請求之后,先去 Redis 里拿緩存的 HTML,如果 Redis 緩存沒有命中,則拉取靜態(tài)的 CGI 接口渲染出 HTML存入 Redis。

客戶端拿到 HTML 之后,會立刻渲染,然后再用 JS 去請求動態(tài)的數(shù)據(jù),渲染到相應(yīng)的地方。

做完之后我們可以看到優(yōu)化效果的提升是非常非常明顯的:

直接從 262ms 提升到了 16ms ?。ū镜丨h(huán)境),簡直飛一般的感覺,媽媽再也不用擔(dān)心領(lǐng)導(dǎo)看耗時了。

三、PWA 直出緩存
關(guān)于什么是 PWA ,以及如何使用,請移步這篇文章。

做了 Node 端直出的 HTML 緩存之后,我們接著優(yōu)化,接著思考,是否可以在客戶端也緩存 HTML,這樣連網(wǎng)絡(luò)延時這部分消耗也省掉呢。

答案就是使用 PWA 在客戶端做離線緩存,將我們直出的 HTML 緩存在客戶端,每次用戶請求的時候,直接從 PWA 離線緩存里取出對應(yīng)的直出頁面(HTML)響應(yīng)給用戶,響應(yīng)之后緊接著請求 Node 服務(wù)更新本地的 PWA 緩存。(如下圖所示)

核心代碼:

self.addEventListener("fetch", event => {  
 // TODO other logic (maybe fetch filter)

  // core logic
  event.respondWith(
    caches.open(cacheName).then(function(cache) {
      return cache.match(cacheCourseUrl).then(function(response) {
        var fetchPromise = fetch(cacheCourseUrl).then(function(
          networkResponse
        ) {
          if (networkResponse.status === 200) {
            cache.put(cacheCourseUrl, networkResponse.clone());
          }
          return networkResponse;
        });
        return response || fetchPromise;
      });
    })
  );
});

廢話不多說,先看效果對比 (左 PWA 直出;右 離線包):

duibi

從上圖可以看出,使用了 PWA 直出緩存之后,首屏渲染基本是毫秒開,可以說與 Native 并肩了。

經(jīng)過我們的數(shù)據(jù)測試,使用 PWA 直出緩存,首屏渲染的時間最好可以到400ms左右級別:

PWA 直出細節(jié)優(yōu)化
一、防頁面跳動

因為對接口進行了動靜分離,使用靜態(tài)接口直出頁面,然后在客戶端拉取動態(tài)數(shù)據(jù)渲染完。這就可能會導(dǎo)致頁面的抖動(比如詳情頁中的試聽模塊,是在客戶端渲染的)。

因為高度改變了,視覺上就會出現(xiàn)抖動(具體可以參考上面章節(jié)直出時候的 GIF 截圖)。

要去掉頁面抖動的情況,就必須保證容器的高度在直出時候已經(jīng)存在了。

比如這個試聽模塊,其實這個封面圖和試聽按鈕是可以在服務(wù)端渲染出來的,而后面的 Video 模塊則必須要在客戶度渲染(騰訊云 Tcplayer)。

所以這里可以拆分成:(試聽封面 + 按鈕 + 時間)服務(wù)端渲染 + 底層 Video(客戶端渲染)。

有些需要在客戶端計算高度的容器(表現(xiàn)為常放在 ComponentDidMount 里計算),如果它們依賴客戶端環(huán)境(比如依賴當(dāng)前系統(tǒng)是安卓還是 IOS),就導(dǎo)致他們肯定不能放在服務(wù)端直接渲染出來,這又怎么辦呢?

這里我們的做法,是將這些計算放在 HTML body 之前,通過內(nèi)聯(lián)的腳本嵌入,計算出當(dāng)前環(huán)境,給 body 加上一個特定的類(class),然后在這個特定的類下面的元素,就可以通過 css 給予特定的樣式。比如下面代碼:

/*
 * 因為在不同的手機 APP 環(huán)境內(nèi),頁面的 padding 是不一樣的。
 * 我們要在頁面渲染完之前加上相應(yīng)的 padding 
 */
var REGEXP_FUDAO_APP = /EducationApp/;
if (
  typeof navigator !== "undefined" &&
  REGEXP_FUDAO_APP.test(navigator.userAgent)
) {
  if (/Android/i.test(navigator.userAgent)) {
    document.body.classList.add("androidFudaoApp");
  } else if (/iPhone|iPad|iPod|iOS/i.test(navigator.userAgent)) {
    if (window.screen.width === 375 && window.screen.height === 812) {
      document.body.classList.add("iphoneXFudaoApp");
    } else {
      document.body.classList.add("iosFudaoApp");
    }
  }
}
.androidFudaoApp .tt {
  padding-top: 48px;
  background-position-y: 84px;
}

.iphoneXFudaoApp .tt {
  padding-top: 88px;
  background-position-y: 124px;
}

.iosFudaoApp .tt {
  padding-top: 64px;
  background-position-y: 100px;
}

然后把這段代碼通過構(gòu)建插入到頁面 body 之前。

-w500

防抖動優(yōu)化效果如下 (左優(yōu)化完,右未優(yōu)化):

duibi_doudong

二、冷啟動預(yù)加載

雖然我們做了 PWA 離線緩存,但是對于冷啟動來說,客戶端里面的 PWA 緩存還是沒有的,這樣就會導(dǎo)致初次點擊頁面,渲染速度相對慢一點。

這里我們可以在 APP 啟動的時候,用一個預(yù)加載的腳本最大限度的拉取用戶可能訪問的頁面。

核心代碼如下:

// 預(yù)加載頁面時, PWA 預(yù)緩存課程詳情頁面的直出
function prefetchCache(fetchUrl) {
    fetch("https://you preFetch Cgi")
      .then(data => {
        return data.json();
      })
      .then(res => {
        const { courseInfo = [] } = res.result || {};
        courseInfo.forEach(item => {
          if (item.cid) {
            caches.open(cacheName).then(function(cache) {
              fetch(`${courseURL}?course_id=${item.cid}`).then(function(
                networkResponse
              ) {
                if (networkResponse.status === 200) {
                  cache.put(
                    `${courseURL}?course_id=${item.cid}`,
                    networkResponse.clone()
                  );
                }
                // return networkResponse;
              });
            });
          }
        });
      })
      .catch(err => {
        // To monitor err
      });
}
PWA 直出遺留問題
一、兼容性問題

隨著 PWA 技術(shù)的發(fā)展,現(xiàn)今大部分手機以及 PC 環(huán)境已經(jīng)支持對 PWA 進行了支持。經(jīng)過我們的測試發(fā)現(xiàn):安卓基本上都是支持的,IOS 需要11.3以上才支持。

Service Workers 兼容性圖

二、IOS 渲染問題

很多的經(jīng)驗告訴我們,外聯(lián)的 script 標(biāo)簽要放在 body 的后面,因為它會阻塞頁面的 DOM 渲染。

經(jīng)過測試發(fā)現(xiàn),IOS 的 WebView (UIWebView)渲染機制并不會上述一樣,而是要等到后面的 JS 執(zhí)行完之后才渲染頁面,如果是這樣,我們的直出渲染優(yōu)化就沒有效果了(因為 HTML 并不在最開始渲染),這里可以使用 script 標(biāo)簽的 asyncdefer 屬性來達到異步渲染的作用。

升級 WkWebView 之后,情況得到改善,渲染正常。

附錄
參考資料

PWA 的探索與最佳實踐

億萬級訪問量下的前端同構(gòu)直出實踐

React 16 加載性能優(yōu)化指南

此文已由作者授權(quán)騰訊云+社區(qū)在各渠道發(fā)布

原文:企鵝輔導(dǎo)課程詳情頁毫秒開的秘密 - PWA 直出

獲取更多新鮮技術(shù)干貨,可以關(guān)注我們騰訊云技術(shù)社區(qū)-云加社區(qū)官方號及知乎機構(gòu)號

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/53567.html

相關(guān)文章

  • 老板虎軀震的前端技術(shù)KPI殺手

    摘要:我們的目標(biāo)是讓的頁面也能夠擁有般的體驗,如果你還在尋求什么技術(shù)能夠讓老板虎軀一震拯救你的,那么這篇文章或許能夠幫助到你。這是一個使用編寫的頁面,運行于多端,包括企鵝輔導(dǎo)手機手機瀏覽器。經(jīng)過我們的測試發(fā)現(xiàn)安卓基本上都是支持的,需要以上才支持。 本文由云+社區(qū)發(fā)表 作者:思衍Jax 天下武功,唯 (wei) 快(fu) 不(bu) 破(po)。 隨著近幾年的前端技術(shù)的高速發(fā)展,越來越多的...

    Jaden 評論0 收藏0
  • 前端文章集合

    摘要:優(yōu)化的探索與最佳實踐讓老板虎軀一震的前端技術(shù),殺手直出是個什么概念基于框架在中型移動端項目的直出同構(gòu)實踐瀏覽器瀏覽器渲染原理及流程瀏覽器渲染原理及解剖瀏覽器內(nèi)部工作原理全新使用指南開發(fā)者工具之內(nèi)存分析網(wǎng)站加載時間過長的原因和解決辦法深度剖析 優(yōu)化 PWA 的探索與最佳實踐 讓老板虎軀一震的前端技術(shù),KPI殺手 直出 是個什么概念? 基于 TVUE 框架在中型移動端項目的直出同構(gòu)實踐 ...

    omgdog 評論0 收藏0

發(fā)表評論

0條評論

PiscesYE

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<