如何确保脚本执行完成后再触发页面渲染(防止 RAF 提前执行)

落丽吖_7300

落丽吖_7300

2026-07-05

425人浏览

原创

如何确保脚本执行完成后再触发页面渲染(防止 RAF 提前执行)

本文详解浏览器中脚本执行与渲染的时序关系,阐明为何 requestAnimationFrame 可能早于 执行触发,并提供通过 blocking="render"、脚本位置控制及现代加载策略实现渲染阻塞的可靠方案。

本文详解浏览器中脚本执行与渲染的时序关系,阐明为何 `requestanimationframe` 可能早于 `<script>` 执行触发,并提供通过 `blocking="render"`、脚本位置控制及现代加载策略实现渲染阻塞的可靠方案。</script>

在构建高性能、无闪烁的 Web 应用时,一个常被忽视却至关重要的细节是:脚本执行与页面渲染的执行顺序并非绝对确定。尽管 JavaScript 是单线程的,但浏览器的渲染流程(包括样式计算、布局、绘制)与 JS 执行共享事件循环,而 requestAnimationFrame(RAF)回调被调度在「下一个帧的渲染前」——这恰恰发生在浏览器决定是否需要重绘的临界点。若脚本尚未执行完毕,DOM 状态可能未就绪,此时 RAF 触发便可能导致读取未挂载元素、样式未生效或 UI 闪动。

? 根本原因:Parser-blocking ≠ Render-blocking

  • Parser-blocking(解析阻塞):默认 <script>(尤其外部脚本)会暂停 HTML 解析器,确保 DOM 构建按序进行。例如:</script>

    <script src="data:text/javascript,console.log(document.body.children.length);"></script><div>content</div>

    此处 console.log 输出为 0,因为

    尚未被解析——这是 parser-blocking 的典型表现。
  • Render-blocking(渲染阻塞):但 parser-blocking 并不自动等同于 render-blocking。只有当脚本位于

    中时,主流浏览器(Chrome、Safari)才会将其视为 render-blocking —— 即强制延迟首次渲染(paint),直到该脚本执行完毕。而放在 底部的脚本,虽阻塞解析,却不阻塞渲染队列,因此 RAF 可能抢在脚本执行前被调用。
  • 可通过 iframe 演示验证(规避 StackBlitz 环境限制):

    AI Cheat Check
    AI Cheat Check

    AI Cheat Check是一款面向学校和机构的 AI 生成文本检测工具。

    下载
    <iframe srcdoc="
      <html><head>
        <script>requestAnimationFrame(() => parent.postMessage(['RAF'], '*'));</script>
        <script>parent.postMessage(['SCRIPT EXECUTED'], '*');</script>
      </head><body><h1>HELLO</h1></body>
    </html>">
    </iframe>

    在 Chrome 中,控制台稳定输出:

    SCRIPT EXECUTED
    RAF

    证明

    内脚本实现了 render-blocking;若将第二个

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
AngularJS教程
AngularJS教程

共24课时 | 7.6万人学习

VBScript教程
VBScript教程

共10课时 | 10.4万人学习