For the browser to show a background image it has to know the dimension of the element containing the background. This means that you cannot have dimensions that are dependent on page content if the image should show up before page content does.
The second thing to be aware of is that the content may no reach a browser directly on PHP output. You should use flush() in php to force output to be sent to the web server. But, the web server may also use buffered output which you cannot effect directly. It's possible that you can find out what this buffer size is by inspecting some conf file.
This, however, works for me
<style type="text/css">
#background
{
background-image: url('http://example.com/exampleimage.jpg');
width: 820px;
height: 616px;
position: absolute;
top: 0px;
left: 0px;
}
</style>
</head>
<body style="margin: 30px;">
<div id="background">
</div>
<?php
echo str_repeat(' ', 4096);
flush();
sleep(2);
?>
<div>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</body>
That is, the background image is shown "directly", while the text doesn't show up until 2 seconds later.
To solve these two issues would otherwise mean that you have nothing but body with background sent on page request, and then use body.onload to load the rest of the contents using ajax.