- Evidence
- All 5 warm campaign loads have the book last, at 4.4 to 4.8 s (median 4.7 s), against medians of 2.6 s for price and order form and 3.1 s for the chart. Inside single loads: 3 October recorded load, chart 2.93 s and book 4.41 s; a timed warm load, price 2.59 s, chart 3.84 s, book 4.80 s. Two earlier loads on 1 October had a much longer wait for the book: 7.49 s and 6.93 s, 3 to 4 s after the chart. The public feed delivers its first message at 0.70 s in the recorded load and 1.24 s in the uncached capture, 3 to 4 s before the book shows. The captures do not show whether that first message carries the book.
- Gap observed
- 1.5 s between the chart and the order book inside the recorded load; 1.6 s between the two medians of the timed loads
- Holds back
- Book (median 4.7 s in the timed loads).
- Fix
- Render the book from the first book snapshot on the public feed; find what the book component waits for after the other panels.
- Where
- Order-book component and its subscription start.
- Verify
- DevTools → Network → WS (api-pub): book snapshot time against book paint in Performance.
Bitfinex: 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 4.8 s, range 4.5 s–4.8 s; loads: 4.8 s, 4.8 s, 4.7 s, 4.5 s, 4.8 s |
| Uncached reload | median 4.8 s, range 4.5 s–5.2 s; loads: 4.5 s, 5.0 s, 4.6 s, 5.2 s, 4.8 s |
| Standing | 17 of 27 by median; possible rank 13 to 20. 2.4 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 ready | 5 of 5 warm, 5 of 5 uncached |
| Notes | recent trades not measured: outside viewport |
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, built with Vite (index and App chunks); TradingView chart library (library.js); Google Tag Manager.
Delivery
trading.bitfinex.com through Cloudflare over HTTP/2; HTML marked no-cache and not cached at the CDN (DYNAMIC); content-hashed app files cached for only one day; market data from api-pub.bitfinex.com and api.bitfinex.com.
| Host | Role | CDN edge seen | Connect | Response |
|---|---|---|---|---|
| trading.bitfinex.com | page | Cloudflare Amsterdam | 13 ms | 39 ms |
| api-pub.bitfinex.com | market data | Cloudflare Amsterdam | 13 ms | 29 ms |
| api.bitfinex.com | market data | Cloudflare Amsterdam | 13 ms | 33 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.04 s | HTML arrives. |
| 0.14–0.47 s | index.js (859 KB unpacked) and CSS. |
| 0.49 s | First paint. |
| 0.66–0.84 s | App.js (2.6 MB unpacked); both sockets open at 0.66 s. The public feed (api-pub) completes its handshake at 1.22 s and sends its first message at 1.24 s. |
| 1.31–2.26 s | An api.bitfinex.com request takes 0.95 s. |
| 2.40–2.87 s | Two REST responses from api-pub.bitfinex.com (337 KB and 197 KB unpacked, no-cache). |
| 2.53 s | Price shows. |
| 2.95 s | The chart library (library.js, 2.6 MB unpacked) is requested, after the price. |
| 3.79 s | Chart drawn. This older capture did not time the order book, so it does not show trade-ready; in the five ranked warm loads the book is last, at 4.4–4.8 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 |
| 0.3 s | First market-data request |
| 0.7 s | First frame sent on a live feed |
| 0.7 s | First frame received on a live feed |
| 2.5 s | Price ready |
| 2.5 s | Order form ready |
| 2.9 s | Chart ready |
| 4.4 s | Order book ready |
| 4.4 s | Trade-ready |
249 requests before trade-ready; 5 long main-thread tasks (over 50 ms) before trade-ready, longest 362 ms; 15 script requests before the first panel; 0 requests over HTTP/1.1.
Request waterfalldiagnostic capture 1 October, uncached
66 of the 164 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.
PageScriptStylesheetFont, media, other fileData requestwaiting for the serverdownloading
Bottlenecks and fixes, largest firstdiagnostic capture 1 October, uncached
- Evidence
- 1 October capture: the public socket (api-pub) is created at 0.66 s, connected at 1.22 s and delivers at 1.24 s. Two api-pub REST responses (345 KB and 202 KB unpacked, marked no-cache) start only at 2.40 s and 2.77 s, one just before and one just after the price at 2.53 s; a separate api.bitfinex.com request takes 0.96 s (1.31–2.26 s), and the 3 October recording has one of 0.88 s on the same host (0.77–1.65 s). Other requests, such as /v2/tickers, already go out at 0.69 s, so not all REST is late.
- Gap observed
- 1.2 s between the public feed connecting and the first late REST request
- Holds back
- Not established: the captures do not show which panel waits for this.
- Fix
- Start the two late api-pub requests with the early ones at 0.7 s, or take that data from the socket subscription.
- Where
- Trade page data bootstrap.
- Verify
- DevTools → Network: all api-pub REST requests start before 1 s.
- Evidence
- 1 October capture: lib/tradingview-27.005/bundles/library.53d7b371803f8096a4cd.js (2.7 MB unpacked) is requested at 2.95 s, 0.42 s after the price; chart drawn at 3.79 s. A timed warm load: library at 2.93 s, the candle request (/v2/candles/…/hist) only at 3.64 s, chart at 3.84 s, 0.18 s after the candles arrive. The chart is not the last panel, so this does not move trade-ready until BFX-1 is fixed.
- Gap observed
- 0.42 s between the price and the chart-library request
- Holds back
- Chart (median 3.1 s in the timed loads).
- Fix
- Preload library.js on the trading route and send the candle request with the first market requests at 0.7 s.
- Where
- HTML head or route entry; the chart datafeed.
- Verify
- DevTools → Network: library.js starts before 1 s; filter "candles": the request starts before 1 s.
- Evidence
- index-txXZyaLE.js (0.9 MB unpacked), assets/App-C2ylfBnU.js (2.6 MB) and the chart library (2.7 MB) carry "public, max-age=86400" although their names contain a content hash. The 3 October warm reload re-checked 19 of 235 responses with the server.
- Measured
- max-age=86400 for content-hashed scripts
- Holds back
- Not established: the captures do not show which panel waits for this.
- Fix
- Serve hashed assets with max-age=31536000, immutable.
- Where
- Cloudflare cache rules for trading.bitfinex.com assets.
- Verify
- DevTools → Network → Headers on App-*.js.
- Evidence
- 4 of the 5 warm campaign loads: once every panel passes, the order form, which starts at 428 px high, grows from 436 to 459 px at the next sample, so the page is not yet steady; trade-ready comes 61 to 108 ms after the book. In 3 of the 5 uncached loads the chart is also still animating after the book, for 0.24 to 0.80 s.
- Gap observed
- 0.06 to 0.11 s between the book and trade-ready in four warm loads
- Holds back
- Trade-ready itself: the page counts as ready only when nothing in a panel is still animating or loading.
- Fix
- Give the order form its final height from the start (it grows 31 px in two steps, the last 23 px after everything else is ready), and end the chart's loading animation when its data is in.
- Where
- Order-form layout; the chart panel's loading states.
- Verify
- DevTools → Performance → Layout shifts: none after the order book shows.
- Likely saving
- ~0.1 s warm; up to 0.8 s uncached
- Evidence
- A timed warm load: api-pub.bitfinex.com/v2/tickers is requested at 0.690 and 0.693 s with the same address; both answer in 40 ms. The response sizes were not recorded.
- Measured
- one ticker request sent twice at start-up
- Holds back
- Not established: the captures do not show which panel waits for this.
- Fix
- Share one tickers request between its two callers.
- Where
- The two start-up callers of /v2/tickers.
- Verify
- DevTools → Network, filter "v2/tickers": one request at start-up.
- Likely saving
- Not measured
- Evidence
- 1 October capture: 11 media files (sounds or short clips; the capture masks their names) from static.bitfinex.com, 440 KB together, requested at 0.56 s and complete by 0.68 s, before the public feed is connected at 1.22 s. They are not from the browser cache in that load.
- Measured
- 11 media files, 440 KB, in the first second
- Holds back
- Not established: the captures do not show which panel waits for this.
- Fix
- Load notification sounds and other media on first use, not at start-up.
- Where
- The code that preloads media from static.bitfinex.com.
- Verify
- DevTools → Network, filter "Media": no requests before the order book shows.
- Likely saving
- Small
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.