AMP Platform Dashboard — Performance Analysis

URL: https://platform.sb.amp.vg/#dashboard/partnersales  |  Date: March 1, 2026  |  Environment: Sandbox

1. Core Web Vitals Summary

Metric Measured Value Target Rating
LCP (Largest Contentful Paint) 7,222 ms < 2,500 ms POOR
CLS (Cumulative Layout Shift) 0.23 < 0.1 POOR
TTFB (Time to First Byte) 2,434 ms < 800 ms POOR

LCP Breakdown

The LCP element is the brand logo image (brand-logo-nice.png). The 7.2s LCP breaks down as:

PhaseDuration% of LCPNotes
Time to First Byte (TTFB)2,434 ms33.7%Server response is very slow
Resource Load Delay14 ms0.2%Acceptable
Resource Load Duration649 ms9.0%Image download
Element Render Delay4,124 ms57.1%JS execution blocks rendering

CLS Root Cause

The CLS score of 0.23 is caused by:

2. Request Waterfall Overview

The dashboard loads in a 4-level deep waterfall with a critical path of 7,074 ms. The architecture creates multiple sequential dependencies that prevent parallel loading:

Level 1: Document HTML (304 KB, 2,980 ms) Level 2: ├── newui.js (parse + execute) ├── Render-blocking CSS ×3 + twilio.js Level 3: │ ├── /dashboard/partnersales (SPA navigation) │ ├── GetProfileDetails → GetAssignedPersonaDetails (chained!) │ ├── GetNavigationTopBanner │ └── GetTotalUnreadNotificationsForUser Level 4: │ ├── 11 widget HTML requests (parallel) │ ├── bridge/ask/ai (885 KB!) │ ├── Widget template JS loads (per widget) │ └── Widget API data calls (per widget)
Key bottleneck: The chain Document → newui.js → GetProfileDetails → GetAssignedPersonaDetails → widgets is entirely sequential. Nothing on the dashboard can render until this 4-step chain completes (~5.3 seconds).

3. All Requests — Detailed Breakdown

Phase 1: Document Load (0 – 2,980 ms)

#RequestMethodSizeServer TimeIssues
1 / (HTML document) GET 304 KB 2,434 ms TTFB No gzip compression; ~200 KB of inline theme CSS; slow server response

Phase 2: Static Assets (2,448 ms – 2,982 ms)

#ResourceTypeRender-Blocking?CacheIssues
2default.cssCSSYesCloudflare, 4hr TTLShort cache for hashed URL
3newui.cssCSSYesCloudflare, 4hr TTLShort cache for hashed URL
4IBM Plex Sans (Google Fonts)CSSYesCached
5Roboto (Google Fonts)CSSYesCached
6Open Sans (Google Fonts)CSSYesCached
7twilio.jsJSYesCloudflare, 4hr TTLShould NOT be render-blocking
8jquery.libs.jsJSNoCloudflare, 4hr TTL
9newui.jsJSNoCloudflare, 4hr TTL
10jquery-ui.min.jsJSNoGoogle CDN
11echarts.min.jsJSNoCloudflare CDN
12echartsHelper.jsJSNoOrigin, 24hr TTL
13brand-logo-nice.png (LCP)IMGNoTTL: 0 (none)No cache; no fetchpriority="high"

Phase 3: SPA Navigation + Core APIs (3,444 ms – 4,409 ms)

These fire after newui.js parses and executes the SPA hash-router:

#API EndpointMethodResponse SizeServer TimeIssues
14 /dashboard/partnersales GET 83 KB ~3,400 ms wait Dashboard skeleton HTML with inline CSS/JS; no gzip
15 /api/GetProfileDetails POST 750 B ~850 ms Returns user profile, logo URLs, engagement level
16 /api/GetNavigationTopBanner POST 110 B ~600 ms Returns empty string — wasted call
17 /api/GetTotalUnreadNotificationsForUser POST 95 B ~700 ms 700 ms to return a single integer

Phase 4: Persona Chain — Critical Path Bottleneck (4,300 ms)

#API EndpointMethodResponse SizeServer TimeIssues
18 /api/GetAssignedPersonaDetails POST 250 B ~850 ms Depends on GetProfileDetails; blocks ALL widget loading
Critical path issue: GetAssignedPersonaDetails cannot start until GetProfileDetails completes. This sequential dependency adds ~1,700 ms to the critical path. Both calls return small JSON and could be merged into a single endpoint or parallelized.

Phase 5: Widget Requests — Parallel Burst (6,788 ms – 6,890 ms)

All fired in parallel after persona details resolve. Each returns server-rendered HTML with inline JS:

#Widget RequestSizeIssues
19/bridge/ask/ai (BridgeAI chatbot)885 KBMassive response; should be lazy-loaded on interaction
20/api/GetAnnocmentNotificationInfo190 BReturns "no announcement" — wasted call
21/widgets/userprofile/version/36 KBHTML + inline JS, triggers templateJS sub-request
22/widgets/organizationprofile/version/2~5 KBHTML + inline JS, triggers templateJS sub-request
23/widgets/yourchannelmanagers/version/3~4 KBHTML + inline JS, triggers templateJS sub-request
24/widgets/webbanner?version=5~3 KBBanner widget
25/widgets/custom/quickactionlink~4 KBQuick action links
26/widgets/webbanner?version=4~3 KBBanner widget
27/widgets/partnertiergoal/progress~5 KBTier goal progress chart
28/widgets/registereddealsdonut25 KBDeal donut chart + inline JS
29/widgets/dealtoopportunities/version/3~8 KBOpportunity list table
30/widgets/webbanner?version=3~3 KBBanner widget

Phase 6: Widget Sub-Requests (7,000 ms+)

After each widget HTML loads, it fires its own template JS fetch and then API data calls (3 round trips per widget):

#RequestTypeIssues
31widgets/userprofile/templatejsTemplate JSEach widget requires HTML → Template JS → API = 3 sequential round trips
32widgets/custom/quickactionlink/templatejsTemplate JS
33widgets/yourchannelmanagers/templatejsTemplate JS
34widgets/organizationprofile/templatejsTemplate JS
35/auto2/{id}/...Banner content3 separate requests for banner content
36/api/GetChannelManagersForUserAPI (JSON)Returns FULL user objects (~10 KB+ per user) with photo metadata, all URLs, login history, social profiles — massive over-fetching
37/api/GetTierDataAPI (JSON)
38/api/GetListedQuickActionModulesAPI (JSON)
39/api/GetAllLeadRequestsAPI (JSON)
40/api/GetThumbnailForWidgetAPI (JSON)
41/api/GetTierGoalDataProgressAPI (JSON)
42/api/GetContactInfoForDealRegistrationAPI (JSON)
43/api/GetApprovedDetailsOfDealRequestAPI (JSON)
44/api/getInteractiveBannerTemplateAPI (JSON)Sequential banner template calls
45/api/getInteractiveBannerPageAPI (JSON)Sequential banner page calls
46/api/GetDealRegistrationDataCountStatusAPI (JSON)

Third-Party Scripts

ScriptTransfer SizeMain Thread TimeNotes
Intercom1.1 MB199 msChat widget; consider lazy loading
Cloudflare CDN1.3 MB39 msStatic asset delivery
WalkMe~50 KBMultiple XHR callsUser guidance; fires 4+ API calls
Google CDN (jQuery UI)320 KB28 ms
Google Fonts248 KB3 font families

Other Frontend Issues

IssueImpactDetails
Forced Reflows (Layout Thrashing)222 ms wastedjQuery We() function triggers 169 ms of forced synchronous layout. Tooltip positioning (applyPlacement) adds 11 ms more.
DOM Size1,098 elements, depth 17<body> has 61 direct children. Style recalculations up to 55 ms affecting 432 elements.
No preconnect hints+200-400 msNo <link rel="preconnect"> for cache.sb.amp.vg, fonts.googleapis.com, or fonts.gstatic.com.

4. Total Request Count Summary

CategoryCountTotal Transfer
Document / page HTML2~387 KB
Widget HTML responses11~95 KB
BridgeAI chatbot1885 KB
API calls (JSON)~25~50 KB
Widget template JS5~15 KB
Static bundles (CSS/JS)~12~1.5 MB (cached on repeat)
Fonts~8~400 KB
Images~6~280 KB
Third-party (Intercom, WalkMe)~10~1.5 MB
TOTAL~80 requests~5.1 MB

5. Recommended Fixes (Priority Order)

PriorityFixEstimated SavingsEffort
P0 Enable gzip/brotli compression on all IIS responses (HTML, JSON, JS, CSS). Currently NONE of the origin server responses are compressed. ~2,300 ms LCP savings Low — IIS config change
P0 Merge GetProfileDetails + GetAssignedPersonaDetails into a single API call to eliminate the sequential dependency on the critical path. ~850 ms critical path savings Medium — Backend change
P0 Lazy-load BridgeAI chatbot (/bridge/ask/ai) — defer the 885 KB response until user clicks the chat icon instead of loading on every page view. 885 KB transfer savings + reduced server load Medium — Frontend change
P1 Add width/height to the brand logo image to fix CLS. Add fetchpriority="high" to improve LCP discovery. CLS 0.23 → ~0 Low — HTML attribute
P1 Defer twilio.js — add async or defer attribute. It’s render-blocking but not needed for first paint. ~300 ms FCP improvement Low — HTML attribute
P1 Increase cache TTL for hashed bundles on Cloudflare from 4 hours to max-age=31536000, immutable. URLs already contain content hashes. Eliminates re-downloads on repeat visits Low — Cache rule change
P1 Add cache headers to images served from /img/ (currently TTL: 0). At minimum max-age=86400. ~270 KB saved on repeat visits Low — IIS/config change
P1 Add <link rel="preconnect"> for cache.sb.amp.vg, fonts.googleapis.com, and fonts.gstatic.com. ~200-400 ms connection setup savings Low — HTML tags
P2 Reduce GetChannelManagersForUser response — currently returns full user objects with every field. The widget only needs name + photo URL. ~10 KB+ per request; faster server response Medium — Backend change
P2 Eliminate unnecessary API calls: GetNavigationTopBanner (returns empty), GetAnnocmentNotificationInfo (returns "no announcement"). Cache or skip when data is empty. 2 fewer API calls per page load Low — Conditional logic
P2 Lazy-load Intercom — defer the 1.1 MB Intercom widget until after the page is interactive. 199 ms main thread + 1.1 MB transfer Low — Script loading change
P2 Extract inline theme CSS from the 304 KB HTML document into a cacheable static file. The ~200 KB of dynamic theme rules are currently inlined on every page load. ~200 KB per page load Medium — Architecture change
P3 Bundle widget HTML + template JS into a single response per widget to eliminate the 2nd round trip. 1 fewer round trip per widget × 11 widgets High — Widget architecture change
P3 Optimize user profile image (thumb_400-Ellipse_1.png) — served at 400×400 but displayed at 40×40. Use responsive images or serve the correct size. Convert to WebP. ~104 KB savings Low — Image pipeline
P3 Investigate server-side TTFB — 2,434 ms for the initial HTML response suggests slow backend rendering. Profile the server-side code for the dashboard page. Potentially 1,000+ ms High — Backend investigation

6. Estimated Impact of Top Fixes

If we implement P0 + P1 fixes:
If we also implement P2 fixes:

Generated using Chrome DevTools Performance Trace — Lab data, no CPU/network throttling applied.