<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何使用 Performance API 讓您的網(wǎng)站更快

          共 8296字,需瀏覽 17分鐘

           ·

          2021-07-05 04:31

          本教程介紹了如何使用 Performance API 記錄來自訪問您的應用程序的真實用戶的類似 DevTool 的統(tǒng)計信息。

          使用瀏覽器 DevTools 評估 Web 應用程序性能很有用,但復制實際使用情況并不容易。使用不同設備、瀏覽器和網(wǎng)絡的不同地點的人都會有不同的體驗。

          性能 API 簡介

          性能API使用緩沖記錄DevTool般在你的網(wǎng)頁的生命周期的特定點對象屬性指標。這些要點包括:

          1. 頁面導航:記錄頁面加載重定向、連接、握手、DOM 事件等。

          2. 資源加載:記錄圖片、CSS、腳本、Ajax 調用等資源加載。

          3. Paint metrics:記錄瀏覽器渲染信息。

          4. 自定義性能:記錄任意應用程序處理時間以查找慢功能。

          所有 API 都在客戶端 JavaScript 中可用,包括Web Workers。您可以使用以下方法檢測 API 支持:

          if ('performance' in window) {

          // call Performance APIs

          }

          注意:請注意,盡管實現(xiàn)了大部分 API,但 Safari 并不支持所有方法。

          自定義(用戶)性能 API 也復制到:

          • Node.js 內置performance_hook模塊,以及

          • Deno性能 API(使用它的腳本必須在--allow-hrtime許可下運行)。

          Date()不夠好?

          您可能已經看過使用該Date()函數(shù)記錄經過時間的示例。例如:

          const start = new Date();

          // ... run code ...

          const elapsed = new Date() - start;

          但是,Date()計算僅限于最接近的毫秒并基于系統(tǒng)時間,操作系統(tǒng)可以隨時更新系統(tǒng)時間。

          Performance API 使用一個單獨的、更高分辨率的計時器,可以在幾分之一毫秒內進行記錄。它還提供了以其他方式無法記錄的指標,例如重定向和 DNS 查找時間。

          記錄性能指標

          如果您可以將其記錄在某處,則在客戶端代碼中計算性能指標非常有用。您可以使用 Ajax Fetch / XMLHttpRequest請求或Beacon API將統(tǒng)計信息發(fā)送到您的服務器進行分析。

          或者,大多數(shù)分析系統(tǒng)提供自定義事件類 API 來記錄時間。例如,Google Analytics User Timings API可以DOMContentLoaded通過傳遞類別 ( 'pageload')、變量名稱 ( "DOMready") 和值來記錄時間:

          const pageload = performance.getEntriesByType( 'navigation' )[0];

          ga('send', 'timing', 'pageload', 'DOMready', pageload.domContentLoadedEventStart);

          此示例使用頁面導航計時 API。所以讓我們從那里開始……

          頁面導航時序

          在快速連接上測試您的網(wǎng)站不太可能代表用戶體驗。瀏覽器 DevTools網(wǎng)絡選項卡允許您調節(jié)速度,但它無法模擬較差或斷斷續(xù)續(xù)的 3G 信號。

          Navigation Timing API 將單個PerformanceNavigationTiming對象推送到性能緩沖區(qū)。它包含真實用戶觀察到的有關重定向、加載時間、文件大小、DOM 事件等的信息。

          通過運行訪問對象:

          const pagePerf = performance.getEntriesByType( 'navigation' );

          或者通過將頁面 URL ( window.location)傳遞給 來訪問它getEntriesByName() method

          const pagePerf = performance.getEntriesByName( window.location );

          兩者都返回一個包含具有只讀屬性的對象的單個元素的數(shù)組。例如:

          [
          {
          name: "https://site.com/",
          initiatorType: "navigation",
          entryType: "navigation",
          initiatorType: "navigation",
          type: "navigate",
          nextHopProtocol: "h2",
          startTime: 0
          ...
          }
          ]

          該對象包括資源標識屬性

          財產描述
          名稱資源網(wǎng)址
          條目類型性能類型——"navigation"對于頁面,"resource"對于資產
          發(fā)起者類型啟動下載的資源 -"navigation"用于頁面
          下一跳協(xié)議網(wǎng)絡協(xié)議
          服務器定時PerformanceServerTiming對象數(shù)組

          注意:performanceServerTiming namedescriptiondurationmetrics由服務器響應寫入 HTTPServer-Timing標頭

          該對象包括相對于頁面加載開始的以毫秒為單位的資源計時屬性。通常按以下順序預計時間:

          財產描述
          開始時間獲取開始時的時間戳 -0用于頁面
          工人開始啟動 Service Worker 之前的時間戳
          重定向開始第一次重定向的時間戳
          重定向結束收到上次重定向的最后一個字節(jié)后的時間戳
          獲取開始獲取資源之前的時間戳
          域查找開始DNS 查找前的時間戳
          域查找結束DNS 查找后的時間戳
          連接開始建立服務器連接前的時間戳
          連接結束建立服務器連接后的時間戳
          安全連接啟動SSL 握手前的時間戳
          請求開始瀏覽器請求前的時間戳
          響應開始瀏覽器收到第一個字節(jié)數(shù)據(jù)時的時間戳
          響應結束收到最后一個字節(jié)數(shù)據(jù)后的時間戳
          期間startTimeresponseEnd之間經過的時間

          該對象包括以字節(jié)為單位下載大小屬性

          財產描述
          傳輸大小資源大小,包括標題和正文
          編碼體尺寸解壓前的資源體大小
          解碼體尺寸解壓后的資源體大小

          最后,該對象包括進一步的導航和 DOM 事件屬性(在 Safari 中不可用):

          財產描述
          類型要么"navigate""reload""back_forward"或者"prerender"
          重定向計數(shù)重定向次數(shù)
          卸載事件開始unload上一個文檔事件之前的時間戳
          卸載事件結束unload上一個文檔事件之后的時間戳
          domInteractiveHTML 解析和 DOM 構建完成時的時間戳
          domContentLoadedEventStart

          運行DOMContentLoaded事件處理程序之前的時間戳

          domContentLoadedEventEnd

          運行DOMContentLoaded事件處理程序后的時間戳

          domCompleteDOM 構建和DOMContentLoaded事件完成時的時間戳
          加載事件開始頁面load事件觸發(fā)前的時間戳
          加載事件結束頁面load事件后的時間戳。下載所有資產

          在頁面完全加載后記錄頁面加載指標的示例:

          'performance' in window && window.addEventListener('load', () => {

          const
          pagePerf = performance.getEntriesByName( window.location )[0],
          pageDownload = pagePerf.duration,
          pageDomComplete = pagePerf.domComplete;

          });

          頁面資源時序

          PerformanceResourceTiming每當頁面加載圖像、字體、CSS 文件、JavaScript 文件或任何其他項目等資產時,Resource Timing API 都會將對象推送到性能緩沖區(qū)。跑步:

          const resPerf = performance.getEntriesByType( 'resource' );

          這將返回一組資源計時對象。這些具有與上面顯示頁面計時相同的屬性,但沒有導航和 DOM 事件信息。

          這是一個示例結果:

          [
          {
          name: "https://site.com/style.css",
          entryType: "resource",
          initiatorType: "link",
          fetchStart: 150,
          duration: 300
          ...
          },
          {
          name: "https://site.com/script.js",
          entryType: "resource",
          initiatorType: "script",
          fetchStart: 302,
          duration: 112
          ...
          },
          ...
          ]

          可以通過將其 URL 傳遞給.getEntriesByName()方法來檢查單個資源:

          const resourceTime = performance.getEntriesByName('https://site.com/style.css');

          這將返回一個包含單個元素的數(shù)組:

          [
          {
          name: "https://site.com/style.css",
          entryType: "resource",
          initiatorType: "link",
          fetchStart: 150,
          duration: 300
          ...
          }
          ]

          您可以使用 API 報告每個 CSS 文件的加載時間和解壓縮大小:

          // array of CSS files, load times, and file sizes
          const css = performance.getEntriesByType('resource')
          .filter( r => r.initiatorType === 'link' && r.name.includes('.css'))
          .map( r => ({

          name: r.name,
          load: r.duration + 'ms',
          size: r.decodedBodySize + ' bytes'

          }) );

          css數(shù)組現(xiàn)在包含每個 CSS 文件的對象。例如:

          [
          {
          name: "https://site.com/main.css",
          load: "155ms",
          size: "14304 bytes"
          },
          {
          name: "https://site.com/grid.css",
          load: "203ms",
          size: "5696 bytes"
          }
          ]

          注意:負載和大小為零表示資產已被緩存。

          至少 150 個資源指標對象將被記錄到性能緩沖區(qū)。您可以使用.setResourceTimingBufferSize(N)方法定義一個特定的數(shù)字。例如:

          // record 500 resources
          performance.setResourceTimingBufferSize(500);

          可以使用 清除現(xiàn)有指標.clearResourceTimings() method

          瀏覽器繪制時間

          First Contentful Paint (FCP)衡量用戶導航到您的頁面后呈現(xiàn)內容所需的時間。Chrome 的 DevTool Lighthouse 面板的Performance部分顯示了該指標。Google 認為 FCP 時間少于 2 秒是好的,并且您的頁面將比 Web 的 75% 顯示得更快。

          在以下情況下,Paint Timing API 將兩個記錄兩個PerformancePaintTiming對象推送到性能緩沖區(qū):

          • first-paint發(fā)生:瀏覽器繪制第一個像素,并且

          • first-contentful-paint發(fā)生:瀏覽器繪制 DOM 內容的第一項

          運行時,兩個對象都以數(shù)組形式返回:

          const paintPerf = performance.getEntriesByType( 'paint' );

          結果示例:

          [
          {
          "name": "first-paint",
          "entryType": "paint",
          "startTime": 125
          },
          {
          "name": "first-contentful-paint",
          "entryType": "paint",
          "startTime": 127
          }
          ]

          開始時間是相對于初始頁面加載。

          用戶計時

          Performance API 可用于為您自己的應用程序功能計時。所有用戶計時方法都可以在客戶端 JavaScript、Web Workers、Deno 和 Node.js 中使用。

          請注意,Node.js 腳本必須加載Performance hooks( perf_hooks) 模塊

          CommonJSrequire語法:

          const { performance } = require('perf_hooks');

          或者 ES 模塊import語法:

          import { performance } from 'perf_hooks';

          最簡單的選項是performance.now(),它返回進程生命周期開始時的高分辨率時間戳。

          您可以performance.now()用于簡單的計時器。例如:

          const start = performance.now();

          // ... run code ...

          const elapsed = performance.now() - start;

          注意:非標準timeOrigin屬性返回 Unix 時間的時間戳。它可以在 Node.js 和瀏覽器 JavaScript 中使用,但不能在 IE 和 Safari 中使用。

          performance.now()在管理多個計時器時很快變得不切實際。該.mark()方法將一個命名的PerformanceMark 對象對象添加到性能緩沖區(qū)。例如:

          performance.mark('script:start');

          performance.mark('p1:start');
          // ... run process 1 ...
          performance.mark('p1:end');

          performance.mark('p2:start');
          // ... run process 2 ...
          performance.mark('p2:end');

          performance.mark('script:end');

          以下代碼返回一個標記對象數(shù)組:

          const marks = performance.getEntriesByType( 'mark' );

          entryTypenamestartTime屬性:

          [
          {
          entryType: "mark",
          name: "script:start",
          startTime: 100
          },
          {
          entryType: "mark",
          name: "p1:start",
          startTime: 200
          },
          {
          entryType: "mark",
          name: "p1:end",
          startTime: 300
          },
          ...
          ]

          可以使用該.measure()方法計算兩個標記之間經過的時間。它傳遞了一個度量名稱、開始標記名稱(或null使用零)和結束標記名稱(或null使用當前時間):

          performance.measure('p1', 'p1:start', 'p1:end');
          performance.measure('script', null, 'script:end');

          每次調用都會將具有計算持續(xù)時間的PerformanceMeasure對象推送到性能緩沖區(qū)。可以通過運行來訪問一系列度量:

          const measures = performance.getEntriesByType( 'measure' );

          例子:

          [
          {
          entryType: "measure",
          name: "p1",
          startTime: 200,
          duration: 100
          },
          {

          entryType: "measure",
          name: "script",
          startTime: 0,
          duration: 500
          }
          ]

          可以使用以下.getEntriesByName()方法按名稱檢索標記或測量對象:

          performance.getEntriesByName( 'p1' );

          其他方法:

          • .getEntries(): 返回所有性能條目的數(shù)組。

          • .clearMarks( [name] ): 清除命名標記(不帶名稱運行以清除所有標記)

          • .clearMeasures( [name] ): 清除已命名的度量(不帶名稱運行以清除所有度量)

          一個PerformanceObserver可以觀看更改到緩沖區(qū),并運行一個函數(shù),當特定對象出現(xiàn)。觀察者函數(shù)定義有兩個參數(shù):

          1. list: 觀察者條目

          2. observer(可選觀察者對象


          function performanceHandler(list, observer) {

          list.getEntries().forEach(entry => {

          console.log(`name : ${ entry.name }`);
          console.log(`type : ${ entry.type }`);
          console.log(`duration: ${ entry.duration }`);

          // other code, e.g.
          // send data via an Ajax request

          });

          }

          這個函數(shù)被傳遞給一個新PerformanceObserver對象。該.observe()方法然后將觀察到的entryTypes(通常"mark""measure"和/或"resource"):

          let observer = new PerformanceObserver( performanceHandler );
          observer.observe( { entryTypes: [ 'mark', 'measure' ] } );

          performanceHandler()每當將新標記或度量對象推送到性能緩沖區(qū)時,該函數(shù)就會運行。

          自我分析 API

          自我剖析API是關系到性能API和可以幫助找到低效或不必要的后臺功能,而無需手動設置標志和措施。

          示例代碼:

          // new profiler, 10ms sample rate
          const profile = await performance.profile({ sampleInterval: 10 });

          // ... run code ...

          // stop profiler, get trace
          const trace = await profile.stop();

          跟蹤返回有關在每個采樣間隔執(zhí)行的腳本、函數(shù)和行號的數(shù)據(jù)。重復引用相同的代碼可能表明進一步優(yōu)化是可能的。

          API 目前正在開發(fā)中(請參閱Chrome 狀態(tài))并且可能會發(fā)生變化。

          調整應用程序性能

          性能 API 提供了一種方法來衡量網(wǎng)站和應用程序在真實設備上的網(wǎng)站和應用程序速度,這些設備由真實的人在不同位置使用一系列連接。它可以輕松地為每個人整理類似 DevTool 的指標并識別潛在的瓶頸。

          解決這些性能問題是另一回事,但SitePoint Jump Start Web Performance 一書會有所幫助。它提供了一系列快餐、簡單的食譜和改變生活的飲食,讓您的網(wǎng)站更快、響應更快。

          瀏覽 115
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  大香蕉大香蕉最新视频97 | 91白丝在线观看 | 超碰97在线免费 | 午夜老司机福利 | 91狠狠操|