一个网页为什么会打开很慢?

一个网页为什么会打开很慢?

建立连接之后,浏览器会发送 HTTP 请求。

现在轮到服务器处理这个请求。

对于一个简单的静态 HTML 文件,这个过程可能非常快。

但对于一个动态应用,服务器可能需要:

验证用户身份

执行应用代码

查询数据库

调用其他服务

访问缓存

生成 HTML

执行服务端渲染

如果这些操作总共花费了 800 毫秒,浏览器也没有太多办法。

浏览器正在等待响应的第一个字节。

这也是 Time to First Byte (TTFB)成为 Web 性能重要指标的原因之一。

TTFB 包含网络耗时,以及服务器开始生成响应所需要的时间,因此较高的 TTFB 并不一定完全由后端处理造成。

一个缓慢的后端会延迟后面发生的一切。

因此,前端性能优化不能只关注 Java 和 CSS。生成初始 HTML 所需要的时间同样重要。

3. HTML 只是开始

最终,浏览器收到了 HTML。

但收到 HTML 并不意味着页面已经准备好了。

浏览器开始解析文档并构建 DOM。

例如:

Helloh1>

>

body>

在解析 HTML 的过程中,浏览器会发现其他资源。

它可能需要下载:

CSS 文件

Java 文件

图片

字体

视频

API 数据

第三方脚本

这会形成一个资源依赖关系图。

HTML 本身可能很小,但它描述的页面可能需要几十甚至几百个额外资源。

MDN 将 Resource Timing 描述为一种查看这些单独资源详细时间信息的方式,包括 DNS 查询、请求、响应以及传输时间。

所以,当一个页面感觉很慢时,问题并不只是:

HTML 有多大?

更值得问的问题是:

HTML 会让浏览器下载和执行什么?

浏览器性能中一个非常重要的概念是 Critical Rendering Path。

浏览器需要构建足够的信息,才能确定屏幕上应该显示什么。

CSS 在这里发挥着重要作用。

浏览器会根据样式表构建 CSSOM,并将它与 DOM 结合起来创建 Render Tree。

CSS 通常会阻塞渲染,因为浏览器不希望在页面明显没有样式的情况下直接显示页面。

对于应用于当前媒体类型的外部样式表来说,一个很大或者加载缓慢的 stylesheet 因此可能延迟渲染。

这也是 Web 性能指南建议减少关键 CSS 数量,并避免让不必要的 CSS 进入初始渲染路径的原因。

重要的一点是,文件大小只是问题的一部分。

一个资源出现在哪里,以及浏览器是否认为它属于关键资源,同样可能很重要。

5. Java 可能让浏览器无法继续向前解析

Java 是另一个重要的延迟来源。

例如,一个传统的 :

>

可能会阻塞 HTML parser。

为什么?

因为 Java 可以修改 DOM 和 CSSOM。

当浏览器遇到这个 时,它不能简单地认为 后面的 HTML 与这段代码没有关系。

它可能需要先下载并执行这个 ,然后才能继续解析。

这可能形成这样的链路:

HTML

↓

发现 Java

↓

下载 Java

↓

执行 Java

↓

继续解析 HTML

↓

渲染

对于大型应用来说,这可能带来比较大的开销。

可以使用下面这样的机制进行改善:

>

或者:

>

defer和 async的执行语义不同,因此不能把它们当成完全一样的东西。

具体来说,deferred s 会在文档解析完成之后,并按照文档中的顺序执行;asynchronous s 会在下载完成后立即执行,因此执行顺序可能不同。Module s 默认具有 deferred 的行为。

6. 下载 Java 只是问题的一半

一个常见的误区是看到一个 Java bundle,然后认为:

只有 500 KB,这并不算大。

但下载文件只是成本的一部分。

浏览器还可能需要:

下载它

解析它

编译它

执行它

更新 DOM

重新计算样式

执行 layout

绘制结果

因此,大型 Java 应用可能会消耗大量 main thread 时间。

当 main thread 忙于执行 long tasks 时,渲染和用户交互也可能被延迟。

对于 client-side rendered applications 来说,这一点尤其重要。

web.dev 指出,如果完全通过 Java 渲染关键内容,可能会延迟重要资源的发现,并形成更长的关键请求链。

所以,即使网络速度很好,一个页面仍然可能感觉很慢,因为浏览器正在执行太多 Java 工作。

7. 图片可能成为最大的资源

图片通常是网页中体积最大的资源之一。

一张 hero image 可能就有几 MB。

如果浏览器需要下载一张很大的图片,页面的主要内容才能在视觉上完整显示,那么这张图片就可能对用户感知到的性能产生很大影响。

这与 Largest Contentful Paint (LCP)尤其相关。

LCP 衡量的是视口内最大的图片或文本块被渲染出来的时间。Google 建议,对于至少 75% 的页面访问,LCP 应该达到 2.5 秒或更短。

在某些情况下,重要图片的网络优先级可能比预期更低。因此,开发者可以使用 fetchpriority="high",向浏览器提供提高关键资源优先级的提示。

不过,fetchpriority只是给浏览器的提示,并不能保证该资源一定会最先加载。

因此,图片优化仍然很重要。

常见的方法包括:

使用尺寸合适的图片

使用现代图片格式

使用 responsive images

对首屏以下的图片进行 lazy loading

提高重要图片的优先级

避免下载不必要的图片

对于重要的 LCP 图片来说,降低它的网络优先级实际上可能让情况变得更糟。

8. 字体可能延迟用户看到的内容

Web fonts 是另一个很容易被忽略的资源。

页面可能有这样的代码:

@font-face{

font-family: "MyFont";

src: url("my-font.woff2");

}

现在,浏览器可能需要先获取字体,才能使用这个字体显示文字,具体取决于字体加载行为。

因此,即使 HTML 和 CSS 已经到达,页面在视觉上仍然可能没有完全显示。

字体也会与其他资源竞争网络带宽。

因此,字体加载应该被视为页面资源策略的一部分,而不仅仅是一个设计问题。

9. 第三方脚本可能悄悄让情况变得更糟

现代网站很少只依赖自己的代码。

一个页面可能加载:

analytics

advertising

social widgets

customer support tools

A/B testing frameworks

tracking systems

video players

recommendation engines

每一个第三方依赖都可能引入额外的网络请求和 Java 执行。

它还可能消耗网络带宽和 main thread 时间,在某些情况下还会延迟其他重要工作。

更麻烦的是,页面通常无法控制第三方服务器响应的速度。

因此,如果一个小型脚本位于关键路径上,也可能产生出乎意料的性能成本。

所以,只有真正需要的时候才应该加载第三方资源,而非关键脚本通常应该避免进入初始渲染路径。

10. 浏览器仍然需要完成渲染

最终,浏览器拥有了足够的信息,可以开始渲染页面。

但渲染本身也需要进行大量工作。

一个简化后的过程如下:

HTML

↓

DOM CSS

↓ ↓

CSSOM

↓

Render Tree

↓

Layout

↓

Paint

↓

Composite

↓

Pixels on Screen

浏览器在处理 HTML 和 CSS 的过程中构建 DOM 和 CSSOM。当所需的信息准备完成之后,浏览器就可以构建 Render Tree。

然后,浏览器会计算样式,确定元素的大小和位置,绘制像素,并合成各个图层。

如果页面包含非常大的 DOM,或者复杂的样式,这些操作可能会变得很昂贵。

Java 如果不断修改 DOM,也会让情况变得更糟,因为这可能触发额外的样式计算或 layout 工作。

因此,即使所有资源都已经下载完成,浏览器仍然可能有大量工作需要处理。

11. 页面在技术上已经加载完成,但用户仍然觉得很慢

这是一个非常重要的区别。

浏览器可以完成 document 的加载,但用户仍然可能觉得页面很慢。

例如:

HTML loaded

↓

Java executing

↓

API request

↓

data arrives

↓

DOM updated

↓

layout

↓

paint

↓

page becomes useful

传统的 load事件并不一定代表页面已经到了对用户有用的时刻。

因此,现代性能分析更加关注以用户为中心的指标。

例如:

LCP— 主要内容什么时候变得可见

CLS— 页面布局发生了多少意外偏移

INP— 页面对用户交互的响应速度

一个页面即使很快触发了 load,如果主要内容出现得很晚,或者 main thread 一直处于阻塞状态,用户体验仍然可能很差。

12. 如何找到真正的性能瓶颈?

性能优化的第一条原则很简单:

先测量,再优化。

浏览器本身已经提供了大量性能信息。

例如:

performance.getEntriesByType("navigation");

可以提供 navigation timing 信息。

而:

performance.getEntriesByType("resource");

可以提供单个资源的 timing 信息。

对于跨域资源,如果服务器没有提供适当的 Timing-Allow-Origin响应头,详细的 timing 信息可能会受到限制。

这些 API 可以帮助回答下面这些问题:

DNS 花了多长时间?

服务器响应花了多长时间?

哪个资源最大?

哪个 下载时间最长?

哪个请求启动得太晚?

请求是不是太多?

Java 是否占用了太多 main thread 时间?

MDN 将 Navigation Timing 和 Resource Timing 描述为分析主文档以及该文档加载资源的互补方式。

浏览器 DevTools 中的 Network 面板在这里特别有用。

Waterfall 视图通常可以很快暴露问题。

你可能会看到类似这样的情况:

HTML ███████

CSS █████████

JS █████████████

Image ███████████

API ███████

重要的问题并不只是哪个资源最大。

真正值得问的是:

哪个资源正在延迟用户需要的东西?

考虑这样一个简化示例:

DNS 100 ms

TCP + TLS 150 ms

Server processing 400 ms

HTML transfer 100 ms

CSS 300 ms

Java 500 ms

LCP image 700 ms

Rendering 250 ms

--------------------------------

Total 2500 ms

其中没有任何一个数字看起来特别严重。

但它们加在一起,就形成了一个需要 2.5 秒才能完成视觉呈现的页面。

这也是为什么 Web 性能从根本上来说与 critical path有关。

如果某件事情并不需要在用户看到页面或与页面交互之前完成,那么理想情况下,就应该把它移出这条 critical path。

14. 那么,一个网页为什么会慢?

当一个页面需要很长时间才能打开时,根本原因通常可以归结到下面一个或多个方面:

Network

DNS、连接建立、TLS、网络延迟、丢包或者带宽不足。

Server

后端处理缓慢、数据库查询、API 依赖或者缓存不合理。

Resources

HTML、CSS、Java、图片、字体体积过大,以及请求过多。

Critical Rendering Path

Render-blocking CSS 或 parser-blocking Java 延迟首次渲染。

Java

Bundle 过大、解析和执行成本高、long tasks,或者过多的 DOM 操作。

Rendering

DOM 树过大、样式计算成本高、layout 工作以及 paint。

Third Parties

Analytics、advertising、tracking、widgets 以及其他外部依赖。

Resource Prioritization

浏览器发现重要资源太晚,或者给重要资源分配的优先级太低。

重要的是,“页面很慢”并不是一个诊断结果。

它只是一个现象。

真正应该问的问题是:

浏览器的时间到底花在哪里?

一旦能够通过测量回答这个问题,性能优化就会变得更加系统。

总结

从用户的角度来看,打开一个网页似乎很简单。

输入 URL。

等待。

看到页面。

但在浏览器内部,其实发生了一长串操作:

URL

↓

DNS

↓

TCP / TLS

↓

HTTP Request

↓

Server

↓

HTML

↓

DOM + CSSOM

↓

Java

↓

Layout

↓

Paint

↓

Composite

↓

Pixels

其中任何一个重要环节出现延迟,都可能影响最终体验。

所以,前端性能并不只是“让 Java 更小”或者“压缩图片”。

真正的目标,是减少 critical path 上的工作,让重要资源尽可能早地可用,并避免让 main thread 把时间花在用户暂时不需要的工作上。

理解了这条加载链路之后,一个缓慢的网页就不再那么神秘。

你可以打开 DevTools,看 Waterfall,检查 Performance 时间线,然后问一个更有价值的问题:

到底是哪一步让用户一直在等?返回搜狐,查看更多

相关推荐

建行龙卡信用卡取现方法
365bet官网开户

建行龙卡信用卡取现方法

📅 06-27 👁️ 258
微星笔记本403如何满足你的需求
365bet体坛即时比分

微星笔记本403如何满足你的需求

📅 01-15 👁️ 4522
excel图片工具栏在哪里(Excel图片工具栏在哪里找)
365bet体坛即时比分

excel图片工具栏在哪里(Excel图片工具栏在哪里找)

📅 11-11 👁️ 8934
7X24小时严酷环境下也能无忧存储?西部数据紫盘实测小记!
比特小队官方版
365bet官网开户

比特小队官方版

📅 09-27 👁️ 7443
微博怎么发微博故事,掌握这几个简单步骤让你轻松上手!