It seems this topic hasn't been touched in a while, but I had a similar problem and wanted to pass along the solution I found. In spite of turning off output buffers and compression, I found network and browser buffers were getting in the way. All the progress messages were only shown in the final milliseconds on the browser. The solution was to simply fill the pipeline with spaces before the flush. My entire solution that worked was:
echo "$i % complete...<br>";
// Padding in case of other browser or network buffers
echo(str_repeat(' ', 4096));
// Now, force this to be immediately displayed:
if (ob_get_level() > 0 && ob_end_flush())
ob_start();
flush();