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

Measured from the Netherlands in Chrome, logged out, October 2026.

In short. On a warm reload the screen is trade-ready after 3.9 s (median of 5 loads), 9 of 27 perpetual trading screens, possible rank 7 to 11; after an uncached reload 4.7 s. It was measured logged out, so with fewer panels to load than a logged-in screen. The largest bottleneck: The 4.9 MB chart library is requested only after book and price are up. First change to try: Preload library.js when the trading route is matched, and send the two candle requests (kline/market and kline/mark) with the first market requests, not after the library has loaded.

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 3.9 s, range 3.8 s–4.3 s; loads: 4.3 s, 3.8 s, 3.9 s, 4.0 s, 3.9 s
Uncached reloadmedian 4.7 s, range 4.4 s–9.3 s; loads: 4.7 s, 4.4 s, 9.3 s, 4.8 s, 4.7 s
Standing9 of 27 by median; possible rank 7 to 11. 1.4 s behind the fastest, Thalex (2.4 s): 1.6 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
Notesmeasured logged out (fewer panels to load); order book or trades drawn as a picture; checked as drawn and updating, values not read; 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.

0 s1 s2 s3 s
Price1.7 s
Order book2.0 s +0.4 s
Account panel2.0 s +0.0 s
Order form2.8 s +0.8 s
Chart2.9 s +0.2 s
Trade-ready3.9 s +0.9 s settling

Stack

React 18.2; TradingView chart library (library.js, the largest in this test); unversioned "latest" scripts (data-core, by-vendors, header, antiPhishingCode); AppsFlyer, an A/B-test service and Google sign-in.

Delivery

www.bybit.com over HTTP/3 (OpenResty); HTML cached 60 s; hashed app files cached a year; unversioned "latest" scripts cached for 60–300 s; market data over one socket to ws2.bybit.com.

HostRoleCDN edge seenConnectResponse
www.bybit.compage—13 ms23 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.07 sHTML arrives.
0.21–0.55 smain.js (2.4 MB unpacked), vendor-biz (0.9 MB), data-core.latest, by-vendors.latest; react.18.2 later starts 1.04 s of main-thread work.
0.72 sFirst paint.
1.09 sThe market socket opens; handshake at 1.64 s; first message at 2.14 s.
1.71–1.90 sheader.latest.js (617 KB unpacked) and antiPhishingCode.latest.js (328 KB unpacked).
1.75–3.02 sA/B-test requests to sc-abtest…de take 1.3 s.
2.75 sOrder book shows; price at 3.24 s.
3.70 sThe chart library is requested: library.js, 0.8 MB compressed, 4.8 MB unpacked.
3.78 sGoogle sign-in script (268 KB unpacked).
5.29 sChart drawn: trade-ready in this load.

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.8 sPrice ready
2.8 sasks ready
2.8 sbids ready
2.8 sOrder form ready
2.8 spositions ready
2.8 sFirst market-data request
3.0 sChart ready
3.9 sTrade-ready

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

Request waterfalldiagnostic capture 1 October, uncached

65 of the 262 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.

PageScriptStylesheetData requestwaiting for the serverdownloading

0 s0 s1 s1 s2 s2 s3 s3 s4 s4 s5 s5 s1www.bybit.com13 kB326 ms2www.bybit.com/monitor.lat…28 kB326 ms3www.bybit.com/react.18.2.…45 kB332 ms4www.bybit.com/global-comm…3 kB319 ms5www.bybit.com/data-core.l…65 kB339 ms6www.bybit.com/by-vendors.…62 kB335 ms7www.bybit.com/by-globals.…29 kB335 ms8www.bybit.com/fe-trading-…7 kB332 ms9www.bybit.com/main-DAmgxw…77 kB322 ms10www.bybit.com/vendor-biz-…2 kB319 ms11www.bybit.com/__commonjsH…388 B335 ms12www.bybit.com/vendor-biz-…38 kB337 ms13www.bybit.com/vendor-biz-…247 kB341 ms14www.bybit.com/vendor-webw…95 kB338 ms15www.bybit.com/vendor-pv-w…47 kB339 ms16www.bybit.com/vendor-trad…56 kB332 ms17www.bybit.com/vendor-pb-w…65 kB333 ms18www.bybit.com/main-Cj06xC…677 kB346 ms19www.bybit.com201 kB335 ms20sc-datasink.ffbbbdc6d3c35…12 B379 ms21www.bybit.com407 B419 ms22www.bybit.com67 kB387 ms23www.bybit.com70 kB323 ms24www.bybit.com54 B342 ms25www.bybit.com70 kB131 ms26www.bybit.com151 B351 ms27www.bybit.com2 kB349 ms28www.bybit.com158 B432 ms29www.bybit.com197 B331 ms30www.bybit.com24 kB1077 ms31www.bybit.com586 B1096 ms32www.bybit.com349 B778 ms33www.bybit.com166 B778 ms34www.bybit.com/header.late…170 kB156 ms35www.bybit.com/antiPhishin…78 kB183 ms36sc-abtest.ffe390afd658c19…3 kB1275 ms37sc-abtest.ffe390afd658c19…3 kB1278 ms38www.bybit.com2 kB708 ms39www.bybit.com/b4a5e2f575d…152 B520 ms40www.bybit.com540 B721 ms41www.bybit.com3 kB659 ms42www.bybit.com/QuickOrder-…2 kB352 ms43www.bybit.com/ConfirmClos…967 B352 ms44www.bybit.com358 B518 ms45monitor-frontend-collecto…21 B328 ms46monitor-frontend-collecto…21 B504 ms47www.bybit.com113 B435 ms48www.bybit.com/4865.125afa…7 kB307 ms49www.bybit.com/3841.14f772…598 B306 ms50www.bybit.com520 B430 ms51www.bybit.com166 B660 ms52www.bybit.com188 B456 ms53www.bybit.com50 kB500 ms54www.bybit.com54 B295 ms55www.bybit.com2 kB652 ms56www.bybit.com971 B275 ms57www.bybit.com/library.0f0…819 kB254 ms58accounts.google.com101 kB80 ms59www.bybit.com537 B329 ms60sc-datasink.ffbbbdc6d3c35…12 B298 ms61monitor-frontend-collecto…21 B554 ms62sc-datasink.ffbbbdc6d3c35…12 B442 ms63www.bybit.com384 B457 ms64accounts.google.com129 B285 ms65www.bybit.com1 kB378 msprice 3.2 sorder book 2.7 schart 5.3 s
Download this figure as an image:

Bottlenecks and fixes, largest firstdiagnostic capture 1 October, uncached

BY-1The 4.9 MB chart library is requested only after book and price are up.grade C
Evidence
1 October capture: library.0f032f79907a36608fbe_v1.js (4.9 MB unpacked, 0.8 MB compressed) is requested at 3.70 s, 1.0 s after the book at 2.75 s; chart drawn at 5.29 s. In the campaign the chart is the last panel in the warm loads (median 2.9 s). A timed warm load shows the two candle requests starting later still: /x-api/contract/v5/public/instrument/kline/market at 4.00 s and /kline/mark at 4.09 s, with the chart ready at 4.20 s, 34 ms after the second one ends.
Gap observed
1.0 s between the order book and the chart library request
Holds back
Chart (median 2.9 s in the timed loads).
Fix
Preload library.js when the trading route is matched, and send the two candle requests (kline/market and kline/mark) with the first market requests, not after the library has loaded.
Where
Trading route entry; chart widget loader and datafeed.
Verify
DevTools → Network: library.js starts before 1.5 s; filter "kline": both requests start before 2 s.
BY-2Eleven unversioned scripts are cached for only 60 to 300 seconds.grade B
Evidence
1 October capture: ten "latest" scripts have max-age=60 (header, antiPhishingCode, by-vendors, by-globals, monitor, globalPopup, complianceWall, campaign, googleOneTap, ada) and data-core.latest.min.js has 300 s; the largest are header (0.6 MB unpacked), antiPhishingCode (0.3 MB) and data-core (0.2 MB). The hashed app files next to them are cached for a year. A trader who returns after more than a minute has to re-check these with the server; within a minute they come from cache (the 3 October warm reload re-checked only 1 of 279 responses).
Measured
cache lifetimes of 60 s for ten scripts and 300 s for one
Holds back
Not established: the captures do not show which panel waits for this.
Fix
Version the "latest" scripts by content hash and cache them for a year, like the hashed app files.
Where
Build output and CDN rules for *.latest.js and *.latest.min.js.
Verify
DevTools → Network → Headers on header.latest.js: max-age=31536000.
BY-3Marketing and sign-in scripts compete with the chart.grade C
Evidence
1 October capture: two A/B-test calls take 1.3 s each (1.75–3.02 s); AppsFlyer scripts at 0.59 and 1.04 s; googleOneTap.latest.js at 3.21 s and Google's account script (0.3 MB unpacked) at 3.78 s, all before the chart is drawn at 5.29 s. In a timed warm load the A/B-test calls (/api/v2/abtest/online/results) take only 0.19 s, so the 1.3 s is not constant. Whether the chart waits for any of these is not shown.
Gap observed
1.3 s for the A/B-test calls
Holds back
Probably the chart (median 2.9 s in the timed loads): the timing points to it, but the captures do not show that this panel waits for it.
Fix
Load A/B testing, AppsFlyer and Google sign-in after the chart is drawn.
Where
Tag loading in the trading page.
Verify
DevTools → Network: no sc-abtest, appsflyer or accounts.google.com request before the first chart paint.
BY-4Trade-ready comes 0.9 s after the chart has its data: the chart is still animating.grade B
Evidence
All 5 warm campaign loads: between the chart having its data and trade-ready (0.89 to 1.18 s, median 0.95 s) the only readiness condition failing is an animation running in the chart panel. Recorded load: 0.85 s, 9 of 10 samples. Nothing moves and no font or image is pending.
Gap observed
0.95 s median between the chart and trade-ready in the five warm loads
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.
Where
The chart panel and its loading states.
Verify
DevTools → Animations during a reload: nothing in the chart container animates after the candles appear.
Likely saving
Up to ~0.9 s
BY-5In one of five uncached loads the order book dropped out for 5.7 seconds.grade C
Evidence
Campaign, uncached round 4: the chart had its data at 3.59 s, but the bid side of the order book failed its check in 57 of the next 58 samples and trade-ready came only at 9.29 s. The other 4 uncached loads did not show it. The records do not show a failed request.
Gap observed
5.7 s with the bid side of the order book failing its check, in one uncached load
Holds back
The order book, in 1 of 10 timed loads.
Fix
Check the order book for a state where the bid side empties or re-renders after the first snapshot.
Where
Order-book component and its feed subscription on ws2.bybit.com.
Verify
Reload 20 times with the cache disabled: the bid side stays filled once it has appeared.
Likely saving
None on the median; aimed at a rare 5.7 s stall
BY-6A 0.2 MB translation file and the web configuration are requested repeatedly.grade B
Evidence
Timed loads: /common-static/fhs/i18n-upload/low-cache/project/release/common/en.json (237 KB unpacked, 70 KB compressed) is requested twice, 0.3 s apart (0.64 and 0.98 s uncached, both downloaded; 0.71 and 1.05 s warm, both from cache). /x-api/v3/config/web is fetched seven times before trade-ready on the uncached load (from 1.40 to 4.64 s) and four times on the warm one. /x-api/spot/api/basic/symbol_list_v3, the spot symbol list (169 KB unpacked), takes 0.56 to 0.66 s on the perpetuals page.
Measured
one translation file requested twice and one configuration address up to seven times per load
Holds back
Not established: the captures do not show which panel waits for this.
Fix
Share one request for the common translation file and one for config/web; load the spot symbol list only where spot markets are shown.
Where
The callers of common/en.json and /x-api/v3/config/web; the caller of symbol_list_v3.
Verify
DevTools → Network, filter "common/en.json" and "config/web": one request each.
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.