如何让Safari预加载JS/CSS资源?Chrome/Firefox可正常实现
问题
我一直尝试让Safari在页面加载过程中预加载资源,但始终无法实现,而Chrome和Firefox却能正常做到。
测试场景如下:通过脚本渲染如下HTML,中间会暂停2秒,且响应的第一部分已刷新并传输至浏览器(这一点已通过Chrome和Firefox能提前获取JS文件得到验证)。
<!DOCTYPE html> <html lang="en"> <head> <link rel="preload" href="http://localhost:8888/js.js" as="script" /> <script href="http://localhost:8888/js.js"/> </head> <!-- 此处渲染HTML的脚本会暂停2秒后再渲染文档剩余部分 --> <!-- 响应的第一部分已刷新并发送至浏览器 --> <body> </body> </html>
获取JS文件时也添加了2秒延迟,便于在浏览器时间线中可视化观察。
注意:即使没有<link preload>标签,Chrome和Firefox也会提前加载JS,它们会在接收到部分HTML后立即开始解析,并下载遇到的JS文件。Firefox和Chrome的加载瀑布流显示它们能提前加载JS,但Safari的加载瀑布流却显示其不会异步加载脚本,而是等待完整的HTML响应接收完毕后才开始加载。
请问我忽略了什么?Safari完全不支持资源预加载吗?
分析与解决
Safari并非完全不支持资源预加载,你的问题主要出在两个关键点:
- Script标签写法错误
你使用的<script href="http://localhost:8888/js.js"/>存在两处错误:
- script标签不能自闭合,必须写成
<script src="http://localhost:8888/js.js"></script>的完整形式; - 脚本文件的引用属性是
src而非href。
这个语法错误会导致Safari无法正确识别该脚本资源,自然不会触发提前加载。
- Safari的渐进式解析策略差异
Chrome和Firefox的HTML解析器会在接收到部分HTML内容时就启动解析,提前处理资源请求;但Safari的解析器默认会等待完整的<head>标签闭合后,才开始处理其中的preload和script标签——尤其是在分块传输(chunked)的响应场景下,即使你提前发送了的部分内容,Safari也会等待的结束标记才开始处理资源。
额外优化建议
- 修正script标签写法后重新测试;
- 确保服务器启用分块编码(
Transfer-Encoding: chunked),并尽早刷新缓冲区发送部分内容; - 可以配合
<link rel="preconnect" href="http://localhost:8888">预连接到资源服务器,进一步提升资源加载优先级。
内容的提问来源于stack exchange,提问作者Khepin
相关产品推荐
相关产品推荐

