<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>脚本加载 on ZiYang FrontEnd Interview</title><link>https://fe-interview.pangcy.cn/tags/%E8%84%9A%E6%9C%AC%E5%8A%A0%E8%BD%BD/</link><description>Recent content in 脚本加载 on ZiYang FrontEnd Interview</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Thu, 06 Mar 2025 13:07:39 +0800</lastBuildDate><atom:link href="https://fe-interview.pangcy.cn/tags/%E8%84%9A%E6%9C%AC%E5%8A%A0%E8%BD%BD/index.xml" rel="self" type="application/rss+xml"/><item><title>script标签加载策略</title><link>https://fe-interview.pangcy.cn/docs/html/html-04/</link><pubDate>Tue, 04 Mar 2025 06:58:29 +0000</pubDate><guid>https://fe-interview.pangcy.cn/docs/html/html-04/</guid><description>&lt;h2 id="考察点分析">考察点分析 &lt;a href="#%e8%80%83%e5%af%9f%e7%82%b9%e5%88%86%e6%9e%90" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h2>&lt;p>本题主要考察以下核心能力维度：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>浏览器渲染机制&lt;/strong>：理解脚本加载对文档解析的影响&lt;/li>
&lt;li>&lt;strong>性能优化认知&lt;/strong>：不同加载策略对首屏时间/LCP指标的影响&lt;/li>
&lt;li>&lt;strong>工程化思维&lt;/strong>：根据业务场景选择最佳加载方案&lt;/li>
&lt;/ol>
&lt;p>具体技术评估点：&lt;/p>
&lt;ul>
&lt;li>脚本下载与文档解析的阻塞关系&lt;/li>
&lt;li>执行时机对DOMContentLoaded事件的影响&lt;/li>
&lt;li>多脚本场景下的执行顺序控制&lt;/li>
&lt;li>网络条件与脚本依赖关系的协同处理&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="技术解析">技术解析 &lt;a href="#%e6%8a%80%e6%9c%af%e8%a7%a3%e6%9e%90" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h2>&lt;h3 id="关键知识点优先级">关键知识点优先级 &lt;a href="#%e5%85%b3%e9%94%ae%e7%9f%a5%e8%af%86%e7%82%b9%e4%bc%98%e5%85%88%e7%ba%a7" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h3>&lt;ol>
&lt;li>渲染阻塞机制 &amp;gt; 执行时序控制 &amp;gt; 依赖管理&lt;/li>
&lt;/ol>
&lt;h3 id="原理剖析">原理剖析 &lt;a href="#%e5%8e%9f%e7%90%86%e5%89%96%e6%9e%90" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h3>&lt;p>浏览器解析HTML时，默认同步加载脚本会触发：&lt;/p>
&lt;ol>
&lt;li>停止文档解析&lt;/li>
&lt;li>下载脚本（同步阻塞）&lt;/li>
&lt;li>立即执行脚本&lt;/li>
&lt;li>恢复文档解析&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>async脚本&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>异步下载（不阻塞解析）&lt;/li>
&lt;li>下载完成后&lt;strong>立即执行&lt;/strong>（可能中断文档解析）&lt;/li>
&lt;li>执行顺序不保证（先下载完的先执行）&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>defer脚本&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>异步下载（不阻塞解析）&lt;/li>
&lt;li>在DOMContentLoaded事件&lt;strong>前顺序执行&lt;/strong>&lt;/li>
&lt;li>严格保持脚本声明顺序&lt;/li>
&lt;/ul>
&lt;h3 id="常见误区">常见误区 &lt;a href="#%e5%b8%b8%e8%a7%81%e8%af%af%e5%8c%ba" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h3>&lt;ol>
&lt;li>认为async/defer都能完全避免渲染阻塞（async执行仍可能阻塞）&lt;/li>
&lt;li>混淆执行顺序（async不保序，defer保序）&lt;/li>
&lt;li>忽视DOMContentLoaded事件触发时机&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="问题解答">问题解答 &lt;a href="#%e9%97%ae%e9%a2%98%e8%a7%a3%e7%ad%94" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h2>&lt;p>&lt;strong>执行差异对比表&lt;/strong>：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>特性&lt;/th>
 &lt;th>默认&lt;/th>
 &lt;th>async&lt;/th>
 &lt;th>defer&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>阻塞解析&lt;/td>
 &lt;td>是&lt;/td>
 &lt;td>否&lt;/td>
 &lt;td>否&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>执行时机&lt;/td>
 &lt;td>立即&lt;/td>
 &lt;td>下载完&lt;/td>
 &lt;td>文档解析后&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>顺序保证&lt;/td>
 &lt;td>N/A&lt;/td>
 &lt;td>不保证&lt;/td>
 &lt;td>声明顺序&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>最佳实践&lt;/strong>：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>关键渲染路径脚本&lt;/strong>：使用&lt;code>defer&lt;/code>保持执行顺序，避免阻塞首屏渲染&lt;/li>
&lt;li>&lt;strong>独立第三方库&lt;/strong>（如统计代码）：使用&lt;code>async&lt;/code>实现非阻塞加载&lt;/li>
&lt;li>&lt;strong>强依赖DOM的脚本&lt;/strong>：必须用&lt;code>defer&lt;/code>或放在body末尾&lt;/li>
&lt;li>&lt;strong>现代模块化方案&lt;/strong>：使用&lt;code>type=&amp;quot;module&amp;quot;&lt;/code>（默认defer行为）&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="解决方案">解决方案 &lt;a href="#%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h2>&lt;h3 id="代码示例">代码示例 &lt;a href="#%e4%bb%a3%e7%a0%81%e7%a4%ba%e4%be%8b" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h3>


 
 
 

 
 
 
 

 

 &lt;div class="prism-codeblock ">
 &lt;pre id="b1f3493" class="language-html ">
 &lt;code>&amp;lt;!-- 关键业务逻辑：保证顺序且不阻塞 --&amp;gt;
&amp;lt;script defer src=&amp;#34;app.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;

&amp;lt;!-- 独立SDK：尽快执行不阻塞 --&amp;gt;
&amp;lt;script async src=&amp;#34;analytics.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;

&amp;lt;!-- 内联脚本需后置 --&amp;gt;
&amp;lt;script&amp;gt;
document.addEventListener(&amp;#39;DOMContentLoaded&amp;#39;, () =&amp;gt; {
 // 安全操作DOM
})
&amp;lt;/script&amp;gt;&lt;/code>
 &lt;/pre>
 &lt;/div>
&lt;h3 id="可扩展性建议">可扩展性建议 &lt;a href="#%e5%8f%af%e6%89%a9%e5%b1%95%e6%80%a7%e5%bb%ba%e8%ae%ae" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h3>&lt;ol>
&lt;li>&lt;strong>大流量场景&lt;/strong>：配合preload实现优先级控制&lt;/li>
&lt;/ol>



 
 
 

 
 
 
 

 

 &lt;div class="prism-codeblock ">
 &lt;pre id="a7a762d" class="language-html ">
 &lt;code>&amp;lt;link rel=&amp;#34;preload&amp;#34; href=&amp;#34;critical.js&amp;#34; as=&amp;#34;script&amp;#34;&amp;gt;&lt;/code>
 &lt;/pre>
 &lt;/div>
&lt;ol start="2">
&lt;li>&lt;strong>低端设备&lt;/strong>：动态注入脚本控制超时&lt;/li>
&lt;/ol>



 
 
 

 
 
 
 

 

 &lt;div class="prism-codeblock ">
 &lt;pre id="55ae860" class="language-javascript ">
 &lt;code>const script = document.createElement(&amp;#39;script&amp;#39;);
script.src = &amp;#39;heavy.js&amp;#39;;
script.onerror = handleFailure;
document.body.appendChild(script);&lt;/code>
 &lt;/pre>
 &lt;/div>
&lt;hr>
&lt;h2 id="深度追问">深度追问 &lt;a href="#%e6%b7%b1%e5%ba%a6%e8%bf%bd%e9%97%ae" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h2>&lt;ol>
&lt;li>
&lt;p>&lt;strong>如何预加载async脚本但不立即执行？&lt;/strong>
使用&lt;code>&amp;lt;link rel=&amp;quot;preload&amp;quot;&amp;gt;&lt;/code>配合&lt;code>async&lt;/code>属性&lt;/p></description></item></channel></rss>