H5 性能優化方案

1、減小cookie傳輸css

cookie傳輸會形成帶寬浪費,能夠:html

  • 減小cookie中存儲的東西
  • 靜態資源不須要cookie,能夠採用其餘的域名,不會主動帶上cookie。

2.避免過多的迴流與重繪webpack

3. Gizp 壓縮web

4JavaScriptCssHtml壓縮跨域

工程化項目中直接使用對應的插件便可,webpack的主要有下面三個:瀏覽器

  • UglifyJS
  • webpack-parallel-uglify-plugin
  • terser-webpack-plugin

5http2首部壓縮緩存

6.webpack 的優化cookie

1DllPlugin 提高構建速度網絡

2splitChunks 拆包antd

  1. 骨架屏幕,減小頁面的迴流和重繪
  2. 谷歌瀏覽器的light house插件。能夠檢測性能

本文主要介紹preload的使用,以及與prefetch的區別。而後會聊聊瀏覽器的加載優先級。

preload 提供了一種聲明式的命令,讓瀏覽器提早加載指定資源(加載後並不執行),在須要執行的時候再執行。提供的好處主要是

  • 將加載和執行分離開,可不阻塞渲染和 document 的 onload 事件
  • 提早加載指定資源,再也不出現依賴的font字體隔了一段時間才刷出

如何使用 preload

使用 link 標籤建立

<!-- 使用 link 標籤靜態標記須要預加載的資源 -->

<link rel="preload" href="/path/to/style.css" as="style">

<!-- 或使用腳本動態建立一個 link 標籤後插入到 head 頭部 -->

<script>

const link = document.createElement('link');

link.rel = 'preload';

link.as = 'style';

link.href = '/path/to/style.css';

document.head.appendChild(link);

</script>

使用 HTTP 響應頭的 Link 字段建立

Link: https://example.com/other/sty...; rel=preload; as=style

如咱們經常使用到的 antd 會依賴一個 CDN 上的 font.js 字體文件,咱們能夠設置爲提早加載,以及有一些模塊雖然是按需異步加載,但在某些場景下知道其一定會加載的,則能夠設置 preload 進行預加載,如:

<link rel="preload" as="font" href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff">

<link rel="preload" as="script" href="https://a.xxx.com/xxx/PcCommon.js">

<link rel="preload" as="script" href="https://a.xxx.com/xxx/TabsPc.js">

如何判斷瀏覽器是否支持 preload

目前咱們支持的瀏覽器主要爲高版本 Chrome,因此可放心使用 preload 技術。 其餘環境在 caniuse.com 上查到的支持狀況以下:

在不支持 preload 的瀏覽器環境中,會忽略對應的 link 標籤,而若須要作特徵檢測的話,則能夠用以下方法:

const isPreloadSupported = () => {

const link = document.createElement('link');

const relList = link.relList;

if (!relList || !relList.supports) {

return false;

}

return relList.supports('preload');

};

如何區分 preloadprefetch

  • preload 是告訴瀏覽器頁面一定須要的資源,瀏覽器必定會加載這些資源;
  • prefetch 是告訴瀏覽器頁面可能須要的資源,瀏覽器不必定會加載這些資源。

preload 是確認會加載指定資源,如在咱們的場景中,x-report.js 初始化後必定會加載 PcCommon.js 和 TabsPc.js, 則能夠預先 preload 這些資源;

prefetch 是預測會加載指定資源,如在咱們的場景中,咱們在頁面加載後會初始化首屏組件,當用戶滾動頁面時,會拉取第二屏的組件,若能預測用戶行爲,則能夠 prefetch 下一屏的組件。

preload 將提高資源加載的優先級

使用 preload 前,在遇到資源依賴時進行加載:

使用 preload 後,無論資源是否使用都將提早加載:

能夠看到,preload 的資源加載順序將被提早:

避免濫用 preload

使用 preload 後,Chrome 會有一個警告:

如上文所言,若不肯定資源是一定會加載的,則不要錯誤使用 preload,以避免本末倒置,給頁面帶來更沉重的負擔。

固然,能夠在 PC 中使用 preload 來刷新資源的緩存,但在移動端則須要特別慎重,由於可能會浪費用戶的帶寬。

避免混用 preloadprefetch

preload 和 prefetch 混用的話,並不會複用資源,而是會重複加載。

<link rel="preload" href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff" as="font">

<link rel="prefetch" href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff" as="font">

使用 preload 和 prefetch 的邏輯可能不是寫到一塊兒,但一旦發生對同一資源 preload 或 prefetch 的話,會帶來雙倍的網絡請求,這點經過 Chrome 控制檯的網絡面板就能甄別:

避免錯用 preload 加載跨域資源

若 css 中有應用於已渲染到 DOM 樹的元素的選擇器,且設置了 @font-face 規則時,會觸發字體文件的加載。 而字體文件加載中時,DOM 中的這些元素,是處於不可見的狀態。對已知必加載的 font 文件進行預加載,除了有性能提高外,更有體驗優化的效果。

在咱們的場景中,已知 antd.css 會依賴 font 文件,因此咱們能夠對這個字體文件進行 preload:

<link rel="preload" as="font" href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff">

然而我發現這個文件加載了兩次:

緣由是對跨域的文件進行 preload 的時候,咱們必須加上 crossorigin 屬性:

<link rel="preload" as="font" crossorigin href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff">

再看一下網絡請求,就變成一條了。

W3 規範是這麼解釋的:

Preload links for CORS enabled resources, such as fonts or images with a crossorigin attribute, must also include a crossorigin attribute, in order for the resource to be properly used.

那爲什麼會有兩條請求,且優先級不一致,又沒有命中緩存呢?這就得引出下一個話題來解釋了。

不一樣資源加載的優先級規則

咱們先來看一張圖:

這張表詳見:Chrome Resource Priorities and Scheduling

這張圖表示的是,在 Chrome 46 之後的版本中,不一樣的資源在瀏覽器渲染的不一樣階段進行加載的優先級。 在這裏,咱們只須要關注 DevTools Priority 體現的優先級,一共分紅五個級別:

  • Highest 最高
  • Hight 高
  • Medium 中等
  • Low 低
  • Lowest 最低

html 主要資源,其優先級是最高的

css 樣式資源,其優先級也是最高的

CSS(match) 指的是對已有的 DOM 具有規則的有效的樣式文件。

script 腳本資源,優先級不一

前三個 js 文件是寫死在 html 中的靜態資源依賴,後三個 js 文件是根據首屏按需異步加載的組件資源依賴,這正驗證了這個規則。font 字體資源,優先級不一

css 樣式文件中有一個 @font-face 依賴一個 font 文件,樣式文件中依賴的字體文件加載的優先級是 Highest; 在使用 preload 預加載這個 font 文件時,若不指定 crossorigin 屬性(即便同源),則會採用匿名模式的 CORS 去加載,優先級是 High,看下圖對比: 第一條 High 優先級也就是 preload 的請求:

第二條 Highest 也就是樣式引入的請求:

能夠看到,在 preload 的請求中,缺乏了一個 origin 的請求頭字段,表示這個請求是匿名的請求。 讓這兩個請求能共用緩存的話,目前的解法是給 preload 加上 crossorigin 屬性,這樣請求頭會帶上 origin, 且與樣式引入的請求同源,從而作到命中緩存:

<link rel="preload" as="font" crossorigin href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff">

這麼請求就只剩一個:

在網絡瀑布流圖中,也顯示成功預加載且後續命中緩存再也不二次加載:

總結

preload 是個好東西,能告訴瀏覽器提早加載當前頁面必須的資源,將加載與解析執行分離開,作得好能夠對首次渲染帶來不小的提高,但要避免濫用,區分其與 prefetch 的關係,且須要知道 preload 不一樣資源時的網絡優先級差別。

preload 加載頁面必需的資源如 CDN 上的字體文件,與 prefetch 預測加載下一屏數據,興許是個不錯的組合。

相關文章
相關標籤/搜索