关于 Angular SSR 的 inlineCriticalCss 属性

举报
汪子熙 发表于 2025/04/03 23:26:16 2025/04/03
【摘要】 inlineCriticalCss 是 Angular Universal 提供的一个功能,主要用于优化网页的首屏加载速度。它的作用是将页面的关键 CSS 提取出来并内联到 HTML 中,这样可以在页面首次加载时就直接应用这些 CSS 样式,而无需等待外部样式文件的完全加载。这种方式可以有效减少首屏加载的阻塞,提升网页的显示速度和用户体验。 什么是 Critical CSSCritical ...

inlineCriticalCss 是 Angular Universal 提供的一个功能,主要用于优化网页的首屏加载速度。它的作用是将页面的关键 CSS 提取出来并内联到 HTML 中,这样可以在页面首次加载时就直接应用这些 CSS 样式,而无需等待外部样式文件的完全加载。这种方式可以有效减少首屏加载的阻塞,提升网页的显示速度和用户体验。

什么是 Critical CSS

Critical CSS 是一种 Web 性能优化技术,目标是尽可能快地渲染网页首屏所需的最小化样式,而把其余的非关键 CSS 延迟加载。通常在加载一个网页时,浏览器会阻塞页面的渲染,直到它下载并解析所有的 CSS 样式。这意味着如果 CSS 文件过大或者加载过慢,就会影响用户看到首屏内容的时间。

通过将关键 CSS 内联到 HTML 中,浏览器在渲染页面时无需等待整个 CSS 文件的加载,从而可以极大地加快页面的渲染速度,特别是对于内容丰富的应用,这种技术尤为重要。

Angular 中的 inlineCriticalCss

在 Angular Universal 中,inlineCriticalCssCommonEngineRenderOptions 的一个配置选项,用来控制是否将关键 CSS 提取并内联到页面 HTML 中。它的默认值为 true,这意味着当启用 Angular Universal 进行服务端渲染时,默认情况下会进行关键 CSS 的提取和内联。

const options: CommonEngineRenderOptions = {
  document: indexHtml,
  url: req.url,
  bootstrap: AppServerModule,
  inlineCriticalCss: true, // 启用关键 CSS 的内联
};

inlineCriticalCss 的使用场合

inlineCriticalCss 适用于想要加速首屏加载的网站和应用,尤其是在网络环境不佳的情况下,它能够显著减少首屏的加载时间。这对以下场景尤为有用:

  • SEO 优化:页面渲染速度直接影响 SEO 排名,尤其是对于搜索引擎抓取页面时,如果页面渲染时间过长,搜索引擎可能会认为页面质量不高,进而影响排名。使用 inlineCriticalCss 可以让页面的首屏加载更加迅速,从而改善搜索引擎抓取体验。
  • 移动设备用户体验优化:移动设备的网络速度普遍慢于桌面设备,通过将关键 CSS 内联,移动设备用户可以更快看到页面内容,这样可以显著改善用户体验。
  • 首次内容绘制优化 (FCP):内联关键 CSS 帮助优化首屏的内容绘制时间,使得用户在较短时间内看到主要内容,减少由于白屏时间过长导致的用户流失。

inlineCriticalCss 的具体作用

启用 inlineCriticalCss 后,Angular Universal 会在渲染过程中分析页面的 CSS,找到对首屏渲染至关重要的部分并将其内联到页面 HTML 中。这样,浏览器在加载 HTML 时可以直接应用这些 CSS,从而更快地渲染页面,而不用等待外部 CSS 文件的加载和解析。

内联后的 CSS 通常被直接嵌入到 HTML 文档的 <head> 部分,使得浏览器在遇到这些样式时可以立即应用。

工作原理

内联关键 CSS 的过程大致如下:

  1. 分析 CSS:渲染引擎在服务端渲染页面时,会分析页面中所有的 CSS 文件,确定哪些样式是页面首次绘制时必须的(例如涉及页面布局、字体样式等的 CSS)。
  2. 提取和内联:将这些关键 CSS 提取出来并直接内联到 HTML 的 <head> 中,使得浏览器在解析 HTML 时可以立即获取并应用这些样式。
  3. 异步加载非关键 CSS:其余的非关键 CSS 会被以异步的方式加载,从而不会阻塞页面的渲染。

通过这种方式,inlineCriticalCss 能够显著加快页面的首次内容绘制时间,提高用户体验,特别是在网络带宽有限或设备性能较低的场景中效果尤为明显。

真实世界的例子

为了更好地理解 inlineCriticalCss 的作用,我们来看一个实际的案例。

案例:优化在线新闻门户网站的性能

假设你在为一个在线新闻门户网站工作,这个网站的用户覆盖了全球,其中很多用户来自于网络条件较差的地区。首页通常包括大量的图文内容,如果完全依赖客户端加载和渲染,页面初次加载时可能会出现长时间的白屏现象,这对用户体验影响很大。

你决定使用 Angular Universal 来提升首屏的渲染速度,并启用了 inlineCriticalCss,以下是这个过程的效果对比:

  • 未使用 inlineCriticalCss 的情况

    • 浏览器请求 HTML 文档,收到服务器返回的页面内容。
    • 浏览器开始解析 HTML,并在遇到 <link rel="stylesheet" href="styles.css"> 时,阻塞页面渲染,等待外部样式文件的加载和解析。
    • 由于 styles.css 较大,且用户网络环境差,整个加载和解析过程耗时较长,导致用户长时间看到的是白屏,页面的首次内容绘制时间(FCP)很长。
  • 使用 inlineCriticalCss 的情况

    • 浏览器请求 HTML,收到服务器返回的页面内容。
    • 此时 HTML 的 <head> 中已经包含了内联的关键 CSS,这些样式用于页面的基础布局和首屏内容的样式。
    • 浏览器解析 HTML 时能够立即应用这些内联的 CSS,从而在极短时间内完成页面的首次内容绘制,让用户迅速看到页面的主内容。
    • 其余的非关键样式通过异步方式加载,并在加载完成后逐步应用,从而不会影响首屏渲染速度。

通过这种方式,可以极大提升网站首页的加载性能和用户体验。特别是在网络条件较差的地区,使用 inlineCriticalCss 可以帮助用户在几秒钟内看到有内容的页面,而不是漫长的白屏等待。

inlineCriticalCss 的代码示例

下面给出一个简单的代码示例,演示如何使用 inlineCriticalCss 来实现关键 CSS 的内联。

import { CommonEngine, CommonEngineRenderOptions } from '@angular/platform-server';
import { AppServerModule } from './src/main.server';
import * as express from 'express';
import { join } from 'path';

const app = express();
const distFolder = join(process.cwd(), 'dist/your-app/browser');
const indexHtml = join(distFolder, 'index.html');

const engine = new CommonEngine();

app.get('*', (req, res) => {
  const options: CommonEngineRenderOptions = {
    document: indexHtml,
    url: req.url,
    bootstrap: AppServerModule,
    inlineCriticalCss: true, // 内联关键 CSS
  };

  engine.render(options).then(html => {
    res.status(200).send(html);
  }).catch(err => {
    res.status(500).send(`渲染出错: ${err.message}`);
  });
});

在这个示例中,通过设置 inlineCriticalCss: trueCommonEngine 会在渲染时自动提取页面的关键 CSS 并将其内联到 HTML 中,从而加快首屏内容的渲染速度。

inlineCriticalCss 的优势与挑战

优势

  1. 减少首屏渲染时间
    通过内联关键 CSS,用户可以更快地看到页面的内容,因为浏览器在渲染时无需等待整个样式表的加载。

  2. 提升用户体验
    内联关键 CSS 后,页面可以在用户第一次请求时迅速加载出重要内容,从而减少用户等待的时间,提高对网站的满意度。

  3. SEO 友好
    搜索引擎爬虫通常会受到页面渲染速度的影响。内联关键 CSS 可以确保搜索引擎在抓取页面时能够看到快速渲染的内容,这对 SEO 有很大帮助。

  4. 改善低带宽设备的表现
    在移动设备或低速网络环境下,内联关键 CSS 能够显著提升用户的页面加载体验,让页面的内容更早呈现给用户。

挑战

  1. 复杂度增加
    提取关键 CSS 并进行内联虽然能够提升页面加载性能,但也会使得构建过程更加复杂,特别是在管理复杂的样式系统时,确定哪些样式是“关键”的并不总是容易的。

  2. 可能导致 HTML 文件过大
    如果关键 CSS 过多,内联后可能会导致 HTML 文件变得较大,这会增加初次加载的 HTML 体积,反而可能在某些情况下影响加载性能。因此需要对关键 CSS 进行合理的控制,尽量保证它只包含最小的必要样式。

  3. 开发工具链的配置复杂度
    内联 CSS 涉及到构建工具和渲染引擎的额外配置,特别是在一些较为定制化的应用中,开发者可能需要手动调优内联的 CSS 量和其他性能选项,增加了开发的复杂度。

进一步优化的思考

对于启用了 inlineCriticalCss 的应用,还可以结合其他性能优化手段以进一步提高页面的加载速度。例如:

  • Lazy Loading (惰性加载)
    将非关键的 CSS 文件进行惰性加载,使得这些资源不会阻塞页面的渲染。可以通过 JavaScript 动态加载这些非关键样式,在用户需要时再进行加载。

  • 代码拆分与优化
    在 Angular 中使用 ng build --prod 可以进行代码拆分和压缩,生成的 CSS 文件通常也会被拆分为较小的部分,可以结合 inlineCriticalCss 将最重要的部分内联,其余部分通过异步方式加载,进一步提升页面性能。

  • 使用 Web Vitals 指标监控效果
    为了确保 inlineCriticalCss 实际提升了页面加载速度,可以通过 Google 提供的 Web Vitals 指标来监控页面的首屏加载时间、交互延迟等数据,从而持续进行优化。


通过对 inlineCriticalCss 的深入理解及其具体的应用场景分析,我们可以看到它在提升 Angular 应用性能方面的显著效果。尤其是在面向终端用户的项目中,使用内联关键 CSS 是改善用户体验、提升页面渲染速度的有效手段之一。虽然其配置和管理需要一些额外的投入,但带来的性能收益往往是值得的。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。