Decibel: where its trading screen loses time, and what to fix

Measured from the Netherlands in a logged-in Chrome, October 2026.

In short. On a warm reload the screen is trade-ready after 5.0 s (median of 5 loads), 19 of 27 perpetual trading screens, possible rank 16 to 25; after an uncached reload 6.5 s. The largest bottleneck: Nothing shows until 3.5 s: data is requested at 1.9 s and drawn 1.3 s after it arrives. First change to try: Start the market requests and the subscription from the first script and draw from the first snapshot; check why /decibel/api/v1/candlesticks takes about 1 s on the server.

Three measurements appear on this page, and their times differ. Rank and results come from the campaign's timed reloads. The diagnostic capture and the recorded reload are single loads made with recording switched on, which slows the page: read them for the order of events and the gaps, not for totals.

Resultscampaign: 5 warm and 5 uncached reloads

Warm reloadmedian 5.0 s, range 4.9 s–7.4 s; loads: 5.0 s, 5.0 s, 5.1 s, 7.4 s, 4.9 s
Uncached reloadmedian 6.5 s, range 5.8 s–8.8 s; loads: 6.5 s, 5.8 s, 7.0 s, 5.9 s, 8.8 s
Standing19 of 27 by median; possible rank 16 to 25. 2.5 s behind the fastest, Thalex (2.4 s): 2.0 times as long. The possible rank is the range the measurements leave open: it counts only the exchanges that clearly beat this one and those it clearly beats. Exchanges whose ranges overlap cannot be told apart.
Loads ready5 of 5 warm, 5 of 5 uncached
Notesrecent trades not measured: inactive tab

Where the time goescampaign medians, warm reload

Panels in the order they first showed real, usable data on a warm reload. The coloured part of each row is the time that panel added after the one before it. The last row is trade-ready: every panel is ready and the page has stopped moving.

0 s1 s2 s3 s4 s
Price3.3 s
Order book3.3 s +0.0 s
Order form3.3 s +0.0 s
Chart4.2 s +0.9 s
Account panel4.3 s +0.0 s
Trade-ready5.0 s +0.7 s settling

Stack

Next.js (Turbopack); TradingView chart library; Sentry with session replay; RudderStack analytics. Not captured on 1 October: from the 3 October recorded warm load, plus a logged-out follow-up recording that keeps the addresses but stopped at a legal notice.

Delivery

app.decibel.trade; market data from the Aptos API (api.mainnet.aptoslabs.com).

HostRoleCDN edge seenConnectResponse
app.decibel.tradepage—14 ms30 ms
api.mainnet.aptoslabs.commarket data—17 ms16 ms

Median of up to 10 attempts from the test machine. Response time includes the server's own time, so it is not a distance.

What happened, in orderrecorded warm reload 3 October

From one warm reload recorded with Chrome's performance trace on 3 October 2026. Recording slows the page, so read the order and the gaps, not the totals. Some host names were masked when the recording was saved.

WhenWhat
0.49 sHTML arrives.
1.87 sFirst market-data request.
2.13 sThe market socket subscribes; first message at 2.26 s.
3.55 sPrice, order book and order form show, 1.3 s after the first message.
4.16 sPositions and account panel show.
4.39 sChart drawn.
5.07 sTrade-ready in the recorded load. 1.5 s of long tasks before the first panel, the longest 348 ms; 115 script requests before the first panel.

Request waterfallrecorded warm reload 3 October

65 of the 299 requests (the page itself, the longest and the largest) started before trade-ready in the warm reload recorded on 3 October, in start order. The outlined part of a bar is waiting for the server; the solid part is downloading. Rows are numbered so a request can be pointed to. The numbers on the right are the size received and the total time. Vertical lines mark when a panel had data in this capture.

PageScriptData requestwaiting for the serverdownloading

0 s0 s1 s1 s2 s2 s3 s3 s4 s4 s5 s5 s1app.decibel.trade · trades97 kB767 ms2host masked118 ms3app.decibel.trade69 B66 ms4app.decibel.trade133 ms5app.decibel.trade149 B131 ms6app.decibel.trade72 B60 ms7app.decibel.trade71 B76 ms8api.mainnet.aptoslabs.com3 kB321 ms9app.decibel.trade189 ms10host masked230 ms11app.decibel.trade153 ms12api.mainnet.aptoslabs.com20 kB289 ms13host masked285 ms14api.mainnet.aptoslabs.com3 kB705 ms15app.decibel.trade153 B169 ms16host masked23 kB211 ms17app.decibel.trade135 B133 ms18app.decibel.trade114 B54 ms19api.mainnet.aptoslabs.com…42 kB826 ms20app.decibel.trade149 ms21app.decibel.trade261 B144 ms22app.decibel.trade240 B178 ms23app.decibel.trade232 B212 ms24app.decibel.trade328 B138 ms25app.decibel.trade287 B150 ms26app.decibel.trade234 B131 ms27app.decibel.trade235 B137 ms28app.decibel.trade · trades265 B147 ms29app.decibel.trade · trades243 B138 ms30host masked719 ms31host masked717 ms32host masked715 ms33app.decibel.trade1 kB134 ms34app.decibel.trade1 kB133 ms35app.decibel.trade1 kB178 ms36app.decibel.trade1 kB145 ms37app.decibel.trade1 kB133 ms38app.decibel.trade1 kB161 ms39api.mainnet.aptoslabs.com…40 kB629 ms40app.decibel.trade · trades1 kB151 ms41api.mainnet.aptoslabs.com136 B298 ms42api.mainnet.aptoslabs.com19 B300 ms43api.mainnet.aptoslabs.com44 B291 ms44api.mainnet.aptoslabs.com19 B298 ms45api.mainnet.aptoslabs.com797 B336 ms46api.mainnet.aptoslabs.com45 B336 ms47api.mainnet.aptoslabs.com19 B292 ms48api.mainnet.aptoslabs.com20 kB36 ms49host masked183 ms50host masked212 ms51api.mainnet.aptoslabs.com19 B299 ms52api.mainnet.aptoslabs.com2 kB593 ms53api.mainnet.aptoslabs.com…21 kB42 ms54host masked334 ms55host masked332 ms56api.mainnet.aptoslabs.com20 kB42 ms57host masked35 B159 ms58host masked337 ms59host masked36 B179 ms60api.mainnet.aptoslabs.com…21 kB23 ms61host masked288 ms62host masked285 ms63host masked282 ms64host masked283 ms65api.mainnet.aptoslabs.com25 kB25 msprice 3.5 sorder book 3.5 schart 4.4 s
Download this figure as an image:

Bottlenecks and fixes, largest firstrecorded warm reload 3 October

DC-1Nothing shows until 3.5 s: data is requested at 1.9 s and drawn 1.3 s after it arrives.grade C
Evidence
Recorded load: two requests to the Aptos API start at 1.80 and 1.87 s and take 0.7 and 0.8 s; the first socket frame is sent at 2.13 s and the first received at 2.26 s; the first panel shows at 3.55 s. In the warm campaign loads the first panels show at 3.2 to 3.3 s at the earliest. The logged-out follow-up names the candle request, api.mainnet.aptoslabs.com/decibel/api/v1/candlesticks: it takes 1.19 s the first time and 0.80 s the second, almost all of it waiting for the server, and is preceded by a permission request (CORS preflight).
Gap observed
1.29 s between the first socket message and the first panel
Holds back
Every panel: nothing is shown before this ends.
Fix
Start the market requests and the subscription from the first script and draw from the first snapshot; check why /decibel/api/v1/candlesticks takes about 1 s on the server.
Where
Trade page data bootstrap; the candlesticks endpoint on the Aptos API.
Verify
DevTools → Network: first market request before 0.5 s; "candlesticks" waiting time under 300 ms.
DC-21.5 s of long main-thread tasks before the first panel.grade B
Evidence
8 long tasks total 1.46 s before the first panel at 3.55 s, the longest 348 ms at 1.17 s; 115 script requests start before the first panel, 104 of them served from the browser cache, so the cost is running them, not downloading. The logged-out follow-up, which samples the running code, places the most time in these scripts: 04n43bj1ayibt.js (333 ms), the chart library (319 ms), the Turbopack runtime (254 ms) and Sentry's replay.min.js (154 ms). Two tasks stand out: one of 530 ms at 2.87 s, spent in module initialisers (125 ms in the Turbopack runtime, 116 ms in 0nk8di7~0omx1.js, 85 ms in 0yr4832mhp2lw.js), and one of 537 ms at 3.70 s with about 93 ms in setting and clearing timers; the first candle request goes out at 3.92 s, during that second task.
Gap observed
1.46 s of main-thread time in 8 long tasks before the first panel
Holds back
Every panel: nothing is shown before this ends.
Fix
Bundle the start-up chunks, defer wallet and account code until after the first panels, start Sentry session replay after trade-ready, and look at the two half-second tasks: what the module initialisers at 2.9 s set up, and which component sets and clears timers at 3.7 s.
Where
Bundler configuration; Sentry replay initialisation.
Verify
DevTools → Performance: no task over 200 ms before the first panel; replay.min.js is requested after the chart is drawn.
DC-3The HTML takes 0.5 s.grade B
Evidence
0.49 s from sending the request to the first byte in the recorded load; the document is 97 KB compressed and arrives by 0.77 s.
Gap observed
0.49 s to the document first byte
Holds back
Every panel: nothing is shown before this ends.
Fix
Cache the trading page HTML at the edge.
Where
CDN rules for app.decibel.trade.
Verify
DevTools → Network → document Timing.
DC-4Trade-ready comes 0.7 s after the panels are in: the chart and the order form are still animating.grade B
Evidence
All 10 campaign loads: in the wait before trade-ready, counted from when the page's main parts are in place (0.65 to 0.74 s), the chart panel still has a running animation. Recorded warm load: chart at 4.39 s, trade-ready at 5.07 s; the chart animates in 6 samples in between (the last at 4.98 s) and the order form in 2. In the warm campaign loads the chart is last in 2 of 5 and the positions and account panels in the others. One warm load was slow before the panels, not after: its first panels came at 5.5 s where the others had them by 3.3 s.
Gap observed
0.65 to 0.74 s before trade-ready in the ten timed loads, counted from when the page's main parts are in place
Holds back
Trade-ready itself: the page counts as ready only when nothing in a panel is still animating or loading.
Fix
Record a reload with DevTools → Animations and find what still animates in the chart after the candles are drawn, for example a toolbar loading spinner or a fade-in; end it when the data is in. Do the same for the order form.
Where
The chart panel and its loading states. The order form.
Verify
DevTools → Animations during a reload: nothing in the chart container animates after the candles appear.
Likely saving
Up to ~0.7 s
DC-5Analytics requests fail and are retried while the page loads.grade B
Evidence
Logged-out follow-up: the permission requests (CORS preflights) for RudderStack at rudder.mainnet.gcp.aptosdev.com/v1/page and /v1/track are answered with HTTP 503 and retried: 12 failures between 5.7 and 22 s, four of them after about 1.1 s and eight after about 0.27 s. This does not touch market data.
Measured
12 failed analytics permission requests in one load
Holds back
Not established: the captures do not show which panel waits for this.
Fix
Fix the RudderStack endpoint or its CORS set-up, and stop retrying during page load.
Where
RudderStack data-plane URL and its retry settings.
Verify
DevTools → Network, filter "rudder": no 503 responses.
Likely saving
None on trade-ready
DC-6A 227 KB font file.grade B
Evidence
Logged-out follow-up: /fonts/FTAktualDBVariable.woff2 is 227 KB, requested at 2.49 s and again (from cache) at 4.80 s for the chart frame.
Measured
one 227 KB font file
Holds back
Not established: the captures do not show which panel waits for this.
Fix
Ship a subset of the font with only the character ranges and weights in use.
Where
The font file and @font-face rule.
Verify
DevTools → Network, filter "woff2": the font is under 100 KB.
Likely saving
Small on a reload; about 0.15 MB less on a first visit

Grade B: the capture shows the problem directly. Grade C: the order of events in the capture points to it; the dependency is for the team to confirm. The order is our judgement of each finding's effect on trade-ready, largest first; it is not sorted by gap. A gap is the time between two observed events or the time one piece of work takes; gaps overlap and do not add up. Where a finding is about size or count and no time was measured, the row says what was measured instead. Holds back names the panel the finding delays. Nothing here is graded higher, because no fix was confirmed by changing a page and measuring again.

Savings are estimates from the timeline, not measured after a change. They overlap, so they do not add up; the summary gives the combined estimate.

How this was measured

Timings: 5 warm and 5 uncached reloads in a seeded random order across all exchanges, each judged against a checklist frozen for this page before the campaign; trade-ready is the first moment every checklist panel shows real data, nothing is still loading, and the layout holds still for 0.5 s. The findings on this page come from separate recorded loads, which are never part of the timings. Full method.