如何通过Ajax缩短大型数组的传输耗时
Alright, let’s tackle this latency issue you’re facing with transferring that 200×200 integer array via JSON. I’ve dealt with similar bulk data transfer problems before, so here are some practical, actionable solutions to speed things up:
JSON is plain text, and a 40,000-integer array can get surprisingly bulky. Compressing the response will drastically cut down on transfer size, which is usually the biggest culprit for latency.
Enable GZIP compression on PHP/Apache/Nginx:
The easiest way is to let PHP handle it with output buffering. Add this at the top of your PHP script:ob_start('ob_gzhandler'); header('Content-Type: application/json'); // Generate your 200x200 array $data = array_fill(0, 200, array_fill(0, 200, rand(1, 1000))); echo json_encode($data); ob_end_flush();Alternatively, configure your web server to auto-compress JSON responses (Apache’s
mod_deflateor Nginx’sgzipmodule) — this is even better since it applies to all relevant responses without modifying code.Use a more compact format (optional):
If your integers are small (e.g., 0-65535), you could skip JSON entirely and send a comma-separated string of values. For example, flatten the 2D array into a single string like1,2,3,...and split it client-side. This reduces the overhead of JSON’s brackets and quotes, though GZIP often makes this negligible.
Make sure you’re getting the most out of PHP’s json_encode function:
- Use the latest PHP version: Newer PHP releases (7.4+) have significant performance improvements for
json_encodewith large arrays. - Avoid unnecessary processing: Generate your integer array directly without extra loops or transformations. If you’re fetching data from a database, pull it in a format that’s already ready for encoding (e.g., fetch as a numeric array instead of associative).
JSON is convenient, but binary formats are way more compact for numeric data. For a 200×200 integer array, you can convert it to a binary buffer (like Uint16Array if your integers fit in 16 bits) and transfer that instead:
PHP Side:
header('Content-Type: application/octet-stream'); // Generate 2D array $data = array_fill(0, 200, array_fill(0, 200, rand(1, 1000))); // Flatten and convert to binary $flat = array_merge(...$data); $binary = pack('S*', ...$flat); // 'S' for unsigned 16-bit integers echo $binary;
JS Side:
fetch('data.php') .then(response => response.arrayBuffer()) .then(buffer => { const uint16Array = new Uint16Array(buffer); // Convert back to 2D array const data = []; for (let i = 0; i < 200; i++) { data.push(Array.from(uint16Array.slice(i*200, (i+1)*200))); } // Now render data as needed });
This cuts the transfer size from ~100KB (compressed JSON) to ~80KB (uncompressed binary) — and binary compresses even better if you still apply GZIP.
If you don’t need the entire array at once, split it into smaller chunks and load them sequentially. For example, send 50 rows at a time:
PHP Side:
header('Content-Type: application/json'); $startRow = $_GET['start'] ?? 0; $chunkSize = 50; // Generate chunk of data $data = []; for ($i = $startRow; $i < min($startRow + $chunkSize, 200); $i++) { $data[] = array_fill(0, 200, rand(1, 1000)); } echo json_encode([ 'data' => $data, 'nextStart' => $startRow + $chunkSize < 200 ? $startRow + $chunkSize : null ]);
JS Side:
function loadChunk(start = 0) { fetch(`data.php?start=${start}`) .then(response => response.json()) .then(result => { // Render the chunk immediately renderChunk(result.data); // Load next chunk if available if (result.nextStart !== null) { loadChunk(result.nextStart); } }); } function renderChunk(chunk) { const fragment = document.createDocumentFragment(); chunk.forEach(row => { const tr = document.createElement('tr'); row.forEach(num => { const td = document.createElement('td'); td.textContent = num; tr.appendChild(td); }); fragment.appendChild(tr); }); document.getElementById('table').appendChild(fragment); } // Start loading first chunk loadChunk();
This way, the user sees content immediately instead of waiting for the entire array to load.
Even if data comes fast, slow DOM manipulation can make it feel delayed. Avoid repeated DOM updates:
- Use
DocumentFragmentto batch-create elements (like in the chunk example above) instead of appending each row/cell individually. - If you’re rendering a table, consider using a virtual scrolling approach to only render the rows visible on screen — this is a game-changer for large datasets.
- Enable OPcache: This caches compiled PHP scripts, so your server doesn’t recompile the script on every request. Add
opcache.enable=1to yourphp.ini. - Increase memory limit: If your array is causing PHP to hit memory limits, set
memory_limit = 256M(or higher if needed) inphp.ini.
Pick the solutions that fit your use case — starting with GZIP compression is the quickest win, and chunking or binary transfer will give you the biggest performance boosts if you need them.
内容的提问来源于stack exchange,提问作者DUK

