Criar um teste de velocidade de internet pode parecer algo complexo, mas na prática, é possível fazer tudo com PHP e JavaScript puro, sem bibliotecas externas, sem dependência de terceiros e sem enrolação.
Este post mostra como montar um sistema que mede:
- Velocidade de download
- Velocidade de upload
- Latência de resposta (proxy de ping)
Tudo em um único arquivo PHP.
speedtest.php
Copie e cole o conteúdo abaixo em um arquivo speedtest.php no seu servidor:
<?php
// Backend de upload
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['upload'])) {
$start = microtime(true);
file_get_contents('php://input'); // consome os dados enviados
$time = microtime(true) - $start;
$size = (int) ($_SERVER['CONTENT_LENGTH'] ?? 0);
echo json_encode([
'upload_speed_mbps' => round(($size * 8 / 1024 / 1024) / $time, 2),
'time' => round($time, 3)
]);
exit;
}
// Backend de download
if (isset($_GET['download'])) {
$size = 10 * 1024 * 1024; // 10 MB
header('Content-Type: application/octet-stream');
header('Content-Length: ' . $size);
echo str_repeat('A', $size);
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Teste de Velocidade</title>
<style>
body { font-family: monospace; margin: 2rem; }
button { padding: 0.5rem 1rem; font-size: 1rem; }
pre { background: #f0f0f0; padding: 1rem; border: 1px solid #ccc; }
</style>
</head>
<body>
<h1>Teste de Velocidade</h1>
<button onclick="runTest()">Iniciar Teste</button>
<pre id="result">Clique no botão para começar o teste.</pre>
<script>
async function runTest() {
const result = document.getElementById('result');
result.textContent = "Iniciando teste de download...";
// Teste de Download
const startDownload = performance.now();
const blob = await fetch('?download=1').then(r => r.blob());
const endDownload = performance.now();
const downloadTime = (endDownload - startDownload) / 1000;
const downloadMbps = ((blob.size * 8) / 1024 / 1024) / downloadTime;
result.textContent = `Download: ${downloadMbps.toFixed(2)} Mbps\nIniciando teste de upload...`;
// Teste de Upload
const uploadPayload = new Uint8Array(5 * 1024 * 1024); // 5 MB
const startUpload = performance.now();
const uploadResp = await fetch('?upload=1', {
method: 'POST',
headers: { 'Content-Type': 'application/octet-stream' },
body: uploadPayload
});
const endUpload = performance.now();
const uploadData = await uploadResp.json();
// Ajustando o cálculo do tempo e velocidade do upload
const uploadTime = (endUpload - startUpload) / 1000; // Tempo em segundos
const uploadMbps = (uploadPayload.length * 8 / 1024 / 1024) / uploadTime; // Calcula a velocidade de upload
result.textContent += `\nUpload: ${uploadMbps.toFixed(2)} Mbps`;
result.textContent += `\nLatência de upload: ${uploadData.time * 1000} ms`;
}
</script>
</body>
</html>
Considerações Técnicas
O que isso mede com precisão
- Download entre cliente e servidor via HTTP (sem cache)
- Upload real com consumo de 5 MB
- Tempo de resposta do upload como métrica de latência
O que isso não é
- Não é um Speedtest.net. Não usa múltiplas conexões TCP paralelas.
- Não testa sua conexão com a internet como um todo, apenas com o servidor onde está hospedado.
Onde isso é útil
- Para testar qualidade de conexão com seu servidor
- Para usar como ferramenta interna em redes, provedores ou intranets
- Para testar o desempenho entre clientes e servidores em datacenters
Limitações e Expansões
- É possível usar Web Workers para fazer múltiplas conexões paralelas e simular um Speedtest profissional.
- Pode-se usar backend em Go, Python ou Node.js se o objetivo for suportar alto tráfego com mais eficiência.
- Pode-se integrar log, autenticação, fila de testes e estatísticas.
