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 2025/01/09 13:52:26 UTC

(skywalking) branch master updated: Support new browser metrics upload API (#12948)

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.git


The following commit(s) were added to refs/heads/master by this push:
     new 3232b54752 Support new browser metrics upload API (#12948)
3232b54752 is described below

commit 3232b547528bba435a15070694f122d76049ecc0
Author: mrproliu <74...@qq.com>
AuthorDate: Thu Jan 9 21:52:20 2025 +0800

    Support new browser metrics upload API (#12948)
---
 apm-protocol/apm-network/src/main/proto            |   2 +-
 docs/en/changes/changes.md                         |   6 +-
 .../apache/skywalking/oal/rt/grammar/OALLexer.g4   |   2 +
 .../apache/skywalking/oal/rt/grammar/OALParser.g4  |   2 +-
 .../endpoint/BrowserAppPageTrafficDispatcher.java  |   1 +
 .../browser/source/BrowserAppResourcePerf.java     |  63 ++
 .../browser/source/BrowserAppWebVitalsPerf.java    |  61 ++
 .../oap/server/core/source/DefaultScopeDefine.java |   3 +
 .../browser/provider/BrowserModuleProvider.java    |  14 +-
 .../handler/grpc/BrowserPerfServiceHandler.java    |  47 +-
 .../rest/BrowserPerfServiceHTTPHandler.java        |  38 +-
 .../parser/performance/PerfDataAnalyzer.java       |  37 +-
 .../performance/PerfDataParserListenerManager.java |  34 +-
 .../{ => decorators}/BrowserPerfDataDecorator.java |   4 +-
 .../BrowserPerfDecorator.java}                     |  25 +-
 .../BrowserResourcePerfDataDecorator.java          |  83 +++
 .../BrowserWebVitalsPerfDataDecorator.java}        |  93 +--
 ...r.java => BrowserPerfDataAnalysisListener.java} |  18 +-
 ...lder.java => BrowserPerfDataSourceBuilder.java} |   2 +-
 ...BrowserWebResourcePerfDataAnalysisListener.java |  78 +++
 .../BrowserWebVitalsPerfDataAnalysisListener.java  |  76 +++
 .../listener/PerfDataAnalysisListener.java         |   6 +-
 .../listener/PerfDataListenerFactory.java          |   5 +-
 .../src/main/resources/oal/browser.oal             |  10 +
 .../browser/browser-page.json                      | 631 ++++++++++++++++++++-
 25 files changed, 1197 insertions(+), 144 deletions(-)

diff --git a/apm-protocol/apm-network/src/main/proto b/apm-protocol/apm-network/src/main/proto
index bd1f91f7e1..385fb8b005 160000
--- a/apm-protocol/apm-network/src/main/proto
+++ b/apm-protocol/apm-network/src/main/proto
@@ -1 +1 @@
-Subproject commit bd1f91f7e1cb4de9d9b5ccb71f36ce6b1c7c97f5
+Subproject commit 385fb8b0057b98c9350f7a94d228b977f5154d4b
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index 7f392efdd9..dbf0a69f14 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -13,8 +13,6 @@
     source tar from the website and publish them to your private maven repository.
 * [Breaking Change] Remove H2 as storage option permanently. BanyanDB 0.8(OAP 10.2 required) is easy, stable and 
   production-ready. Don't need H2 as default storage anymore.
-* Support `labelAvg` function in the OAL engine.
-* Added `maxLabelCount` parameter in the `labelCount` function of OAL to limit the number of labels can be counted.
 
 #### OAP Server
 
@@ -56,6 +54,9 @@
 * Fix `AvgHistogramPercentileFunction` doesn't have proper field definition for `ranks`.
 * BanyanDB: Support the new Property data module.
 * MQE: Support `top_n_of` function for merging multiple metrics topn query.
+* Support `labelAvg` function in the OAL engine.
+* Added `maxLabelCount` parameter in the `labelCount` function of OAL to limit the number of labels can be counted.
+* Adapt the new Browser API(`/browser/perfData/webVitals`, `/browser/perfData/resources`) protocol.
 
 #### UI
 
@@ -78,6 +79,7 @@
 * Optimize Trace Profiling widget.
 * Implement Async Profiling widget.
 * Fix inaccurate data query issue on endpoint topology page.
+* Update browser dashboard for the new metrics.
 
 #### Documentation
 * Update release document to adopt newly added revision-based process.
diff --git a/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALLexer.g4 b/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALLexer.g4
index ccb6cd74d5..6ddd83d600 100644
--- a/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALLexer.g4
+++ b/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALLexer.g4
@@ -73,6 +73,8 @@ SRC_BROWSER_APP_SINGLE_VERSION_PERF: 'BrowserAppSingleVersionPerf';
 SRC_BROWSER_APP_TRAFFIC: 'BrowserAppTraffic';
 SRC_BROWSER_APP_PAGE_TRAFFIC: 'BrowserAppPageTraffic';
 SRC_BROWSER_APP_SINGLE_VERSION_TRAFFIC: 'BrowserAppSingleVersionTraffic';
+SRC_BROWSER_APP_RESOURCE_PERF: 'BrowserAppResourcePerf';
+SRC_BROWSER_APP_WEB_VITALS_PERF: 'BrowserAppWebVitalsPerf';
 
 // Constructors symbols
 
diff --git a/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALParser.g4 b/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALParser.g4
index e78a3102da..f1ec8c4045 100644
--- a/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALParser.g4
+++ b/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALParser.g4
@@ -59,7 +59,7 @@ source
       SRC_SERVICE_INSTANCE_CLR_CPU | SRC_SERVICE_INSTANCE_CLR_GC | SRC_SERVICE_INSTANCE_CLR_THREAD |
       SRC_SERVICE_INSTANCE_JVM_CPU | SRC_SERVICE_INSTANCE_JVM_MEMORY | SRC_SERVICE_INSTANCE_JVM_MEMORY_POOL | SRC_SERVICE_INSTANCE_JVM_GC | SRC_SERVICE_INSTANCE_JVM_THREAD | SRC_SERVICE_INSTANCE_JVM_CLASS |// JVM source of service instance
       SRC_ENVOY_INSTANCE_METRIC |
-      SRC_BROWSER_APP_PERF | SRC_BROWSER_APP_PAGE_PERF | SRC_BROWSER_APP_SINGLE_VERSION_PERF |
+      SRC_BROWSER_APP_PERF | SRC_BROWSER_APP_PAGE_PERF | SRC_BROWSER_APP_SINGLE_VERSION_PERF | SRC_BROWSER_APP_RESOURCE_PERF | SRC_BROWSER_APP_WEB_VITALS_PERF |
       SRC_BROWSER_APP_TRAFFIC | SRC_BROWSER_APP_PAGE_TRAFFIC | SRC_BROWSER_APP_SINGLE_VERSION_TRAFFIC |
       SRC_EVENT | SRC_MQ_ACCESS | SRC_MQ_ENDPOINT_ACCESS |
       SRC_K8S_SERVICE | SRC_K8S_SERVICE_INSTANCE | SRC_K8S_ENDPOINT | SRC_K8S_SERVICE_RELATION | SRC_K8S_SERVICE_INSTANCE_RELATION |
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/browser/manual/endpoint/BrowserAppPageTrafficDispatcher.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/browser/manual/endpoint/BrowserAppPageTrafficDispatcher.java
index 8df13e6f1e..443a1ddcfb 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/browser/manual/endpoint/BrowserAppPageTrafficDispatcher.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/browser/manual/endpoint/BrowserAppPageTrafficDispatcher.java
@@ -30,6 +30,7 @@ public class BrowserAppPageTrafficDispatcher extends BrowserAppTrafficSourceDisp
         traffic.setTimeBucket(source.getTimeBucket());
         traffic.setName(source.getName());
         traffic.setServiceId(source.getServiceId());
+        traffic.setLastPingTimestamp(source.getTimeBucket());
         MetricsStreamProcessor.getInstance().in(traffic);
     }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/browser/source/BrowserAppResourcePerf.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/browser/source/BrowserAppResourcePerf.java
new file mode 100644
index 0000000000..cda18af2e0
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/browser/source/BrowserAppResourcePerf.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.skywalking.oap.server.core.browser.source;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.skywalking.oap.server.core.analysis.IDManager;
+import org.apache.skywalking.oap.server.core.source.ScopeDeclaration;
+import org.apache.skywalking.oap.server.core.source.ScopeDefaultColumn;
+import org.apache.skywalking.oap.server.core.source.Source;
+
+import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.BROWSER_APP_RESOURCE_PERF;
+import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.ENDPOINT_CATALOG_NAME;
+
+@ScopeDeclaration(id = BROWSER_APP_RESOURCE_PERF, name = "BrowserAppResourcePerf", catalog = ENDPOINT_CATALOG_NAME)
+@ScopeDefaultColumn.VirtualColumnDefinition(fieldName = "entityId", columnName = "entity_id", isID = true, type = String.class)
+@Setter
+@Getter
+public class BrowserAppResourcePerf extends Source {
+
+    @Override
+    public int scope() {
+        return BROWSER_APP_RESOURCE_PERF;
+    }
+
+    @Override
+    public String getEntityId() {
+        return IDManager.EndpointID.buildId(serviceId, path);
+    }
+
+    @ScopeDefaultColumn.DefinedByField(columnName = "service_id")
+    @ScopeDefaultColumn.BanyanDB(groupByCondInTopN = true)
+    private String serviceId;
+    @ScopeDefaultColumn.DefinedByField(columnName = "service_name", requireDynamicActive = true)
+    private String serviceName;
+    private String path;
+    private String name;
+    private int duration;
+    private int size;
+    private String protocol;
+    private String type;
+
+    @Override
+    public void prepare() {
+        serviceId = IDManager.ServiceID.buildId(serviceName, true);
+    }
+}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/browser/source/BrowserAppWebVitalsPerf.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/browser/source/BrowserAppWebVitalsPerf.java
new file mode 100644
index 0000000000..95c003596c
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/browser/source/BrowserAppWebVitalsPerf.java
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.skywalking.oap.server.core.browser.source;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.skywalking.oap.server.core.analysis.IDManager;
+import org.apache.skywalking.oap.server.core.source.ScopeDeclaration;
+import org.apache.skywalking.oap.server.core.source.ScopeDefaultColumn;
+import org.apache.skywalking.oap.server.core.source.Source;
+
+import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.BROWSER_APP_WEB_VITALS_PAGE_PERF;
+import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.ENDPOINT_CATALOG_NAME;
+
+@ScopeDeclaration(id = BROWSER_APP_WEB_VITALS_PAGE_PERF, name = "BrowserAppWebVitalsPerf", catalog = ENDPOINT_CATALOG_NAME)
+@ScopeDefaultColumn.VirtualColumnDefinition(fieldName = "entityId", columnName = "entity_id", isID = true, type = String.class)
+@Setter
+@Getter
+public class BrowserAppWebVitalsPerf extends Source {
+
+    @Override
+    public int scope() {
+        return BROWSER_APP_WEB_VITALS_PAGE_PERF;
+    }
+
+    @Override
+    public String getEntityId() {
+        return IDManager.EndpointID.buildId(serviceId, path);
+    }
+
+    @ScopeDefaultColumn.DefinedByField(columnName = "service_id")
+    @ScopeDefaultColumn.BanyanDB(groupByCondInTopN = true)
+    private String serviceId;
+    @ScopeDefaultColumn.DefinedByField(columnName = "service_name", requireDynamicActive = true)
+    private String serviceName;
+    private String path;
+    private int fmpTime;
+    private int clsTime;
+    private int lcpTime;
+
+    @Override
+    public void prepare() {
+        serviceId = IDManager.ServiceID.buildId(serviceName, true);
+    }
+}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java
index 88595ad457..15eed04799 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java
@@ -147,6 +147,9 @@ public class DefaultScopeDefine {
     public static final int ASYNC_PROFILER_TASK = 85;
     public static final int ASYNC_PROFILER_TASK_LOG = 86;
 
+    public static final int BROWSER_APP_WEB_VITALS_PAGE_PERF = 87;
+    public static final int BROWSER_APP_RESOURCE_PERF = 88;
+
     /**
      * Catalog of scope, the metrics processor could use this to group all generated metrics by oal rt.
      */
diff --git a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/BrowserModuleProvider.java b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/BrowserModuleProvider.java
index d7e6dd074b..2ee5969356 100644
--- a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/BrowserModuleProvider.java
+++ b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/BrowserModuleProvider.java
@@ -36,7 +36,12 @@ import org.apache.skywalking.oap.server.receiver.browser.provider.parser.errorlo
 import org.apache.skywalking.oap.server.receiver.browser.provider.parser.errorlog.listener.ErrorLogRecordListener;
 import org.apache.skywalking.oap.server.receiver.browser.provider.parser.errorlog.listener.MultiScopesErrorLogAnalysisListener;
 import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.PerfDataParserListenerManager;
-import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.listener.MultiScopesPerfDataAnalysisListener;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserPerfDataDecorator;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserResourcePerfDataDecorator;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserWebVitalsPerfDataDecorator;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.listener.BrowserPerfDataAnalysisListener;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.listener.BrowserWebResourcePerfDataAnalysisListener;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.listener.BrowserWebVitalsPerfDataAnalysisListener;
 import org.apache.skywalking.oap.server.receiver.sharing.server.SharingServerModule;
 import org.apache.skywalking.oap.server.telemetry.TelemetryModule;
 
@@ -117,9 +122,10 @@ public class BrowserModuleProvider extends ModuleProvider {
     }
 
     private PerfDataParserListenerManager perfDataListenerManager() {
-        PerfDataParserListenerManager listenerManager = new PerfDataParserListenerManager();
-        listenerManager.add(new MultiScopesPerfDataAnalysisListener.Factory(getManager(), moduleConfig));
-
+        PerfDataParserListenerManager listenerManager = new PerfDataParserListenerManager(getManager(), moduleConfig);
+        listenerManager.add(BrowserPerfDataDecorator.class, new BrowserPerfDataAnalysisListener.Factory(getManager(), moduleConfig));
+        listenerManager.add(BrowserWebVitalsPerfDataDecorator.class, new BrowserWebVitalsPerfDataAnalysisListener.Factory(getManager(), moduleConfig));
+        listenerManager.add(BrowserResourcePerfDataDecorator.class, new BrowserWebResourcePerfDataAnalysisListener.Factory(getManager(), moduleConfig));
         return listenerManager;
     }
 
diff --git a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/handler/grpc/BrowserPerfServiceHandler.java b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/handler/grpc/BrowserPerfServiceHandler.java
index 61f55f848b..f9fe795a17 100644
--- a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/handler/grpc/BrowserPerfServiceHandler.java
+++ b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/handler/grpc/BrowserPerfServiceHandler.java
@@ -23,13 +23,18 @@ import org.apache.skywalking.apm.network.common.v3.Commands;
 import org.apache.skywalking.apm.network.language.agent.v3.BrowserErrorLog;
 import org.apache.skywalking.apm.network.language.agent.v3.BrowserPerfData;
 import org.apache.skywalking.apm.network.language.agent.v3.BrowserPerfServiceGrpc;
+import org.apache.skywalking.apm.network.language.agent.v3.BrowserResourcePerfData;
+import org.apache.skywalking.apm.network.language.agent.v3.BrowserWebVitalsPerfData;
 import org.apache.skywalking.oap.server.library.module.ModuleManager;
 import org.apache.skywalking.oap.server.library.server.grpc.GRPCHandler;
 import org.apache.skywalking.oap.server.receiver.browser.provider.BrowserServiceModuleConfig;
 import org.apache.skywalking.oap.server.receiver.browser.provider.parser.errorlog.ErrorLogAnalyzer;
 import org.apache.skywalking.oap.server.receiver.browser.provider.parser.errorlog.ErrorLogParserListenerManager;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserPerfDataDecorator;
 import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.PerfDataAnalyzer;
 import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.PerfDataParserListenerManager;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserResourcePerfDataDecorator;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserWebVitalsPerfDataDecorator;
 import org.apache.skywalking.oap.server.telemetry.TelemetryModule;
 import org.apache.skywalking.oap.server.telemetry.api.CounterMetrics;
 import org.apache.skywalking.oap.server.telemetry.api.HistogramMetrics;
@@ -95,8 +100,46 @@ public class BrowserPerfServiceHandler extends BrowserPerfServiceGrpc.BrowserPer
         }
         HistogramMetrics.Timer timer = perfHistogram.createTimer();
         try {
-            PerfDataAnalyzer analyzer = new PerfDataAnalyzer(moduleManager, perfDataListenerManager, config);
-            analyzer.doAnalysis(request);
+            PerfDataAnalyzer analyzer = new PerfDataAnalyzer(perfDataListenerManager);
+            analyzer.doAnalysis(new BrowserPerfDataDecorator(request));
+        } catch (Throwable e) {
+            log.error(e.getMessage(), e);
+            perfErrorCounter.inc();
+        } finally {
+            timer.finish();
+            responseObserver.onNext(Commands.newBuilder().build());
+            responseObserver.onCompleted();
+        }
+    }
+
+    @Override
+    public void collectResourcePerfData(BrowserResourcePerfData request, StreamObserver<Commands> responseObserver) {
+        if (log.isDebugEnabled()) {
+            log.debug("receive browser resource performance data");
+        }
+        HistogramMetrics.Timer timer = perfHistogram.createTimer();
+        try {
+            PerfDataAnalyzer analyzer = new PerfDataAnalyzer(perfDataListenerManager);
+            analyzer.doAnalysis(new BrowserResourcePerfDataDecorator(request));
+        } catch (Throwable e) {
+            log.error(e.getMessage(), e);
+            perfErrorCounter.inc();
+        } finally {
+            timer.finish();
+            responseObserver.onNext(Commands.newBuilder().build());
+            responseObserver.onCompleted();
+        }
+    }
+
+    @Override
+    public void collectWebVitalsPerfData(BrowserWebVitalsPerfData request, StreamObserver<Commands> responseObserver) {
+        if (log.isDebugEnabled()) {
+            log.debug("receive browser web vitals performance data");
+        }
+        HistogramMetrics.Timer timer = perfHistogram.createTimer();
+        try {
+            PerfDataAnalyzer analyzer = new PerfDataAnalyzer(perfDataListenerManager);
+            analyzer.doAnalysis(new BrowserWebVitalsPerfDataDecorator(request));
         } catch (Throwable e) {
             log.error(e.getMessage(), e);
             perfErrorCounter.inc();
diff --git a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/handler/rest/BrowserPerfServiceHTTPHandler.java b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/handler/rest/BrowserPerfServiceHTTPHandler.java
index cd55a9adaa..203ba75ee8 100644
--- a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/handler/rest/BrowserPerfServiceHTTPHandler.java
+++ b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/handler/rest/BrowserPerfServiceHTTPHandler.java
@@ -23,12 +23,17 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.skywalking.apm.network.common.v3.Commands;
 import org.apache.skywalking.apm.network.language.agent.v3.BrowserErrorLog;
 import org.apache.skywalking.apm.network.language.agent.v3.BrowserPerfData;
+import org.apache.skywalking.apm.network.language.agent.v3.BrowserResourcePerfData;
+import org.apache.skywalking.apm.network.language.agent.v3.BrowserWebVitalsPerfData;
 import org.apache.skywalking.oap.server.library.module.ModuleManager;
 import org.apache.skywalking.oap.server.receiver.browser.provider.BrowserServiceModuleConfig;
 import org.apache.skywalking.oap.server.receiver.browser.provider.parser.errorlog.ErrorLogAnalyzer;
 import org.apache.skywalking.oap.server.receiver.browser.provider.parser.errorlog.ErrorLogParserListenerManager;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserPerfDataDecorator;
 import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.PerfDataAnalyzer;
 import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.PerfDataParserListenerManager;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserResourcePerfDataDecorator;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserWebVitalsPerfDataDecorator;
 import org.apache.skywalking.oap.server.telemetry.TelemetryModule;
 import org.apache.skywalking.oap.server.telemetry.api.CounterMetrics;
 import org.apache.skywalking.oap.server.telemetry.api.HistogramMetrics;
@@ -116,8 +121,37 @@ public class BrowserPerfServiceHTTPHandler {
     @Post("/browser/perfData")
     public Commands collectPerfData(final BrowserPerfData browserPerfData) {
         try (HistogramMetrics.Timer ignored = perfHistogram.createTimer()) {
-            final PerfDataAnalyzer analyzer = new PerfDataAnalyzer(moduleManager, perfDataListenerManager, config);
-            analyzer.doAnalysis(browserPerfData);
+            final PerfDataAnalyzer analyzer = new PerfDataAnalyzer(perfDataListenerManager);
+            analyzer.doAnalysis(new BrowserPerfDataDecorator(browserPerfData));
+            return Commands.newBuilder().build();
+        } catch (Throwable e) {
+            log.error(e.getMessage(), e);
+            perfErrorCounter.inc();
+            throw e;
+        }
+    }
+
+    @Post("/browser/perfData/webVitals")
+    public Commands collectWebVitalsPerfData(final BrowserWebVitalsPerfData browserPerfData) {
+        try (HistogramMetrics.Timer ignored = perfHistogram.createTimer()) {
+            final PerfDataAnalyzer analyzer = new PerfDataAnalyzer(perfDataListenerManager);
+            analyzer.doAnalysis(new BrowserWebVitalsPerfDataDecorator(browserPerfData));
+            return Commands.newBuilder().build();
+        } catch (Throwable e) {
+            log.error(e.getMessage(), e);
+            perfErrorCounter.inc();
+            throw e;
+        }
+    }
+
+    @Post("/browser/perfData/resources")
+    public Commands collectResourcesPerfData(final List<BrowserResourcePerfData> resourceList) {
+        try (HistogramMetrics.Timer ignored = perfHistogram.createTimer()) {
+            resourceList.stream().filter(resource -> resource.getDuration() > 0 && resource.getSize() > 0)
+                .forEach(resource -> {
+                    final PerfDataAnalyzer analyzer = new PerfDataAnalyzer(perfDataListenerManager);
+                    analyzer.doAnalysis(new BrowserResourcePerfDataDecorator(resource));
+                });
             return Commands.newBuilder().build();
         } catch (Throwable e) {
             log.error(e.getMessage(), e);
diff --git a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/PerfDataAnalyzer.java b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/PerfDataAnalyzer.java
index f39a948025..4926638996 100644
--- a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/PerfDataAnalyzer.java
+++ b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/PerfDataAnalyzer.java
@@ -17,33 +17,25 @@
 
 package org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance;
 
-import java.util.LinkedList;
-import java.util.List;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.skywalking.apm.network.language.agent.v3.BrowserPerfData;
-import org.apache.skywalking.oap.server.library.module.ModuleManager;
 import org.apache.skywalking.oap.server.library.util.StringUtil;
-import org.apache.skywalking.oap.server.receiver.browser.provider.BrowserServiceModuleConfig;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserPerfDecorator;
 import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.listener.PerfDataAnalysisListener;
 
 @Slf4j
 @RequiredArgsConstructor
 public class PerfDataAnalyzer {
-    private final ModuleManager moduleManager;
-    private final PerfDataParserListenerManager listenerManager;
-    private final BrowserServiceModuleConfig config;
+    private final PerfDataParserListenerManager factory;
 
-    private final List<PerfDataAnalysisListener> analysisListeners = new LinkedList<>();
-
-    public void doAnalysis(BrowserPerfData browserPerfData) {
-        if (StringUtil.isBlank(browserPerfData.getService())) {
+    @SuppressWarnings("unchecked")
+    public <T extends BrowserPerfDecorator> void doAnalysis(T decorator) {
+        if (StringUtil.isBlank(decorator.getService())) {
             return;
         }
 
-        createAnalysisListeners();
+        final PerfDataAnalysisListener<T> listener = (PerfDataAnalysisListener<T>) factory.create(decorator.getClass());
 
-        BrowserPerfDataDecorator decorator = new BrowserPerfDataDecorator(browserPerfData);
         // Use the server side current time.
         long nowMillis = System.currentTimeMillis();
         decorator.setTime(nowMillis);
@@ -56,21 +48,8 @@ public class PerfDataAnalyzer {
             decorator.setPagePath("/");
         }
 
-        notifyListener(decorator);
-
-        notifyListenerToBuild();
-    }
-
-    private void notifyListener(BrowserPerfDataDecorator decorator) {
-        analysisListeners.forEach(listener -> listener.parse(decorator));
+        listener.parse(decorator);
+        listener.build();
     }
 
-    private void notifyListenerToBuild() {
-        analysisListeners.forEach(PerfDataAnalysisListener::build);
-    }
-
-    private void createAnalysisListeners() {
-        listenerManager.getPerfDataListenerFactories()
-                       .forEach(factory -> analysisListeners.add(factory.create(moduleManager, config)));
-    }
 }
diff --git a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/PerfDataParserListenerManager.java b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/PerfDataParserListenerManager.java
index 46b8ae7182..e8d714e698 100644
--- a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/PerfDataParserListenerManager.java
+++ b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/PerfDataParserListenerManager.java
@@ -6,27 +6,45 @@
  * (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
+ *     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.
+ *
  */
 
 package org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance;
 
-import java.util.ArrayList;
-import java.util.List;
-import lombok.Getter;
+import org.apache.skywalking.oap.server.library.module.ModuleManager;
+import org.apache.skywalking.oap.server.receiver.browser.provider.BrowserServiceModuleConfig;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserPerfDecorator;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.listener.PerfDataAnalysisListener;
 import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.listener.PerfDataListenerFactory;
 
+import java.util.HashMap;
+import java.util.Map;
+
 public class PerfDataParserListenerManager {
-    @Getter
-    private final List<PerfDataListenerFactory> perfDataListenerFactories = new ArrayList<>();
 
-    public void add(final PerfDataListenerFactory factory) {
-        perfDataListenerFactories.add(factory);
+    private final Map<Class<?>, PerfDataListenerFactory> factories = new HashMap<>();
+
+    private final ModuleManager moduleManager;
+    private final BrowserServiceModuleConfig config;
+
+    public PerfDataParserListenerManager(ModuleManager moduleManager, BrowserServiceModuleConfig config) {
+        this.moduleManager = moduleManager;
+        this.config = config;
+    }
+
+    public <T extends BrowserPerfDecorator> void add(Class<T> decoratorClass, PerfDataListenerFactory<T> factory) {
+        factories.put(decoratorClass, factory);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T extends BrowserPerfDecorator> PerfDataAnalysisListener<T> create(Class<T> decorator) {
+        return factories.get(decorator).create(moduleManager, config);
     }
 }
diff --git a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/BrowserPerfDataDecorator.java b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/decorators/BrowserPerfDataDecorator.java
similarity index 96%
copy from oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/BrowserPerfDataDecorator.java
copy to oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/decorators/BrowserPerfDataDecorator.java
index 119c6f3229..14f3c1697a 100644
--- a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/BrowserPerfDataDecorator.java
+++ b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/decorators/BrowserPerfDataDecorator.java
@@ -15,11 +15,11 @@
  * limitations under the License.
  */
 
-package org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance;
+package org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators;
 
 import org.apache.skywalking.apm.network.language.agent.v3.BrowserPerfData;
 
-public class BrowserPerfDataDecorator {
+public class BrowserPerfDataDecorator implements BrowserPerfDecorator {
     private BrowserPerfData.Builder builder;
 
     public BrowserPerfDataDecorator(final BrowserPerfData browserPerfData) {
diff --git a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/PerfDataParserListenerManager.java b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/decorators/BrowserPerfDecorator.java
similarity index 60%
copy from oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/PerfDataParserListenerManager.java
copy to oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/decorators/BrowserPerfDecorator.java
index 46b8ae7182..62f5dc4e4a 100644
--- a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/PerfDataParserListenerManager.java
+++ b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/decorators/BrowserPerfDecorator.java
@@ -6,27 +6,28 @@
  * (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
+ *     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.
+ *
  */
 
-package org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance;
+package org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators;
+
+public interface BrowserPerfDecorator {
+    String getService();
+
+    void setTime(long time);
+
+    String getServiceVersion();
 
-import java.util.ArrayList;
-import java.util.List;
-import lombok.Getter;
-import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.listener.PerfDataListenerFactory;
+    void setServiceVersion(String serviceVersion);
 
-public class PerfDataParserListenerManager {
-    @Getter
-    private final List<PerfDataListenerFactory> perfDataListenerFactories = new ArrayList<>();
+    String getPagePath();
 
-    public void add(final PerfDataListenerFactory factory) {
-        perfDataListenerFactories.add(factory);
-    }
+    void setPagePath(String pagePath);
 }
diff --git a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/decorators/BrowserResourcePerfDataDecorator.java b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/decorators/BrowserResourcePerfDataDecorator.java
new file mode 100644
index 0000000000..516345d728
--- /dev/null
+++ b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/decorators/BrowserResourcePerfDataDecorator.java
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators;
+
+import org.apache.skywalking.apm.network.language.agent.v3.BrowserResourcePerfData;
+
+public class BrowserResourcePerfDataDecorator implements BrowserPerfDecorator {
+    private final BrowserResourcePerfData.Builder builder;
+
+    public BrowserResourcePerfDataDecorator(BrowserResourcePerfData builder) {
+        this.builder = builder.toBuilder();
+    }
+
+    @Override
+    public String getService() {
+        return builder.getService();
+    }
+
+    @Override
+    public void setTime(long time) {
+        builder.setTime(time);
+    }
+
+    @Override
+    public String getServiceVersion() {
+        return builder.getServiceVersion();
+    }
+
+    @Override
+    public void setServiceVersion(String serviceVersion) {
+        builder.setServiceVersion(serviceVersion);
+    }
+
+    @Override
+    public String getPagePath() {
+        return builder.getPagePath();
+    }
+
+    @Override
+    public void setPagePath(String pagePath) {
+        builder.setPagePath(pagePath);
+    }
+
+    public String getName() {
+        return builder.getName();
+    }
+
+    public int getDuration() {
+        return builder.getDuration();
+    }
+
+    public int getSize() {
+        return builder.getSize();
+    }
+
+    public String getProtocol() {
+        return builder.getProtocol();
+    }
+
+    public String getType() {
+        return builder.getResourceType();
+    }
+
+    public long getTime() {
+        return builder.getTime();
+    }
+}
diff --git a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/BrowserPerfDataDecorator.java b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/decorators/BrowserWebVitalsPerfDataDecorator.java
similarity index 51%
rename from oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/BrowserPerfDataDecorator.java
rename to oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/decorators/BrowserWebVitalsPerfDataDecorator.java
index 119c6f3229..7d4ede1f23 100644
--- a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/BrowserPerfDataDecorator.java
+++ b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/decorators/BrowserWebVitalsPerfDataDecorator.java
@@ -6,107 +6,70 @@
  * (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
+ *     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.
+ *
  */
 
-package org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance;
+package org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators;
 
-import org.apache.skywalking.apm.network.language.agent.v3.BrowserPerfData;
+import org.apache.skywalking.apm.network.language.agent.v3.BrowserWebVitalsPerfData;
 
-public class BrowserPerfDataDecorator {
-    private BrowserPerfData.Builder builder;
+public class BrowserWebVitalsPerfDataDecorator implements BrowserPerfDecorator {
+    private BrowserWebVitalsPerfData.Builder builder;
 
-    public BrowserPerfDataDecorator(final BrowserPerfData browserPerfData) {
-        this.builder = browserPerfData.toBuilder();
+    public BrowserWebVitalsPerfDataDecorator(BrowserWebVitalsPerfData builder) {
+        this.builder = builder.toBuilder();
     }
 
+    @Override
     public String getService() {
         return builder.getService();
     }
 
+    @Override
+    public void setTime(long time) {
+        builder.setTime(time);
+    }
+
+    @Override
     public String getServiceVersion() {
         return builder.getServiceVersion();
     }
 
-    public long getTime() {
-        return builder.getTime();
+    @Override
+    public void setServiceVersion(String serviceVersion) {
+        builder.setServiceVersion(serviceVersion);
     }
 
+    @Override
     public String getPagePath() {
         return builder.getPagePath();
     }
 
-    public int getRedirectTime() {
-        return builder.getRedirectTime();
-    }
-
-    public int getDnsTime() {
-        return builder.getDnsTime();
-    }
-
-    public int getTtfbTime() {
-        return builder.getTtfbTime();
-    }
-
-    public int getTcpTime() {
-        return builder.getTcpTime();
-    }
-
-    public int getTransTime() {
-        return builder.getTransTime();
-    }
-
-    public int getDomAnalysisTime() {
-        return builder.getDomAnalysisTime();
-    }
-
-    public int getFptTime() {
-        return builder.getFptTime();
-    }
-
-    public int getDomReadyTime() {
-        return builder.getDomReadyTime();
-    }
-
-    public int getLoadPageTime() {
-        return builder.getLoadPageTime();
-    }
-
-    public int getResTime() {
-        return builder.getResTime();
-    }
-
-    public int getSslTime() {
-        return builder.getSslTime();
-    }
-
-    public int getTtlTime() {
-        return builder.getTtlTime();
+    @Override
+    public void setPagePath(String pagePath) {
+        builder.setPagePath(pagePath);
     }
 
-    public int getFirstPackTime() {
-        return builder.getFirstPackTime();
+    public long getTime() {
+        return builder.getTime();
     }
 
     public int getFmpTime() {
         return builder.getFmpTime();
     }
 
-    public void setTime(long time) {
-        builder.setTime(time);
+    public int getLcpTime() {
+        return builder.getLcpTime();
     }
 
-    public void setServiceVersion(String version) {
-        builder.setServiceVersion(version);
-    }
-
-    public void setPagePath(String pagePath) {
-        builder.setPagePath(pagePath);
+    public int getClsTime() {
+        return builder.getClsTime();
     }
 }
diff --git a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/MultiScopesPerfDataAnalysisListener.java b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/BrowserPerfDataAnalysisListener.java
similarity index 86%
rename from oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/MultiScopesPerfDataAnalysisListener.java
rename to oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/BrowserPerfDataAnalysisListener.java
index 4aed69033c..60695237c9 100644
--- a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/MultiScopesPerfDataAnalysisListener.java
+++ b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/BrowserPerfDataAnalysisListener.java
@@ -24,21 +24,21 @@ import org.apache.skywalking.oap.server.core.config.NamingControl;
 import org.apache.skywalking.oap.server.core.source.SourceReceiver;
 import org.apache.skywalking.oap.server.library.module.ModuleManager;
 import org.apache.skywalking.oap.server.receiver.browser.provider.BrowserServiceModuleConfig;
-import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.BrowserPerfDataDecorator;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserPerfDataDecorator;
 
 /**
  * Browser traffic and page Performance related metrics.
  */
 @Slf4j
-public class MultiScopesPerfDataAnalysisListener implements PerfDataAnalysisListener {
+public class BrowserPerfDataAnalysisListener implements PerfDataAnalysisListener<BrowserPerfDataDecorator> {
     private final SourceReceiver sourceReceiver;
 
-    private final SourceBuilder sourceBuilder;
+    private final BrowserPerfDataSourceBuilder sourceBuilder;
 
-    public MultiScopesPerfDataAnalysisListener(final SourceReceiver sourceReceiver,
-                                               final NamingControl namingControl) {
+    public BrowserPerfDataAnalysisListener(final SourceReceiver sourceReceiver,
+                                           final NamingControl namingControl) {
         this.sourceReceiver = sourceReceiver;
-        this.sourceBuilder = new SourceBuilder(namingControl);
+        this.sourceBuilder = new BrowserPerfDataSourceBuilder(namingControl);
     }
 
     /**
@@ -85,7 +85,7 @@ public class MultiScopesPerfDataAnalysisListener implements PerfDataAnalysisList
         sourceBuilder.setFmpTime(decorator.getFmpTime());
     }
 
-    public static class Factory implements PerfDataListenerFactory {
+    public static class Factory implements PerfDataListenerFactory<BrowserPerfDataDecorator> {
 
         private final SourceReceiver sourceReceiver;
         private final NamingControl namingControl;
@@ -101,9 +101,9 @@ public class MultiScopesPerfDataAnalysisListener implements PerfDataAnalysisList
         }
 
         @Override
-        public PerfDataAnalysisListener create(final ModuleManager moduleManager,
+        public PerfDataAnalysisListener<BrowserPerfDataDecorator> create(final ModuleManager moduleManager,
                                                final BrowserServiceModuleConfig moduleConfig) {
-            return new MultiScopesPerfDataAnalysisListener(sourceReceiver, namingControl);
+            return new BrowserPerfDataAnalysisListener(sourceReceiver, namingControl);
         }
     }
 }
diff --git a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/SourceBuilder.java b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/BrowserPerfDataSourceBuilder.java
similarity index 99%
rename from oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/SourceBuilder.java
rename to oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/BrowserPerfDataSourceBuilder.java
index 7d50ea4561..b3a87d90e0 100644
--- a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/SourceBuilder.java
+++ b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/BrowserPerfDataSourceBuilder.java
@@ -36,7 +36,7 @@ import org.apache.skywalking.oap.server.core.source.Source;
  * Browser traffic and performance related source.
  */
 @RequiredArgsConstructor
-class SourceBuilder {
+class BrowserPerfDataSourceBuilder {
     private final NamingControl namingControl;
 
     @Getter
diff --git a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/BrowserWebResourcePerfDataAnalysisListener.java b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/BrowserWebResourcePerfDataAnalysisListener.java
new file mode 100644
index 0000000000..c8195df136
--- /dev/null
+++ b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/BrowserWebResourcePerfDataAnalysisListener.java
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.listener;
+
+import org.apache.skywalking.oap.server.core.CoreModule;
+import org.apache.skywalking.oap.server.core.analysis.TimeBucket;
+import org.apache.skywalking.oap.server.core.browser.source.BrowserAppResourcePerf;
+import org.apache.skywalking.oap.server.core.config.NamingControl;
+import org.apache.skywalking.oap.server.core.source.SourceReceiver;
+import org.apache.skywalking.oap.server.library.module.ModuleManager;
+import org.apache.skywalking.oap.server.receiver.browser.provider.BrowserServiceModuleConfig;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserResourcePerfDataDecorator;
+
+public class BrowserWebResourcePerfDataAnalysisListener implements PerfDataAnalysisListener<BrowserResourcePerfDataDecorator>  {
+    private final SourceReceiver sourceReceiver;
+    private final NamingControl namingControl;
+    private BrowserAppResourcePerf browserAppResourcePerf;
+
+    public BrowserWebResourcePerfDataAnalysisListener(SourceReceiver sourceReceiver, NamingControl namingControl) {
+        this.sourceReceiver = sourceReceiver;
+        this.namingControl = namingControl;
+    }
+
+    @Override
+    public void build() {
+        sourceReceiver.receive(browserAppResourcePerf);
+    }
+
+    @Override
+    public void parse(BrowserResourcePerfDataDecorator decorator) {
+        browserAppResourcePerf = new BrowserAppResourcePerf();
+        browserAppResourcePerf.setTimeBucket(TimeBucket.getMinuteTimeBucket(decorator.getTime()));
+        browserAppResourcePerf.setServiceName(namingControl.formatServiceName(decorator.getService()));
+        browserAppResourcePerf.setPath(namingControl.formatEndpointName(browserAppResourcePerf.getServiceName(), decorator.getPagePath()));
+        browserAppResourcePerf.setName(decorator.getName());
+        browserAppResourcePerf.setDuration(decorator.getDuration());
+        browserAppResourcePerf.setSize(decorator.getSize());
+        browserAppResourcePerf.setProtocol(decorator.getProtocol());
+        browserAppResourcePerf.setType(decorator.getType());
+    }
+
+    public static class Factory implements PerfDataListenerFactory<BrowserResourcePerfDataDecorator> {
+
+        private final SourceReceiver sourceReceiver;
+        private final NamingControl namingControl;
+
+        public Factory(ModuleManager moduleManager, BrowserServiceModuleConfig moduleConfig) {
+            this.sourceReceiver = moduleManager.find(CoreModule.NAME)
+                .provider()
+                .getService(SourceReceiver.class);
+
+            this.namingControl = moduleManager.find(CoreModule.NAME)
+                .provider()
+                .getService(NamingControl.class);
+        }
+
+        @Override
+        public PerfDataAnalysisListener<BrowserResourcePerfDataDecorator> create(ModuleManager moduleManager, BrowserServiceModuleConfig moduleConfig) {
+            return new BrowserWebResourcePerfDataAnalysisListener(sourceReceiver, namingControl);
+        }
+    }
+}
diff --git a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/BrowserWebVitalsPerfDataAnalysisListener.java b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/BrowserWebVitalsPerfDataAnalysisListener.java
new file mode 100644
index 0000000000..db7c6cd19a
--- /dev/null
+++ b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/BrowserWebVitalsPerfDataAnalysisListener.java
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.listener;
+
+import org.apache.skywalking.oap.server.core.CoreModule;
+import org.apache.skywalking.oap.server.core.analysis.TimeBucket;
+import org.apache.skywalking.oap.server.core.browser.source.BrowserAppWebVitalsPerf;
+import org.apache.skywalking.oap.server.core.config.NamingControl;
+import org.apache.skywalking.oap.server.core.source.SourceReceiver;
+import org.apache.skywalking.oap.server.library.module.ModuleManager;
+import org.apache.skywalking.oap.server.receiver.browser.provider.BrowserServiceModuleConfig;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserWebVitalsPerfDataDecorator;
+
+public class BrowserWebVitalsPerfDataAnalysisListener implements PerfDataAnalysisListener<BrowserWebVitalsPerfDataDecorator> {
+    private final SourceReceiver sourceReceiver;
+    private final NamingControl namingControl;
+    private BrowserAppWebVitalsPerf browserAppWebVitalsPerf;
+
+    public BrowserWebVitalsPerfDataAnalysisListener(SourceReceiver sourceReceiver, NamingControl namingControl) {
+        this.sourceReceiver = sourceReceiver;
+        this.namingControl = namingControl;
+    }
+
+    @Override
+    public void build() {
+        sourceReceiver.receive(browserAppWebVitalsPerf);
+    }
+
+    @Override
+    public void parse(BrowserWebVitalsPerfDataDecorator decorator) {
+        browserAppWebVitalsPerf = new BrowserAppWebVitalsPerf();
+        browserAppWebVitalsPerf.setTimeBucket(TimeBucket.getMinuteTimeBucket(decorator.getTime()));
+        browserAppWebVitalsPerf.setServiceName(namingControl.formatServiceName(decorator.getService()));
+        browserAppWebVitalsPerf.setPath(namingControl.formatEndpointName(browserAppWebVitalsPerf.getServiceName(), decorator.getPagePath()));
+        browserAppWebVitalsPerf.setFmpTime(decorator.getFmpTime());
+        browserAppWebVitalsPerf.setClsTime(decorator.getClsTime());
+        browserAppWebVitalsPerf.setLcpTime(decorator.getLcpTime());
+    }
+
+    public static class Factory implements PerfDataListenerFactory<BrowserWebVitalsPerfDataDecorator> {
+
+        private final SourceReceiver sourceReceiver;
+        private final NamingControl namingControl;
+
+        public Factory(ModuleManager moduleManager, BrowserServiceModuleConfig moduleConfig) {
+            this.sourceReceiver = moduleManager.find(CoreModule.NAME)
+                .provider()
+                .getService(SourceReceiver.class);
+
+            this.namingControl = moduleManager.find(CoreModule.NAME)
+                .provider()
+                .getService(NamingControl.class);
+        }
+
+        @Override
+        public PerfDataAnalysisListener<BrowserWebVitalsPerfDataDecorator> create(ModuleManager moduleManager, BrowserServiceModuleConfig moduleConfig) {
+            return new BrowserWebVitalsPerfDataAnalysisListener(sourceReceiver, namingControl);
+        }
+    }
+}
diff --git a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/PerfDataAnalysisListener.java b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/PerfDataAnalysisListener.java
index b5a45742e5..f9c95809e4 100644
--- a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/PerfDataAnalysisListener.java
+++ b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/PerfDataAnalysisListener.java
@@ -17,12 +17,12 @@
 
 package org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.listener;
 
-import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.BrowserPerfDataDecorator;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserPerfDecorator;
 
 /**
  * BrowserPerfDataListener represents the callback when OAP does the browser performance data analysis.
  */
-public interface PerfDataAnalysisListener {
+public interface PerfDataAnalysisListener<T extends BrowserPerfDecorator> {
     /**
      * The last step of the analysis process. Typically, the implementations forward the analysis results to the source
      * receiver.
@@ -32,5 +32,5 @@ public interface PerfDataAnalysisListener {
     /**
      * Parse the raw data from the probe (js-client).
      */
-    void parse(BrowserPerfDataDecorator decorator);
+    void parse(T decorator);
 }
diff --git a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/PerfDataListenerFactory.java b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/PerfDataListenerFactory.java
index 24cd4e2f84..1de787dd19 100644
--- a/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/PerfDataListenerFactory.java
+++ b/oap-server/server-receiver-plugin/skywalking-browser-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/browser/provider/parser/performance/listener/PerfDataListenerFactory.java
@@ -19,11 +19,12 @@ package org.apache.skywalking.oap.server.receiver.browser.provider.parser.perfor
 
 import org.apache.skywalking.oap.server.library.module.ModuleManager;
 import org.apache.skywalking.oap.server.receiver.browser.provider.BrowserServiceModuleConfig;
+import org.apache.skywalking.oap.server.receiver.browser.provider.parser.performance.decorators.BrowserPerfDecorator;
 
 /**
  * BrowserPerfDataListenerFactory implementation creates the listener instances when required. Every
  * BrowserPerfDataListener could have its own creation factory.
  */
-public interface PerfDataListenerFactory {
-    PerfDataAnalysisListener create(ModuleManager moduleManager, BrowserServiceModuleConfig moduleConfig);
+public interface PerfDataListenerFactory<T extends BrowserPerfDecorator> {
+    PerfDataAnalysisListener<T> create(ModuleManager moduleManager, BrowserServiceModuleConfig moduleConfig);
 }
diff --git a/oap-server/server-starter/src/main/resources/oal/browser.oal b/oap-server/server-starter/src/main/resources/oal/browser.oal
index 2f813ed996..5c60e5450e 100644
--- a/oap-server/server-starter/src/main/resources/oal/browser.oal
+++ b/oap-server/server-starter/src/main/resources/oal/browser.oal
@@ -58,6 +58,16 @@ browser_app_page_load_page_percentile = from(BrowserAppPagePerf.loadPageTime).pe
 browser_app_page_first_pack_percentile = from(BrowserAppPagePerf.firstPackTime).percentile2(10);
 browser_app_page_fmp_percentile = from(BrowserAppPagePerf.fmpTime).percentile2(10);
 
+// Since the web vitals and resource can be load from cache or cross-origin, so the metrics should ignore when the value is 0
+browser_app_resource_duration_avg = from(BrowserAppResourcePerf.*).filter(duration > 0).labelAvg(name, duration);
+browser_app_resource_size_avg = from(BrowserAppResourcePerf.*).filter(size > 0).labelAvg(name, size);
+browser_app_resource_protocol_count = from(BrowserAppResourcePerf.*).labelCount(protocol);
+browser_app_resource_type_count = from(BrowserAppResourcePerf.*).labelCount(type);
+
+browser_app_web_vitals_fmp_avg = from(BrowserAppWebVitalsPerf.fmpTime).filter(fmpTime > 0).longAvg();
+browser_app_web_vitals_cls_avg = from(BrowserAppWebVitalsPerf.clsTime).filter(clsTime > 0).longAvg();
+browser_app_web_vitals_lcp_avg = from(BrowserAppWebVitalsPerf.lcpTime).filter(lcpTime > 0).longAvg();
+
 // Disable unnecessary hard core stream, targeting @Stream#name
 /////////
 //disable(browser_error_log);
diff --git a/oap-server/server-starter/src/main/resources/ui-initialized-templates/browser/browser-page.json b/oap-server/server-starter/src/main/resources/ui-initialized-templates/browser/browser-page.json
index 875cbdaced..fad1fd7459 100644
--- a/oap-server/server-starter/src/main/resources/ui-initialized-templates/browser/browser-page.json
+++ b/oap-server/server-starter/src/main/resources/ui-initialized-templates/browser/browser-page.json
@@ -63,6 +63,27 @@
                     },
                     {
                       "widgetId": "12-0-10"
+                    },
+                    {
+                      "widgetId": "12-0-11"
+                    },
+                    {
+                      "widgetId": "12-0-12"
+                    },
+                    {
+                      "widgetId": "12-0-13"
+                    },
+                    {
+                      "widgetId": "12-0-14"
+                    },
+                    {
+                      "widgetId": "12-0-15"
+                    },
+                    {
+                      "widgetId": "12-0-16"
+                    },
+                    {
+                      "widgetId": "12-0-17"
                     }
                   ]
                 },
@@ -115,6 +136,27 @@
                     },
                     {
                       "widgetId": "12-0-10"
+                    },
+                    {
+                      "widgetId": "12-0-11"
+                    },
+                    {
+                      "widgetId": "12-0-12"
+                    },
+                    {
+                      "widgetId": "12-0-13"
+                    },
+                    {
+                      "widgetId": "12-0-14"
+                    },
+                    {
+                      "widgetId": "12-0-15"
+                    },
+                    {
+                      "widgetId": "12-0-16"
+                    },
+                    {
+                      "widgetId": "12-0-17"
                     }
                   ]
                 },
@@ -167,6 +209,27 @@
                     },
                     {
                       "widgetId": "12-0-10"
+                    },
+                    {
+                      "widgetId": "12-0-11"
+                    },
+                    {
+                      "widgetId": "12-0-12"
+                    },
+                    {
+                      "widgetId": "12-0-13"
+                    },
+                    {
+                      "widgetId": "12-0-14"
+                    },
+                    {
+                      "widgetId": "12-0-15"
+                    },
+                    {
+                      "widgetId": "12-0-16"
+                    },
+                    {
+                      "widgetId": "12-0-17"
                     }
                   ]
                 },
@@ -219,6 +282,27 @@
                     },
                     {
                       "widgetId": "12-0-10"
+                    },
+                    {
+                      "widgetId": "12-0-11"
+                    },
+                    {
+                      "widgetId": "12-0-12"
+                    },
+                    {
+                      "widgetId": "12-0-13"
+                    },
+                    {
+                      "widgetId": "12-0-14"
+                    },
+                    {
+                      "widgetId": "12-0-15"
+                    },
+                    {
+                      "widgetId": "12-0-16"
+                    },
+                    {
+                      "widgetId": "12-0-17"
                     }
                   ]
                 },
@@ -271,6 +355,27 @@
                     },
                     {
                       "widgetId": "12-0-10"
+                    },
+                    {
+                      "widgetId": "12-0-11"
+                    },
+                    {
+                      "widgetId": "12-0-12"
+                    },
+                    {
+                      "widgetId": "12-0-13"
+                    },
+                    {
+                      "widgetId": "12-0-14"
+                    },
+                    {
+                      "widgetId": "12-0-15"
+                    },
+                    {
+                      "widgetId": "12-0-16"
+                    },
+                    {
+                      "widgetId": "12-0-17"
                     }
                   ]
                 },
@@ -323,6 +428,27 @@
                     },
                     {
                       "widgetId": "12-0-10"
+                    },
+                    {
+                      "widgetId": "12-0-11"
+                    },
+                    {
+                      "widgetId": "12-0-12"
+                    },
+                    {
+                      "widgetId": "12-0-13"
+                    },
+                    {
+                      "widgetId": "12-0-14"
+                    },
+                    {
+                      "widgetId": "12-0-15"
+                    },
+                    {
+                      "widgetId": "12-0-16"
+                    },
+                    {
+                      "widgetId": "12-0-17"
                     }
                   ]
                 },
@@ -378,6 +504,27 @@
                     },
                     {
                       "widgetId": "12-0-10"
+                    },
+                    {
+                      "widgetId": "12-0-11"
+                    },
+                    {
+                      "widgetId": "12-0-12"
+                    },
+                    {
+                      "widgetId": "12-0-13"
+                    },
+                    {
+                      "widgetId": "12-0-14"
+                    },
+                    {
+                      "widgetId": "12-0-15"
+                    },
+                    {
+                      "widgetId": "12-0-16"
+                    },
+                    {
+                      "widgetId": "12-0-17"
                     }
                   ],
                   "metricConfig": [
@@ -455,6 +602,27 @@
                     },
                     {
                       "widgetId": "12-0-0"
+                    },
+                    {
+                      "widgetId": "12-0-11"
+                    },
+                    {
+                      "widgetId": "12-0-12"
+                    },
+                    {
+                      "widgetId": "12-0-13"
+                    },
+                    {
+                      "widgetId": "12-0-14"
+                    },
+                    {
+                      "widgetId": "12-0-15"
+                    },
+                    {
+                      "widgetId": "12-0-16"
+                    },
+                    {
+                      "widgetId": "12-0-17"
                     }
                   ],
                   "metricConfig": [
@@ -471,6 +639,468 @@
                       "label": "ajax_error_sum"
                     }
                   ]
+                },
+                {
+                  "x": 0,
+                  "y": 45,
+                  "w": 8,
+                  "h": 15,
+                  "i": "11",
+                  "type": "Widget",
+                  "expressions": [
+                    "browser_app_web_vitals_fmp_avg"
+                  ],
+                  "graph": {
+                    "type": "Line",
+                    "step": false,
+                    "smooth": false,
+                    "showSymbol": true,
+                    "showXAxis": true,
+                    "showYAxis": true
+                  },
+                  "widget": {
+                    "title": "Web Vitals First Meaningful Paint Latency(ms)"
+                  },
+                  "associate": [
+                    {
+                      "widgetId": "12-0-1"
+                    },
+                    {
+                      "widgetId": "12-0-2"
+                    },
+                    {
+                      "widgetId": "12-0-3"
+                    },
+                    {
+                      "widgetId": "12-0-4"
+                    },
+                    {
+                      "widgetId": "12-0-8"
+                    },
+                    {
+                      "widgetId": "12-0-0"
+                    },
+                    {
+                      "widgetId": "12-0-10"
+                    },
+                    {
+                      "widgetId": "12-0-11"
+                    },
+                    {
+                      "widgetId": "12-0-12"
+                    },
+                    {
+                      "widgetId": "12-0-13"
+                    },
+                    {
+                      "widgetId": "12-0-14"
+                    },
+                    {
+                      "widgetId": "12-0-15"
+                    },
+                    {
+                      "widgetId": "12-0-16"
+                    },
+                    {
+                      "widgetId": "12-0-17"
+                    }
+                  ]
+                },
+                {
+                  "x": 8,
+                  "y": 45,
+                  "w": 8,
+                  "h": 15,
+                  "i": "12",
+                  "type": "Widget",
+                  "expressions": [
+                    "browser_app_web_vitals_cls_avg"
+                  ],
+                  "graph": {
+                    "type": "Line",
+                    "step": false,
+                    "smooth": false,
+                    "showSymbol": true,
+                    "showXAxis": true,
+                    "showYAxis": true
+                  },
+                  "widget": {
+                    "title": "Web Vitals Cumulative Layout Shift Latency(ms)"
+                  },
+                  "associate": [
+                    {
+                      "widgetId": "12-0-1"
+                    },
+                    {
+                      "widgetId": "12-0-2"
+                    },
+                    {
+                      "widgetId": "12-0-3"
+                    },
+                    {
+                      "widgetId": "12-0-4"
+                    },
+                    {
+                      "widgetId": "12-0-8"
+                    },
+                    {
+                      "widgetId": "12-0-0"
+                    },
+                    {
+                      "widgetId": "12-0-10"
+                    },
+                    {
+                      "widgetId": "12-0-11"
+                    },
+                    {
+                      "widgetId": "12-0-12"
+                    },
+                    {
+                      "widgetId": "12-0-13"
+                    },
+                    {
+                      "widgetId": "12-0-14"
+                    },
+                    {
+                      "widgetId": "12-0-15"
+                    },
+                    {
+                      "widgetId": "12-0-16"
+                    },
+                    {
+                      "widgetId": "12-0-17"
+                    }
+                  ]
+                },
+                {
+                  "x": 16,
+                  "y": 45,
+                  "w": 8,
+                  "h": 15,
+                  "i": "13",
+                  "type": "Widget",
+                  "expressions": [
+                    "browser_app_web_vitals_lcp_avg"
+                  ],
+                  "graph": {
+                    "type": "Line",
+                    "step": false,
+                    "smooth": false,
+                    "showSymbol": true,
+                    "showXAxis": true,
+                    "showYAxis": true
+                  },
+                  "widget": {
+                    "title": "Web Vitals Largest Contentful Paint Latency(ms)"
+                  },
+                  "associate": [
+                    {
+                      "widgetId": "12-0-1"
+                    },
+                    {
+                      "widgetId": "12-0-2"
+                    },
+                    {
+                      "widgetId": "12-0-3"
+                    },
+                    {
+                      "widgetId": "12-0-4"
+                    },
+                    {
+                      "widgetId": "12-0-8"
+                    },
+                    {
+                      "widgetId": "12-0-0"
+                    },
+                    {
+                      "widgetId": "12-0-10"
+                    },
+                    {
+                      "widgetId": "12-0-11"
+                    },
+                    {
+                      "widgetId": "12-0-12"
+                    },
+                    {
+                      "widgetId": "12-0-13"
+                    },
+                    {
+                      "widgetId": "12-0-14"
+                    },
+                    {
+                      "widgetId": "12-0-15"
+                    },
+                    {
+                      "widgetId": "12-0-16"
+                    },
+                    {
+                      "widgetId": "12-0-17"
+                    }
+                  ]
+                },
+                {
+                  "x": 0,
+                  "y": 60,
+                  "w": 6,
+                  "h": 15,
+                  "i": "14",
+                  "type": "Widget",
+                  "expressions": [
+                    "browser_app_resource_duration_avg"
+                  ],
+                  "graph": {
+                    "type": "Line",
+                    "step": false,
+                    "smooth": false,
+                    "showSymbol": true,
+                    "showXAxis": true,
+                    "showYAxis": true
+                  },
+                  "widget": {
+                    "title": "Load Duration(ms)"
+                  },
+                  "associate": [
+                    {
+                      "widgetId": "12-0-1"
+                    },
+                    {
+                      "widgetId": "12-0-2"
+                    },
+                    {
+                      "widgetId": "12-0-3"
+                    },
+                    {
+                      "widgetId": "12-0-4"
+                    },
+                    {
+                      "widgetId": "12-0-8"
+                    },
+                    {
+                      "widgetId": "12-0-0"
+                    },
+                    {
+                      "widgetId": "12-0-10"
+                    },
+                    {
+                      "widgetId": "12-0-11"
+                    },
+                    {
+                      "widgetId": "12-0-12"
+                    },
+                    {
+                      "widgetId": "12-0-13"
+                    },
+                    {
+                      "widgetId": "12-0-14"
+                    },
+                    {
+                      "widgetId": "12-0-15"
+                    },
+                    {
+                      "widgetId": "12-0-16"
+                    },
+                    {
+                      "widgetId": "12-0-17"
+                    }
+                  ]
+                },
+                {
+                  "x": 6,
+                  "y": 60,
+                  "w": 6,
+                  "h": 15,
+                  "i": "15",
+                  "type": "Widget",
+                  "expressions": [
+                    "browser_app_resource_size_avg/1024"
+                  ],
+                  "graph": {
+                    "type": "Line",
+                    "step": false,
+                    "smooth": false,
+                    "showSymbol": true,
+                    "showXAxis": true,
+                    "showYAxis": true
+                  },
+                  "widget": {
+                    "title": "Resource Size(KB)"
+                  },
+                  "associate": [
+                    {
+                      "widgetId": "12-0-1"
+                    },
+                    {
+                      "widgetId": "12-0-2"
+                    },
+                    {
+                      "widgetId": "12-0-3"
+                    },
+                    {
+                      "widgetId": "12-0-4"
+                    },
+                    {
+                      "widgetId": "12-0-8"
+                    },
+                    {
+                      "widgetId": "12-0-0"
+                    },
+                    {
+                      "widgetId": "12-0-10"
+                    },
+                    {
+                      "widgetId": "12-0-11"
+                    },
+                    {
+                      "widgetId": "12-0-12"
+                    },
+                    {
+                      "widgetId": "12-0-13"
+                    },
+                    {
+                      "widgetId": "12-0-14"
+                    },
+                    {
+                      "widgetId": "12-0-15"
+                    },
+                    {
+                      "widgetId": "12-0-16"
+                    },
+                    {
+                      "widgetId": "12-0-17"
+                    }
+                  ]
+                },
+                {
+                  "x": 18,
+                  "y": 60,
+                  "w": 6,
+                  "h": 15,
+                  "i": "16",
+                  "type": "Widget",
+                  "expressions": [
+                    "browser_app_resource_protocol_count"
+                  ],
+                  "graph": {
+                    "type": "Line",
+                    "step": false,
+                    "smooth": false,
+                    "showSymbol": true,
+                    "showXAxis": true,
+                    "showYAxis": true
+                  },
+                  "widget": {
+                    "title": "Resource Load Protocol Count Per Min"
+                  },
+                  "associate": [
+                    {
+                      "widgetId": "12-0-1"
+                    },
+                    {
+                      "widgetId": "12-0-2"
+                    },
+                    {
+                      "widgetId": "12-0-3"
+                    },
+                    {
+                      "widgetId": "12-0-4"
+                    },
+                    {
+                      "widgetId": "12-0-8"
+                    },
+                    {
+                      "widgetId": "12-0-0"
+                    },
+                    {
+                      "widgetId": "12-0-10"
+                    },
+                    {
+                      "widgetId": "12-0-11"
+                    },
+                    {
+                      "widgetId": "12-0-12"
+                    },
+                    {
+                      "widgetId": "12-0-13"
+                    },
+                    {
+                      "widgetId": "12-0-14"
+                    },
+                    {
+                      "widgetId": "12-0-15"
+                    },
+                    {
+                      "widgetId": "12-0-16"
+                    },
+                    {
+                      "widgetId": "12-0-17"
+                    }
+                  ]
+                },
+                {
+                  "x": 12,
+                  "y": 60,
+                  "w": 6,
+                  "h": 15,
+                  "i": "17",
+                  "type": "Widget",
+                  "expressions": [
+                    "browser_app_resource_type_count"
+                  ],
+                  "graph": {
+                    "type": "Line",
+                    "step": false,
+                    "smooth": false,
+                    "showSymbol": true,
+                    "showXAxis": true,
+                    "showYAxis": true
+                  },
+                  "widget": {
+                    "title": "Resource Type Load Count Per Min"
+                  },
+                  "associate": [
+                    {
+                      "widgetId": "12-0-1"
+                    },
+                    {
+                      "widgetId": "12-0-2"
+                    },
+                    {
+                      "widgetId": "12-0-3"
+                    },
+                    {
+                      "widgetId": "12-0-4"
+                    },
+                    {
+                      "widgetId": "12-0-8"
+                    },
+                    {
+                      "widgetId": "12-0-0"
+                    },
+                    {
+                      "widgetId": "12-0-10"
+                    },
+                    {
+                      "widgetId": "12-0-11"
+                    },
+                    {
+                      "widgetId": "12-0-12"
+                    },
+                    {
+                      "widgetId": "12-0-13"
+                    },
+                    {
+                      "widgetId": "12-0-14"
+                    },
+                    {
+                      "widgetId": "12-0-15"
+                    },
+                    {
+                      "widgetId": "12-0-16"
+                    },
+                    {
+                      "widgetId": "12-0-17"
+                    }
+                  ]
                 }
               ]
             },
@@ -515,7 +1145,6 @@
       "layer": "BROWSER",
       "entity": "Endpoint",
       "name": "Browser-Page",
-      "id": "Browser-Page",
       "isRoot": false
     }
   }