• Web Vitals All In One


    Web Vitals All In One

    Web 指标

    1. Largest Contentful Paint (LCP): measures loading performance.
      To provide a good user experience, LCP should occur within 2.5 seconds of when the page first starts loading.

    2. First Input Delay (FID): measures interactivity.
      To provide a good user experience, pages should have a FID of 100 milliseconds or less.

    3. Cumulative Layout Shift (CLS): measures visual stability.
      To provide a good user experience, pages should maintain a CLS of 0.1. or less.

    demo

    https://www.npmjs.com/package/web-vitals

    import {getCLS, getFID, getLCP} from 'web-vitals';
    
    // onReport callback
    function sendToAnalytics(metric) {
      // 收集的性能指标数据
      const body = JSON.stringify(metric);
      if(navigator.sendBeacon) {
        // Use `navigator.sendBeacon()` if available
        navigator.sendBeacon('/analytics', body)
      } else {
        // falling back to `fetch()`.
        fetch('/analytics', {body, method: 'POST', keepalive: true});
        // keepalive ❓
      }
    }
    
    getCLS(sendToAnalytics);
    getFID(sendToAnalytics);
    getLCP(sendToAnalytics);
    
    
    
    // once call 当指标准备好报告时
    getCLS(console.log);
    
    // multi call 报告每次更改的值
    getCLS(console.log, true);
    
    
    import {getCLS, getFID, getLCP} from 'web-vitals';
    
    // 仅报告更改的增量
    function logDelta({name, id, delta}) {
      console.log(`${name} matching ID ${id} changed by ${delta}`);
    }
    
    getCLS(logDelta);
    getFID(logDelta);
    getLCP(logDelta);
    
    

    PerformanceObserver

    https://web.dev/vitals/
    https://web.dev/i18n/zh/vitals/

    https://github.com/GoogleChrome/web-vitals

    // 将多个报告一起批处理
    
    import {getCLS, getFID, getLCP} from 'web-vitals';
    
    const queue = new Set();
    
    function addToQueue(metric) {
      queue.add(metric);
    }
    
    function flushQueue() {
      if (queue.size > 0) {
        // Replace with whatever serialization method you prefer.
        // Note: JSON.stringify will likely include more data than you need.
        const body = JSON.stringify([...queue]);
    
      if(navigator.sendBeacon) {
        // Use `navigator.sendBeacon()` if available
        navigator.sendBeacon('/analytics', body)
      } else {
        // falling back to `fetch()`.
        fetch('/analytics', {body, method: 'POST', keepalive: true});
        // keepalive ❓
      }
        // 上报完成,清零
        queue.clear();
      }
    }
    
    getCLS(addToQueue);
    getFID(addToQueue);
    getLCP(addToQueue);
    
    // Report all available metrics whenever the page is backgrounded or unloaded.
    // 当页面后台或卸载时报告所有可用指标。
    addEventListener('visibilitychange', () => {
      if (document.visibilityState === 'hidden') {
        flushQueue();
      }
    });
    
    // NOTE: Safari does not reliably fire the `visibilitychange` event when the  page is being unloaded.
    // If Safari support is needed, you should also flush the queue in the `pagehide` event.
    addEventListener('pagehide', flushQueue);
    
    

    Note: see the Page Lifecycle guide for an explanation of why visibilitychange and pagehide are recommended over events like beforeunload and unload.

    https://developers.google.com/web/updates/2018/07/page-lifecycle-api#legacy-lifecycle-apis-to-avoid

    cdn

    <!-- Append the `?module` param to load the module version of `web-vitals` -->
    <script type="module">
      import {getCLS, getFID, getLCP} from 'https://unpkg.com/web-vitals?module';
    
      getCLS(console.log);
      getFID(console.log);
      getLCP(console.log);
    </script>
    
    
    <script>
    (function() {
      var script = document.createElement('script');
      script.src = 'https://unpkg.com/web-vitals/dist/web-vitals.iife.js';
      script.onload = function() {
        // When loading `web-vitals` using a classic script, all the public
        // methods can be found on the `webVitals` global namespace.
        webVitals.getCLS(console.log);
        webVitals.getFID(console.log);
        webVitals.getLCP(console.log);
      }
      document.head.appendChild(script);
    }())
    </script>
    
    

    Metric

    interface Metric {
      // The name of the metric (in acronym form).
      name: 'CLS' | 'FCP' | 'FID' | 'LCP' | 'TTFB';
    
      // The current value of the metric.
      value: number;
    
      // The delta between the current value and the last-reported value.
      // On the first report, `delta` and `value` will always be the same.
      delta: number;
    
      // A unique ID representing this particular metric that's specific to the
      // current page. This ID can be used by an analytics tool to dedupe
      // multiple values sent for the same metric, or to group multiple deltas
      // together and calculate a total.
      id: string;
    
      // Any performance entries used in the metric value calculation.
      // Note, entries will be added to the array as the value changes.
      entries: (PerformanceEntry | FirstInputPolyfillEntry | NavigationTimingPolyfillEntry)[];
    }
    
    
    interface ReportHandler {
      (metric: Metric): void;
    }
    
    // Event Timing API
    type FirstInputPolyfillEntry = Omit<PerformanceEventTiming, 'processingEnd' | 'toJSON'>
    
    interface FirstInputPolyfillCallback {
      (entry: FirstInputPolyfillEntry): void;
    }
    
    
    // Navigation Timing API Level 2 
    export type NavigationTimingPolyfillEntry = Omit<PerformanceNavigationTiming,
      'initiatorType' | 'nextHopProtocol' | 'redirectCount' | 'transferSize' |
      'encodedBodySize' | 'decodedBodySize' | 'toJSON'>
    
    interface WebVitalsGlobal {
      firstInputPolyfill: (onFirstInput: FirstInputPolyfillCallback) => void;
      resetFirstInputPolyfill: () => void;
      firstHiddenTime: number;
    }
    
    
    interface WebVitalsGlobal {
      firstInputPolyfill: (onFirstInput: FirstInputPolyfillCallback) => void;
      resetFirstInputPolyfill: () => void;
      firstHiddenTime: number;
    }
    
    
    
    type getCLS = (onReport: ReportHandler, reportAllChanges?: boolean) => void
    
    type getFCP = (onReport: ReportHandler, reportAllChanges?: boolean) => void
    
    type getFID = (onReport: ReportHandler, reportAllChanges?: boolean) => void
    
    type getLCP = (onReport: ReportHandler, reportAllChanges?: boolean) => void
    
    type getTTFB = (onReport: ReportHandler, reportAllChanges?: boolean) => void
    
    
    
    import {getTTFB} from 'web-vitals';
    
    getTTFB((metric) => {
      // Calculate the request time by subtracting from TTFB
      // everything that happened prior to the request starting.
      const requestTime = metric.value - metric.entries[0].requestStart;
      console.log('Request time:', requestTime);
    });
    
    
    

    DOM 高分辨率时间戳 / DOM 高精度时间戳

    https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp

    automation test framework

    Next-gen browser and mobile automation test framework for Node.js

    
    $ npm install --save-dev @wdio/cli
    $ npx wdio config --yes
    $ npx wdio run
    
    

    https://webdriver.io/

    https://github.com/webdriverio/webdriverio

    Google Analytics

    analytics.js

    import {getCLS, getFID, getLCP} from 'web-vitals';
    
    function sendToGoogleAnalytics({name, delta, id}) {
      // Assumes the global `ga()` function exists, see:
      // https://developers.google.com/analytics/devguides/collection/analyticsjs
      ga('send', 'event', {
        eventCategory: 'Web Vitals',
        eventAction: name,
        // The `id` value will be unique to the current page load. When sending
        // multiple values from the same page (e.g. for CLS), Google Analytics can
        // compute a total by grouping on this ID (note: requires `eventLabel` to
        // be a dimension in your report).
        eventLabel: id,
        // Google Analytics metrics must be integers, so the value is rounded.
        // For CLS the value is first multiplied by 1000 for greater precision
        // (note: increase the multiplier for greater precision if needed).
        eventValue: Math.round(name === 'CLS' ? delta * 1000 : delta),
        // Use a non-interaction event to avoid affecting bounce rate.
        nonInteraction: true,
        // Use `sendBeacon()` if the browser supports it.
        transport: 'beacon',
    
        // OPTIONAL: any additional params or debug info here.
        // See: https://web.dev/debug-web-vitals-in-the-field/
        // dimension1: '...',
        // dimension2: '...',
        // ...
      });
    }
    
    getCLS(sendToGoogleAnalytics);
    getFID(sendToGoogleAnalytics);
    getLCP(sendToGoogleAnalytics);
    
    

    gtag.js (Universal Analytics)

    import {getCLS, getFID, getLCP} from 'web-vitals';
    
    function sendToGoogleAnalytics({name, delta, id}) {
      // Assumes the global `gtag()` function exists, see:
      // https://developers.google.com/analytics/devguides/collection/gtagjs
      gtag('event', name, {
        event_category: 'Web Vitals',
        // The `id` value will be unique to the current page load. When sending
        // multiple values from the same page (e.g. for CLS), Google Analytics can
        // compute a total by grouping on this ID (note: requires `eventLabel` to
        // be a dimension in your report).
        event_label: id,
        // Google Analytics metrics must be integers, so the value is rounded.
        // For CLS the value is first multiplied by 1000 for greater precision
        // (note: increase the multiplier for greater precision if needed).
        value: Math.round(name === 'CLS' ? delta * 1000 : delta),
        // Use a non-interaction event to avoid affecting bounce rate.
        non_interaction: true,
    
        // OPTIONAL: any additional params or debug info here.
        // See: https://web.dev/debug-web-vitals-in-the-field/
        // metric_rating: 'good' | 'ni' | 'poor',
        // debug_info: '...',
        // ...
      });
    }
    
    getCLS(sendToGoogleAnalytics);
    getFID(sendToGoogleAnalytics);
    getLCP(sendToGoogleAnalytics);
    
    

    https://developers.google.com/analytics/devguides/reporting/core/v4

    https://developers.google.com/analytics/devguides/reporting/core/v4/quickstart/web-js

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>Hello Analytics Reporting API V4</title>
      <meta name="google-signin-client_id" content="<REPLACE_WITH_CLIENT_ID>">
      <meta name="google-signin-scope" content="https://www.googleapis.com/auth/analytics.readonly">
    </head>
    <body>
    
    <h1>Hello Analytics Reporting API V4</h1>
    
    <!-- The Sign-in button. This will run `queryReports()` on success. -->
    <p class="g-signin2" data-onsuccess="queryReports"></p>
    
    <!-- The API response will be printed here. -->
    <textarea cols="80" rows="20" id="query-output"></textarea>
    
    <script>
      // Replace with your view ID.
      var VIEW_ID = '<REPLACE_WITH_VIEW_ID>';
    
      // Query the API and print the results to the page.
      function queryReports() {
        gapi.client.request({
          path: '/v4/reports:batchGet',
          root: 'https://analyticsreporting.googleapis.com/',
          method: 'POST',
          body: {
            reportRequests: [
              {
                viewId: VIEW_ID,
                dateRanges: [
                  {
                    startDate: '7daysAgo',
                    endDate: 'today'
                  }
                ],
                metrics: [
                  {
                    expression: 'ga:sessions'
                  }
                ]
              }
            ]
          }
        }).then(displayResults, console.error.bind(console));
      }
    
      function displayResults(response) {
        var formattedJson = JSON.stringify(response.result, null, 2);
        document.getElementById('query-output').value = formattedJson;
      }
    </script>
    
    <!-- Load the JavaScript API client and Sign-in library. -->
    <script src="https://apis.google.com/js/client:platform.js"></script>
    
    </body>
    </html>
    
    

    Google Analytics Reporting API

    https://github.com/GoogleChromeLabs/web-vitals-report

    https://developers.google.com/analytics/devguides/reporting

    refs

    Web 性能监控

    https://github.com/web-fullstack/web-vitals

    https://www.cnblogs.com/xgqfrms/p/16514500.html



    ©xgqfrms 2012-2020

    www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

    原创文章,版权所有©️xgqfrms, 禁止转载 ️,侵权必究⚠️!


  • 相关阅读:
    python多线程爬虫:亚马逊价格
    python在linux中输出带颜色的文字的方法
    单线程爬虫VS多线程爬虫的效率对比
    python爬虫:正则表达式
    爬虫-python调用百度API/requests
    Python gevent学习笔记-2
    Python gevent学习笔记
    IO多路复用之select总结
    select、poll、epoll之间的区别总结[整理]
    2020年 IEDA破解码失效,2019 版IDEA无法使用 ,已解决,有效期2100年;原标题:IDEA激活—免费永久激活(lookdiv.com)
  • 原文地址:https://www.cnblogs.com/xgqfrms/p/16514500.html
Copyright © 2020-2023  润新知