You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2020/08/26 02:54:01 UTC

[skywalking-client-js] 41/48: feat: update perf detail

This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-client-js.git

commit cd46b4ebf07c712553022aa23fa6eedbd133b98e
Author: Qiuxia Fan <fi...@outlook.com>
AuthorDate: Thu Aug 6 17:03:30 2020 +0800

    feat: update perf detail
---
 src/monitor.ts            |  8 +++++++-
 src/performance/fmp.ts    | 47 +++++++++++------------------------------------
 src/performance/index.ts  | 25 +++++++++++++------------
 src/performance/perf.ts   | 31 +++++++------------------------
 src/performance/type.d.ts | 43 +++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 81 insertions(+), 73 deletions(-)

diff --git a/src/monitor.ts b/src/monitor.ts
index 7b903ba..3c405c2 100644
--- a/src/monitor.ts
+++ b/src/monitor.ts
@@ -65,7 +65,13 @@ const ClientMonitor = {
       ...this.customPerfOptions,
       ...options,
     };
-    Performance.recordPerf(customPerfOptions);
+    if (document.readyState === 'complete') {
+      Performance.recordPerf(customPerfOptions);
+    } else {
+      window.addEventListener('load', () => {
+        Performance.recordPerf(customPerfOptions);
+      }, false);
+    }
   },
 };
 
diff --git a/src/performance/fmp.ts b/src/performance/fmp.ts
index 8f5e8a9..ae5f1ac 100644
--- a/src/performance/fmp.ts
+++ b/src/performance/fmp.ts
@@ -14,16 +14,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-function getStyle(element: Element | any, attr: any) {
+import { ICalScore, Els } from './type';
+
+const getStyle = (element: Element | any, attr: any) => {
   if (window.getComputedStyle) {
     return window.getComputedStyle(element, null)[attr];
   } else {
     return element.currentStyle[attr];
   }
-}
-
-const START_TIME: number = performance.now();
-const IGNORE_TAG_SET: string[] = ['SCRIPT', 'STYLE', 'META', 'HEAD', 'LINK'];
+};
 
 enum ELE_WEIGHT {
   SVG = 2,
@@ -34,33 +33,22 @@ enum ELE_WEIGHT {
   VIDEO = 4,
 }
 
+const START_TIME: number = performance.now();
+const IGNORE_TAG_SET: string[] = ['SCRIPT', 'STYLE', 'META', 'HEAD', 'LINK'];
 const LIMIT: number = 3000;
 const WW: number = window.innerWidth;
 const WH: number = window.innerHeight;
 const DELAY: number = 500;
-interface ICalScore {
-  dpss: ICalScore[];
-  st: number;
-  els: Els;
-  root?: Element;
-}
-type Els = Array<{
-  $node: Element;
-  st: number;
-  weight: number;
-}>;
 
 class FMPTiming {
+  public fmpTime: number = 0;
   private statusCollector: Array<{time: number}> = [];
   private flag: boolean = true;
   private observer: MutationObserver = null;
   private callbackCount: number = 0;
   private entries: any = {};
-  private fmpCallback: any = null;
-  constructor(fmpCallback?: (res: any) => void) {
-    if (fmpCallback) {
-      this.fmpCallback = fmpCallback;
-    }
+
+  constructor() {
     this.initObserver();
   }
   private getFirstSnapShot(): void {
@@ -118,24 +106,11 @@ class FMPTiming {
           this.entries[item.name] = item.responseEnd;
         });
         if (!tp) {
-          if (this.fmpCallback) {
-            this.fmpCallback({
-              tp: null,
-              resultEls: [],
-              fmpTiming: 0,
-            });
-          }
           return false;
         }
         const resultEls: Els = this.filterResult(tp.els);
         const fmpTiming: number = this.getFmpTime(resultEls);
-        if (this.fmpCallback) {
-          this.fmpCallback({
-            tp,
-            resultEls,
-            fmpTiming,
-          });
-        }
+        this.fmpTime = fmpTiming;
     } else {
       setTimeout(() => {
         this.calculateFinalScore();
@@ -162,7 +137,7 @@ class FMPTiming {
           if (match && match[1]) {
             url = match[1];
           }
-          if (url.indexOf('http') === -1) {
+          if (!url.includes('http')) {
             url = location.protocol + match[1];
           }
           time = this.entries[url];
diff --git a/src/performance/index.ts b/src/performance/index.ts
index 65e0bb6..ef32ad8 100644
--- a/src/performance/index.ts
+++ b/src/performance/index.ts
@@ -19,27 +19,29 @@
 import { CustomPerfOptionsType } from '../types';
 import Report from '../services/report';
 import pagePerf from './perf';
+import FMP from './fmp';
+import { IPerfDetail } from './type';
 
 class TracePerf {
   private isPerf: boolean = true;
   private perfConfig = {
-    // resources: [],
     perfDetail: {},
-  } as any;
+  } as { perfDetail: IPerfDetail };
 
-  public recordPerf(options: CustomPerfOptionsType) {
-    setTimeout(async () => {
-      if (this.isPerf) {
-        this.perfConfig.perfDetail = await pagePerf.getPerfTiming();
-      }
+  public async recordPerf(options: CustomPerfOptionsType) {
+    if (this.isPerf) {
+      this.perfConfig.perfDetail = await new pagePerf().getPerfTiming();
+    }
+    const fmp: {fmpTime: number} = await new FMP();
+
+    setTimeout(() => {
       const perfInfo = {
-        perfDetail: this.perfConfig.perfDetail,
-        // resources: this.perfConfig.resources,
+        perfDetail: {...this.perfConfig.perfDetail, fmpTime: fmp.fmpTime},
         ...options,
       };
       new Report(options.reportUrl).sendByXhr(perfInfo);
       this.clearPerf();
-    }, 100);
+    }, 5000);
   }
 
   private clearPerf() {
@@ -48,9 +50,8 @@ class TracePerf {
     }
     window.performance.clearResourceTimings();
     this.perfConfig = {
-      // resources: [],
       perfDetail: {},
-    };
+    } as { perfDetail: IPerfDetail };
   }
 }
 
diff --git a/src/performance/perf.ts b/src/performance/perf.ts
index 2280447..4a62ed7 100644
--- a/src/performance/perf.ts
+++ b/src/performance/perf.ts
@@ -15,32 +15,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-import FMP from './fmp';
+import { IPerfDetail } from './type';
 class PagePerf {
-  private fmpTime: number = 0;
-
-  constructor() {
-    new FMP(this.getFmpTiming);
-  }
 
-  public getPerfTiming() {
+  public getPerfTiming(): IPerfDetail {
     try {
       if (!window.performance || !window.performance.timing) {
         console.log('your browser do not support performance');
         return;
       }
       const { timing } = window.performance;
-      const loadTime = timing.loadEventEnd - timing.loadEventStart;
       let redirectTime = 0;
 
-      if (loadTime < 0) {
-        setTimeout(() => {
-          this.getPerfTiming();
-        }, 3000);
-        return;
-      }
-
       if (timing.navigationStart !== undefined) {
         redirectTime = timing.fetchStart - timing.navigationStart;
       } else if (timing.redirectEnd !== undefined) {
@@ -48,6 +34,7 @@ class PagePerf {
       } else {
         redirectTime = 0;
       }
+
       return {
         redirectTime,
         dnsTime: timing.domainLookupEnd - timing.domainLookupStart,
@@ -59,20 +46,16 @@ class PagePerf {
         domReadyTime: timing.domContentLoadedEventEnd - timing.fetchStart,
         loadPage: timing.loadEventStart - timing.fetchStart, // Page full load time
         resTime: timing.loadEventStart - timing.domContentLoadedEventEnd, // Synchronous load resources in the page
-        sslTime: timing.connectEnd - timing.secureConnectionStart, // Only valid for HTTPS
+        // Only valid for HTTPS
+        sslTime: location.protocol.includes('https') ? timing.connectEnd - timing.secureConnectionStart : null,
         ttlTime: timing.domInteractive - timing.fetchStart, // time to interact
         firstPackTime: timing.responseStart - timing.domainLookupStart, // first pack time
-        fmpTime: this.fmpTime, // First Meaningful Paint
+        fmpTime: 0, // First Meaningful Paint
       };
     } catch (e) {
       throw e;
     }
   }
-
-  private getFmpTiming(data: any) {
-    console.log(data);
-    this.fmpTime = data.fmpTiming;
-  }
 }
 
-export default new PagePerf();
+export default PagePerf;
diff --git a/src/performance/type.d.ts b/src/performance/type.d.ts
new file mode 100644
index 0000000..03435f4
--- /dev/null
+++ b/src/performance/type.d.ts
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export interface ICalScore {
+  dpss: ICalScore[];
+  st: number;
+  els: Els;
+  root?: Element;
+}
+export type Els = Array<{
+  $node: Element;
+  st: number;
+  weight: number;
+}>;
+export type IPerfDetail = {
+  redirectTime: number | undefined;
+  dnsTime: number | undefined;
+  ttfbTime: number | undefined; // Time to First Byte
+  tcpTime: number | undefined;
+  transTime: number | undefined;
+  domAnalysisTime: number | undefined;
+  fptTime: number | undefined; // First Paint Time or Blank Screen Time
+  domReadyTime: number | undefined;
+  loadPage: number | undefined; // Page full load time
+  resTime: number | undefined; // Synchronous load resources in the page
+  sslTime: number | undefined; // Only valid for HTTPS
+  ttlTime: number | undefined; // time to interact
+  firstPackTime: number | undefined; // first pack time
+  fmpTime: number | undefined; // First Meaningful Paint
+};