You can achieve this by adding a class to <body> on load and defining any styles and transitions in CSS.
While this technique ensures inheritance throughout your document, enabling any number of solutions, the most straightforward is to utilise an :after pseudo element on your <body>:
window.onload = function () {
  
  // add a 'ready' class once the window has loaded
  document.body.classList.add("ready");
};
body {
  background: red;
  color: white;
  text-align: center;
}
/* this creates your overlay without unnecessary HTML markup */
body::after {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: white;
}
/* transition the overlay out when body has a 'ready' class */
body.ready::after {
  opacity: 0;
  visibility: hidden;
  
  /* transitioning visibility to "hidden" allows a seamless opacity transition */
  transition-property: opacity, visibility;
  
  /* Set your animation duration here */
  transition-duration: 0.4s;
}
<h1>Awesome content</h1>
 
 
Sidenote: To allow for users without javascript enabled (who would otherwise see a blank screen), you might also consider allowing a 'no-js' class on <html> (replaced with 'js' in your <head>). Your css pseudo declaration would then be: html.js body::after{...}. More info: What is the purpose of the HTML "no-js" class?