- 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.
Kraken Pro: where its trading screen loses time, and what to fix
Measured from the Netherlands in a logged-in Chrome, October 2026.
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 reload | median 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 reload | median 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 |
| Standing | 24 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 ready | 5 of 5 warm, 5 of 5 uncached |
| Notes | recent 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.
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.
| Host | Role | CDN edge seen | Connect | Response |
|---|---|---|---|---|
| pro.kraken.com | page | Cloudflare Amsterdam | 13 ms | 25 ms |
| futures.kraken.com | market data | Cloudflare Amsterdam | 14 ms | 35 ms |
| api.kraken.com | market data | Cloudflare Amsterdam | 14 ms | 10 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.
| When | What |
|---|---|
| 0.03 s | HTML arrives from Cloudflare's cache. |
| 0.25–0.83 s | Three 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 s | About a dozen account and config calls to iapi.kraken.com. |
| 0.67 s | First paint (an empty shell). |
| 0.98 s | The feed worker script (0.75 MB unpacked) loads. |
| 2.5–3.1 s | The OneTrust banner SDK (0.45 MB unpacked) and loader/collector scripts from ftlofs1.kraken.com (0.8 MB unpacked) load. |
| 3.66 s | The live feeds open (ws-frontend.kraken.com, two to futures.kraken.com); first futures messages at 3.85–3.96 s. |
| 4.66 s | Price shows. |
| 5.08–6.01 s | A 1.1 MB (unpacked) JSON response from www.kraken.com; layout-components.js requested at 5.37 s. |
| 7.03 s | Order book shows. |
| 7.93 s | The chart library (library.js, 0.68 MB compressed, 2.7 MB unpacked) is requested; lt-pane-views.js at 8.83 s. |
| 9.59 s | Chart 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.
| When | What |
|---|---|
| 0.0 s | HTML arrives |
| 2.4 s | First market-data request |
| 3.9 s | Price ready |
| 3.9 s | Order form ready |
| 4.7 s | First frame sent on a live feed |
| 4.8 s | First frame received on a live feed |
| 5.0 s | orders ready |
| 5.8 s | Order book ready |
| 6.2 s | Chart ready |
| 6.2 s | Trade-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
Bottlenecks and fixes, largest firstdiagnostic capture 1 October, uncached
- 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.
- 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.
- 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.
- 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.
- 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
- 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
- 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.