Kraken Pro: 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.9 s (median of 5 loads), 24 of 27 perpetual trading screens, possible rank 20 to 24; after an uncached reload 6.1 s. The largest bottleneck: 11.0 MB of JavaScript is loaded before the trading screen works. First change to try: Split the three bundles by route so the futures trading screen loads only its own code; move account, settings and other products into lazy chunks.

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.9 s, range 5.7 s–6.1 s; loads: 5.7 s, 5.9 s, 5.9 s, 6.1 s, 5.9 s
Uncached reloadmedian 6.1 s, range 6.0 s–6.4 s; loads: 6.4 s, 6.0 s, 6.1 s, 6.1 s, 6.2 s
Standing24 of 27 by median; possible rank 20 to 24. 3.4 s behind the fastest, Thalex (2.4 s): 2.4 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 s5 s
Price3.7 s
Order form3.7 s +0.0 s
Order book5.3 s +1.6 s
Account panel5.3 s +0.0 s
Chart5.9 s +0.6 s
Trade-ready5.9 s +0.0 s settling

Stack

React; webpack bundles (main, frontend, vendor); TradingView-style chart library loaded as library.js; a feed web worker; OneTrust cookie banner, Sentry, Braze, an analytics script from seg.kraken.com and loader/collector scripts from ftlofs1.kraken.com.

Delivery

Through Cloudflare, almost all over HTTP/2 (281 of 297 requests); app files cached for 30 days (cf-cache-status HIT); the HTML is cached for 60 s at the edge.

HostRoleCDN edge seenConnectResponse
pro.kraken.compageCloudflare Amsterdam13 ms25 ms
futures.kraken.commarket dataCloudflare Amsterdam14 ms35 ms
api.kraken.commarket dataCloudflare Amsterdam14 ms10 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 orderdiagnostic capture 1 October, uncached

From one uncached diagnostic load recorded on 1 October 2026 (cache disabled, browser extensions active), so totals are slower than the campaign's timed loads; file names, sizes, headers, order of events and main-thread times are what the findings rely on. A main-thread time given for a script counts all the work that starts in that script, including code it calls in other files, so it shows where start-up work begins, not what one library costs. Endpoint paths were masked when the capture was saved.

WhenWhat
0.03 sHTML arrives from Cloudflare's cache.
0.25–0.83 sThree bundles download: main (1.1 MB compressed, 3.9 MB unpacked), frontend (1.0 MB, 3.9 MB), vendor (0.9 MB, 3.0 MB): 11.0 MB of JavaScript to parse and run.
0.56 sAbout a dozen account and config calls to iapi.kraken.com.
0.67 sFirst paint (an empty shell).
0.98 sThe feed worker script (0.75 MB unpacked) loads.
2.5–3.1 sThe OneTrust banner SDK (0.45 MB unpacked) and loader/collector scripts from ftlofs1.kraken.com (0.8 MB unpacked) load.
3.66 sThe live feeds open (ws-frontend.kraken.com, two to futures.kraken.com); first futures messages at 3.85–3.96 s.
4.66 sPrice shows.
5.08–6.01 sA 1.1 MB (unpacked) JSON response from www.kraken.com; layout-components.js requested at 5.37 s.
7.03 sOrder book shows.
7.93 sThe chart library (library.js, 0.68 MB compressed, 2.7 MB unpacked) is requested; lt-pane-views.js at 8.83 s.
9.59 sChart drawn: trade-ready in this load. 27 long tasks took 4.4 s of main thread; vendor.js alone 2.6 s.

Recorded warm reload, 3 October

One warm reload recorded with Chrome's performance trace. Recording slows the page, so read the order and the gaps, not the total.

WhenWhat
0.0 sHTML arrives
2.4 sFirst market-data request
3.9 sPrice ready
3.9 sOrder form ready
4.7 sFirst frame sent on a live feed
4.8 sFirst frame received on a live feed
5.0 sorders ready
5.8 sOrder book ready
6.2 sChart ready
6.2 sTrade-ready

324 requests before trade-ready; 10 long main-thread tasks (over 50 ms) before trade-ready, longest 374 ms; 48 script requests before the first panel; 0 requests over HTTP/1.1.

Request waterfalldiagnostic capture 1 October, uncached

70 of the 297 requests (the page itself, the longest and the largest) started before market data was ready in the 1 October uncached capture, 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. Shaded rows are named in a finding below, tagged with its ID.

PageScriptData requestImagewaiting for the serverdownloading

0 s0 s1 s1 s2 s2 s3 s3 s4 s4 s5 s5 s6 s6 s7 s7 s8 s8 s9 s9 s1pro.kraken.com9 kB24 msKR-12pro.kraken.com/frontend-7…1.1 MB487 msKR-13pro.kraken.com/vendor-331…903 kB542 msKR-14pro.kraken.com/main-9647c…1.1 MB582 ms5iapi.kraken.comopen6o552333.ingest.sentry.io20 B558 ms7pro.kraken.com/feed-worke…231 kB433 ms8pro.kraken.com187 kB267 ms9pro.kraken.com208 kB288 ms10ftlofs1.kraken.com/loader…127 kB124 ms11ftlofs1.kraken.com204 B320 ms12ftlofs1.kraken.com/collec…141 kB316 ms13cdn.cookielaw.org3 kB796 ms14cdn.cookielaw.org14 kB797 ms15cdn.cookielaw.org2 kB795 ms16cdn.cookielaw.org/otCommo…4 kB796 ms17sdk.iad-05.braze.com223 B710 ms18sdk.iad-05.braze.com117 B967 ms19status.kraken.com42 kB961 ms20o552333.ingest.sentry.io20 B1142 ms21o552333.ingest.sentry.io59 B1141 ms22sg.kraken.com414 B995 ms23pro.kraken.com31 kB867 ms24pro.kraken.com27 kB868 ms25pro.kraken.com12 kB867 ms26pro.kraken.com11 kB867 ms27iapi.kraken.com278 B914 ms28iapi.kraken.com2 kB912 ms29iapi.kraken.com9 kB928 ms30iapi.kraken.com400 B911 ms31iapi.kraken.com4 kB912 ms32iapi.kraken.com169 B913 ms33iapi.kraken.com226 B910 ms34iapi.kraken.com441 B922 ms35iapi.kraken.com213 B909 ms36iapi.kraken.com996 B909 ms37iapi.kraken.com318 B908 ms38iapi.kraken.com184 B924 ms39iapi.kraken.com5 kB923 ms40iapi.kraken.com169 B922 ms41iapi.kraken.com1 kB918 ms42iapi.kraken.com1 kB916 ms43iapi.kraken.com570 B915 ms44iapi.kraken.com340 B916 ms45iapi.kraken.com524 B917 ms46iapi.kraken.com229 B914 ms47iapi.kraken.com435 B915 ms48static.zdassets.com/snipp…5 kB549 ms49cdn.cookielaw.org533 B656 ms50cdn.seg.kraken.com20 kB634 ms51ekr.zdassets.com1 kB790 ms52pro.kraken.com/funding-sd…34 kB560 ms53pro.kraken.com/funding-sd…30 kB570 ms54www.kraken.com94 kB935 ms55iapi.kraken.com252 B879 ms56iapi.kraken.com266 B866 ms57iapi.kraken.com203 B866 ms58iapi.kraken.com266 B891 ms59iapi.kraken.com24 kB927 ms60iapi.kraken.com1 kB864 ms61sg.kraken.com356 B853 ms62pro.kraken.com/layout-com…149 kB332 ms63sg.kraken.com535 B965 ms64iapi.kraken.com276 B627 ms65wa.appsflyersdk.com560 B770 ms66o552333.ingest.sentry.io59 B1042 ms67ftlofs2.kraken.com292 B662 ms68cdn.seg.kraken.com/c3dbe2…2 kB534 ms69cdn.seg.kraken.com/aeadee…59 kB535 ms70pro.kraken.com/library.52…692 kB223 msprice 4.7 sorder book 7.0 schart 9.6 s
Download this figure as an image:

Bottlenecks and fixes, largest firstdiagnostic capture 1 October, uncached

KR-111.0 MB of JavaScript is loaded before the trading screen works.grade B
Evidence
/app/main-9647c5cc547bce79.js (4.0 MB unpacked), /app/frontend-7b6fc72d80f54253.js (3.9 MB) and /app/vendor-3315f4a76b3e6cd5.js (3.0 MB) total 3.1 MB compressed and 11.0 MB unpacked, all requested at 0.25 s; 2.6 s of main-thread work starts in vendor.js; 27 long tasks add up to 4.4 s before trade-ready. On the 3 October warm reload, with the files cached, one task still runs 374 ms at 1.85 s.
Gap observed
4.4 s of main-thread time across 27 long tasks
Holds back
Start-up as a whole; which panel waits for this work is not established.
Waterfall rows
row 2: 1.1 MB received, 3.9 MB unpacked, max-age=2592000, public, stale-if-error=; row 3: 903 kB received, 3.0 MB unpacked, max-age=2592000, public, stale-if-error=; row 4: 1.1 MB received, 4.0 MB unpacked, max-age=2592000, public, stale-if-error=
Fix
Split the three bundles by route so the futures trading screen loads only its own code; move account, settings and other products into lazy chunks.
Where
webpack splitChunks configuration and route-level dynamic imports.
Verify
DevTools → Coverage on reload: unused bytes in main/frontend/vendor; Performance → Bottom-up for vendor.js time.
KR-2The live feeds open 2.8 s after the bundles have arrived.grade C
Evidence
1 October capture: the bundles are downloaded by 0.83 s and the feed worker (/app/static/js/async/feed-worker.2b7d1ecec1.js, 0.8 MB unpacked) by 1.42 s; the first market socket is created at 3.66 s. Once created, the futures sockets connect in about 0.2 s, so the wait is before the socket is opened, not in the connection.
Gap observed
2.83 s between bundle download completion and market-socket creation
Holds back
Not established: the captures do not show which panel waits for this.
Fix
Create the futures sockets and send the market subscriptions as soon as the feed worker has loaded (1.4 s), not after the app has booted.
Where
feed-worker start-up and subscription manager.
Verify
DevTools → Network → WS: futures.kraken.com socket created before 1.5 s.
KR-3The chart library is discovered only after the order book is up.grade C
Evidence
library.529d5b8c7f545237e54b.js (2.7 MB unpacked) is requested at 7.93 s, 0.9 s after the book, and arrives in 0.22 s; the chart is drawn at 9.59 s, another 1.4 s later. So both the late request and the work after it count. In the campaign the chart is last, alone or tied, in all 5 warm loads (median 5.9 s).
Gap observed
0.90 s between the order book and the chart-library request
Holds back
Chart (median 5.9 s in the timed loads).
Fix
Preload the chart library (<link rel="preload"> or an early dynamic import) when the trade route is matched.
Where
Trade route entry; chart widget loader.
Verify
DevTools → Network: library.js starts before the price shows.
KR-4The order book shows 2.4 s after the price although the futures feed is already delivering.grade C
Evidence
1 October capture: the futures feed delivers 1,861 messages before trade-ready, from 3.96 s on; the price shows at 4.66 s and the book only at 7.03 s. In between come /app/static/js/async/layout-components.6368adc5aa.js (0.6 MB unpacked, 5.37–5.70 s) and a 1.1 MB response from www.kraken.com (5.08–6.01 s), which the timed loads suggest is /api/cms/data. The capture does not show that the book waits for either. 3 October warm load: price 3.92 s, book 5.81 s.
Gap observed
2.38 s between the price and the order book
Holds back
Book (median 5.3 s in the timed loads).
Fix
Render the book from the first feed snapshot; check whether the book component waits for layout-components.js or the /api/cms/data response, and remove that dependency.
Where
Order-book component mount conditions.
Verify
DevTools → Performance: book paint follows the first futures book message by under 200 ms.
KR-5Third-party scripts load before the market data.grade C
Evidence
1 October capture, all before the price at 4.66 s: ftlofs1.kraken.com/loader.min.js (0.4 MB unpacked) at 2.50 s and collector.min.js (0.4 MB) at 2.83 s; OneTrust otBannerSdk.js (0.5 MB) at 2.53 s; plus Braze, the seg.kraken.com analytics script and Sentry. Their main-thread cost in that load was not measured; in the 3 October recording OneTrust and Zendesk together used about 21 ms.
Measured
about 1.3 MB of third-party script before the price
Holds back
Not established: the captures do not show which panel waits for this.
Fix
Defer the ftlofs1 scripts, Braze, the seg.kraken.com script and the banner SDK until after trade-ready, where their purpose allows.
Where
Tag loading in the app shell.
Verify
DevTools → Network: none of these hosts before the first chart paint.
KR-6About 5.3 MB of catalog and translation JSON is loaded at start-up, some of it uncacheable.grade B
Evidence
1 October capture: three no-store responses of 1.1 MB (1.90 s), 1.2 MB and 0.8 MB unpacked (both 2.8 s) from iapi.kraken.com and futures.kraken.com, each about 20 to 90 KB compressed. The timed loads name candidates on iapi.kraken.com: /api/internal/markets/all/assets, /markets/assets and /markets/all/futures-contracts. A timed load shows two translation files requested together at 1.80 s, nl-NL/translations.json (0.8 MB unpacked) and en-US/translations.json (0.7 MB), and ten more Dutch and English translation scripts at 3.8–4.6 s. A fourth API response of 0.6 MB (cached for 60 s) arrives at 2.81 s.
Measured
3.2 MB of no-store catalog JSON, a further 0.6 MB response and 1.5 MB of translations
Holds back
Not established: the captures do not show which panel waits for this.
Fix
Load one translation file (the active language, with the other only as needed), and trim the market catalogs to the futures markets or give them a short cache lifetime.
Where
The i18n loader for /app/assets/locales/; the callers of the iapi.kraken.com market catalog endpoints.
Verify
DevTools → Network, filter "translations.json": one request; filter "iapi.kraken.com": catalog responses under 300 KB unpacked or served from cache.
Likely saving
Unknown: about 5.3 MB of JSON to parse on the main thread
KR-7Account and settings requests are repeated three to five times.grade C
Evidence
All 20 older timed loads repeat these requests before trade-ready: /api/internal/user-context/feature 3 to 5 times and /preferences 5 to 6 times; in one uncached load /kyc/flows is also requested 4 times (user-context/feature at 0.54, 1.81 and 2.13 s). The request parameters are not recorded, so some may differ.
Measured
three account endpoints requested 3 to 6 times each per load
Holds back
Not established: the captures do not show which panel waits for this.
Fix
Share one request per address between the components that need it.
Where
The callers of user-context/feature, kyc/flows and preferences on iapi.kraken.com.
Verify
DevTools → Network, filter "user-context/feature", "kyc/flows", "preferences": one request each on a load.
Likely saving
Small
KR-8Four more sockets are opened for other products and account data while the futures screen is still loading.grade C
Evidence
1 October capture: after the two futures sockets (3.66 and 3.72 s), the page opens ws-equities-auth.kraken.com (4.68 s), a second ws-frontend socket (4.98 s), ws-auth.kraken.com (4.99 s, connected only at 6.13 s) and ws-portfolio.kraken.com (4.99 s), all before the order book shows at 7.03 s.
Measured
four extra sockets opened before the order book shows
Holds back
Not established: the captures do not show which panel waits for this.
Fix
Open the equities, auth and portfolio sockets after trade-ready, or only when their panel is shown.
Where
Socket set-up in the app shell and feed worker.
Verify
DevTools → Network → WS: the equities, auth and portfolio sockets are created after the chart is drawn.
Likely saving
Unknown

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.