Render免费层服务器启动时预加载动画无法正常显示的问题
解决Render免费层休眠后预加载动画不生效的问题
我在render.com免费层部署了动态网站,该服务闲置15分钟会进入休眠状态,收到新请求时重启服务器需要较长时间,导致页面加载卡顿。想用fetch检测服务状态,在启动期间显示预加载动画,但当前代码仅在服务器启动完成后生效,无法达到预期效果。
原代码
JavaScript代码
// Function to check if the service is up using async/await async function isServiceUp() { try { const response = await fetch("https://cookyourkitchen.onrender.com"); console.log(response); } catch (error) { console.error('Error checking service status:', error); return false; // Service is down or unreachable } } $(document).ready( () => { if(isServiceUp){ $("#loader").fadeOut(1000); $("#content").fadeIn(1000); } else { $("#loader").show(); } });
HTML(EJS)代码
<body> <div id="loader" class="loader"></div> <div id="content" class="container"> <div class="px-4 py-5 my-4 text-center"> <h1 class="display-5 fw-bold text-body-emphasis">Cook Your Kitchen</h1> <div class="col-lg-6 mx-auto"> <p class="lead mb-4">Have some random ingrediants in your kitchen? <br> Those veggies about to go bad?? <br> Enter the ingrediants you want to use and get recipe suggestions! </p> <form action="/search" method="post"> <div class="d-grid gap-2 d-sm-flex justify-content-sm-center"> <input type="text" id="search" name="ingrediants" class="form-control" placeholder="Chicken, beans, tomato,..." aria-label="Recipient's username" aria-describedby="button-addon2"> <button class="btn btn-outline-secondary" type="submit" value="Submit" id="button-addon2">Get a recipe</button> </div> </form> </div> </div> </div> <script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script> <script src="preloadwebpage.js"></script> <script src="loadrecipes.js"></script> </body>
问题分析
- 异步函数判断错误:
isServiceUp是异步函数,直接用if(isServiceUp)判断的是函数对象本身是否存在,永远为true,不会等待异步请求完成就执行了隐藏loader的逻辑。 - 成功状态未返回:
isServiceUp函数在请求成功时没有返回true,无法正确告知调用方服务已就绪。 - 初始状态逻辑颠倒:页面加载时应默认显示loader、隐藏内容,等检测到服务就绪后再切换状态,原代码逻辑会导致初始就隐藏loader。
修正方案
调整JavaScript代码
// 检测服务是否就绪的异步函数 async function isServiceUp() { try { const response = await fetch("https://cookyourkitchen.onrender.com", { method: 'HEAD', // 用HEAD请求减少数据传输,更高效 timeout: 10000 // 设置超时时间,避免无限等待 }); return response.ok; // 响应状态码在200-299之间则返回true } catch (error) { console.error('检测服务状态出错:', error); return false; // 请求失败或超时,服务未就绪 } } $(document).ready(async () => { // 初始状态:显示loader,隐藏内容 $("#loader").show(); $("#content").hide(); // 循环检测服务状态,直到就绪 const checkServiceStatus = async () => { const serviceReady = await isServiceUp(); if (serviceReady) { $("#loader").fadeOut(1000); $("#content").fadeIn(1000); } else { // 未就绪则1秒后再次检测 setTimeout(checkServiceStatus, 1000); } }; // 启动检测 checkServiceStatus(); });
调整CSS样式(可选)
为了确保初始状态正确,可给content添加默认隐藏的样式:
#content { display: none; } .loader { /* 这里添加你的预加载动画样式,比如旋转的圆圈 */ position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 50px; height: 50px; border: 5px solid #f3f3f3; border-top: 5px solid #3498db; border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
内容的提问来源于stack exchange,提问作者Victoria
相关产品推荐
相关产品推荐

