跳到主要内容

资源加载✅

浏览器同一时间可以从一个域名下载多少资源,有什么例外吗?

答案

参考 stackoverflow Max parallel HTTP connections in a browser?

浏览器HTTP/1.1 每域名连接数明
Chrome6
Firefox6
Safari6
Edge6 基于Chromium
IE118 已停止支持
提示

注意这里是针对 HTTP/1.1 协议的限制。HTTP/2 和 HTTP/3 通过多路复用技术可以在单个连接上并行处理多个请求,因此不受此限制。具体参考 Why just one TCP connection

HTTP/1.1 限制原因

  • 服务器负载保护 防止单个客户端占用过多服务器连接
  • 网络拥塞控制 避免过多并发连接导致网络堵塞
  • TCP 连接开销 每个连接都需要三次握手,资源消耗较大

重要例外情况

<!-- 1. 不同子域名可以突破限制 -->
<link rel="stylesheet" href="https://cdn1.example.com/style.css">
<link rel="stylesheet" href="https://cdn2.example.com/theme.css">
<script src="https://static.example.com/app.js"></script>

<!-- 2. HTTP/2 多路复用 -->
<!-- 同一连接可并行传输多个资源 -->
<link rel="preload" href="/critical.css" as="style">
<link rel="preload" href="/main.js" as="script">

<!-- 3. 内联资源不占用连接 -->
<style>
.critical { color: red; }
</style>
<script>
console.log('inline script');
</script>

实际开发优化策略

  • 域名分片 HTTP/1.1 时代通过多个子域名提高并发数
  • 资源合并 减少请求数量,如 CSS/JS 文件合并
  • HTTP/2 升级 利用多路复用特性,避免域名分片反优化
  • 资源优先级 使用 <link rel="preload"> 控制关键资源加载

延伸阅读

CSS 加载是否阻塞 DOM 解析、渲染和 JavaScript 执行?

答案

详细解释

阻塞对象是否阻塞原因说明
DOM 解析不阻塞HTML 解析不依赖 CSS 属于流式解析
页面渲染阻塞渲染依赖 CSSOM 构建,会造成阻塞,注意如果资源加载失败浏览器任然会用兜底的样式进行渲染,这个现象叫做 内容样式短暂失效 (FOUC)
JavaScript 执行阻塞<script> 标签会等待 CSS 加载完成
<!DOCTYPE html>
<html>
  <head>
    <title>CSS 阻塞验证测试</title>
    <style>
      body {
        font-family: Arial;
      }
      .test-box {
        width: 200px;
        height: 100px;
        background: red;
        margin: 10px 0;
      }
      .log {
        background: #f0f0f0;
        padding: 10px;
        margin: 5px 0;
        border-left: 3px solid #333;
      }
    </style>

    <!-- 模拟慢加载的 CSS -->
    <link rel="stylesheet" href="https://httpbin.org/delay/3" />

    <script>
      // 记录脚本开始执行时间
      const scriptStartTime = performance.now();
      console.log("1. Script in <head> 开始执行:", scriptStartTime);
      const domElements = document.querySelectorAll("*");
      console.log("2. DOM 元素数量:", domElements.length);
      console.log("3. body 元素是否存在:", !!document.body);
    </script>
  </head>
  <body>
    <h1>CSS 阻塞测试</h1>
    <div class="test-box">测试盒子</div>

    <div class="log">
      <strong>观察现象:</strong>
      <ul>
        <li>页面内容会延迟显示(等待 CSS 加载)</li>
        <li>但 DOM 结构已经解析完成</li>
        <li>控制台会显示执行顺序</li>
      </ul>
    </div>

    <script>
      // 尝试获取样式(会等待 CSS 加载)
      if (document.body) {
        const bodyStyle = getComputedStyle(document.body);
        console.log("4. body 字体:", bodyStyle.fontFamily);
      }
      // 验证 DOM 解析不被阻塞
      console.log("5. Body 中的 script 执行时间:", performance.now());
      console.log(
        "6. 此时 DOM 已解析,元素数量:",
        document.querySelectorAll("*").length
      );

      // 监听页面加载完成
      window.addEventListener("load", () => {
        console.log("7. 页面完全加载完成(包括 CSS)");
      });

      // 监听 DOMContentLoaded
      document.addEventListener("DOMContentLoaded", () => {
        console.log("8. DOMContentLoaded 触发");
      });
    </script>

    <script>
      // 更详细的测试:CSS 加载状态检测
      function checkCSSLoaded() {
        const links = document.getElementsByTagName("link");
        for (let link of links) {
          if (link.rel === "stylesheet") {
            console.log("CSS 链接状态:", {
              href: link.href,
              loaded: link.sheet !== null,
            });
          }
        }
      }

      // 定期检查 CSS 加载状态
      const checkInterval = setInterval(() => {
        checkCSSLoaded();

        // 如果所有 CSS 都加载完成,停止检查
        const allLoaded = Array.from(document.getElementsByTagName("link"))
          .filter((link) => link.rel === "stylesheet")
          .every((link) => link.sheet !== null);

        if (allLoaded) {
          console.log("9. 所有 CSS 加载完成,脚本继续执行");
          clearInterval(checkInterval);
        }
      }, 100);
    </script>

  </body>
</html>

实际开发建议

  1. 关键 css 内联导入
  2. 非关键 CSS 异步加载 <link rel="preload" href="non-critical.css" as="style" onload="this.onload=null;this.rel='stylesheet'">

延伸阅读

什么是文档的预解析

答案

文档预解析用来解决关键资源串行加载导致的页面渲染延迟,通过预加载技术,实现对核心资源的并行加载,提升页面加载速度。

预加载包含如下类型

类型描述
dns-prefetch浏览器提前解析域名,减少后续请求的 DNS 查询延迟。通过 <link rel="dns-prefetch"> 标签实现。
preconnect浏览器提前建立与服务器的连接,以减少后续请求的延迟。通过 <link rel="preconnect"> 标签实现。
preload浏览器在解析 HTML 时,提前加载指定资源(如脚本、样式表、图片等),以便在需要时可以立即使用。通过 <link rel="preload"> 标签实现。
prefetch浏览器在空闲时加载可能会用到的资源,以便在需要时可以立即使用。通过 <link rel="prefetch"> 标签实现。

延伸阅读

你如何对网站的文件和资源进行优化?

答案

网站文件和资源优化是前端性能优化的核心,主要从减少请求数量、优化文件大小、加速传输和提升缓存效率四个维度进行。

资源压缩与合并

优化类型具体措施工具示例
JavaScript代码压缩、Tree Shaking、代码分割Webpack、Rollup、Terser
CSS压缩、去重、关键CSS提取PurgeCSS、PostCSS、Critical
HTML压缩空格、注释删除HTMLMinifier
图片格式优化、尺寸压缩、懒加载WebP、AVIF、ImageOptim

HTTP 优化策略

<!-- 1. 资源预加载 -->
<link rel="dns-prefetch" href="//cdn.example.com">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preload" href="/critical.css" as="style">
<link rel="prefetch" href="/next-page.js">

<!-- 2. 关键资源优先加载 -->
<style>
/* 关键CSS内联 */
.header { background: #000; }
</style>
<link rel="stylesheet" href="/non-critical.css" media="print"
onload="this.media='all'">

<!-- 3. 脚本优化加载 -->
<script src="/critical.js"></script>
<script src="/non-critical.js" defer></script>
<script src="/analytics.js" async></script>

缓存策略配置

// Service Worker 缓存策略
self.addEventListener('fetch', event => {
if (event.request.destination === 'image') {
// 图片缓存优先策略
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request)
})
)
}
})

// Webpack 文件名哈希
module.exports = {
output: {
filename: '[name].[contenthash].js',
chunkFilename: '[name].[contenthash].chunk.js'
}
}

现代优化技术

  • HTTP/2 推送 主动推送关键资源,减少往返时间
  • 模块联邦 微前端架构下的资源共享
  • ESM 动态导入 按需加载模块,减少初始包体积
  • WebAssembly 计算密集型任务性能优化
// 动态导入示例
const loadChart = async () => {
const { Chart } = await import('./chart.js')
return new Chart()
}

// 图片懒加载
const imageObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target
img.src = img.dataset.src
imageObserver.unobserve(img)
}
})
})

实际开发建议

  • 资源监控 使用 Lighthouse、WebPageTest 定期检测性能
  • 渐进式优化 优先优化影响 FCP、LCP 的关键资源
  • CDN 部署 静态资源使用 CDN 加速全球访问
  • 构建优化 配置合理的 chunk splitting 策略
提示

优化顺序:关键资源内联 → 非关键资源延迟 → 长期缓存策略 → 监控调优

延伸阅读

48%