关于 Angular SSR 的 inlineCriticalCss 属性
inlineCriticalCss
是 Angular Universal 提供的一个功能,主要用于优化网页的首屏加载速度。它的作用是将页面的关键 CSS 提取出来并内联到 HTML 中,这样可以在页面首次加载时就直接应用这些 CSS 样式,而无需等待外部样式文件的完全加载。这种方式可以有效减少首屏加载的阻塞,提升网页的显示速度和用户体验。
什么是 Critical CSS
Critical CSS 是一种 Web 性能优化技术,目标是尽可能快地渲染网页首屏所需的最小化样式,而把其余的非关键 CSS 延迟加载。通常在加载一个网页时,浏览器会阻塞页面的渲染,直到它下载并解析所有的 CSS 样式。这意味着如果 CSS 文件过大或者加载过慢,就会影响用户看到首屏内容的时间。
通过将关键 CSS 内联到 HTML 中,浏览器在渲染页面时无需等待整个 CSS 文件的加载,从而可以极大地加快页面的渲染速度,特别是对于内容丰富的应用,这种技术尤为重要。
Angular 中的 inlineCriticalCss
在 Angular Universal 中,inlineCriticalCss
是 CommonEngineRenderOptions
的一个配置选项,用来控制是否将关键 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 的过程大致如下:
- 分析 CSS:渲染引擎在服务端渲染页面时,会分析页面中所有的 CSS 文件,确定哪些样式是页面首次绘制时必须的(例如涉及页面布局、字体样式等的 CSS)。
- 提取和内联:将这些关键 CSS 提取出来并直接内联到 HTML 的
<head>
中,使得浏览器在解析 HTML 时可以立即获取并应用这些样式。 - 异步加载非关键 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: true
,CommonEngine
会在渲染时自动提取页面的关键 CSS 并将其内联到 HTML 中,从而加快首屏内容的渲染速度。
inlineCriticalCss 的优势与挑战
优势
-
减少首屏渲染时间:
通过内联关键 CSS,用户可以更快地看到页面的内容,因为浏览器在渲染时无需等待整个样式表的加载。 -
提升用户体验:
内联关键 CSS 后,页面可以在用户第一次请求时迅速加载出重要内容,从而减少用户等待的时间,提高对网站的满意度。 -
SEO 友好:
搜索引擎爬虫通常会受到页面渲染速度的影响。内联关键 CSS 可以确保搜索引擎在抓取页面时能够看到快速渲染的内容,这对 SEO 有很大帮助。 -
改善低带宽设备的表现:
在移动设备或低速网络环境下,内联关键 CSS 能够显著提升用户的页面加载体验,让页面的内容更早呈现给用户。
挑战
-
复杂度增加:
提取关键 CSS 并进行内联虽然能够提升页面加载性能,但也会使得构建过程更加复杂,特别是在管理复杂的样式系统时,确定哪些样式是“关键”的并不总是容易的。 -
可能导致 HTML 文件过大:
如果关键 CSS 过多,内联后可能会导致 HTML 文件变得较大,这会增加初次加载的 HTML 体积,反而可能在某些情况下影响加载性能。因此需要对关键 CSS 进行合理的控制,尽量保证它只包含最小的必要样式。 -
开发工具链的配置复杂度:
内联 CSS 涉及到构建工具和渲染引擎的额外配置,特别是在一些较为定制化的应用中,开发者可能需要手动调优内联的 CSS 量和其他性能选项,增加了开发的复杂度。
进一步优化的思考
对于启用了 inlineCriticalCss
的应用,还可以结合其他性能优化手段以进一步提高页面的加载速度。例如:
-
Lazy Loading (惰性加载):
将非关键的 CSS 文件进行惰性加载,使得这些资源不会阻塞页面的渲染。可以通过 JavaScript 动态加载这些非关键样式,在用户需要时再进行加载。 -
代码拆分与优化:
在 Angular 中使用ng build --prod
可以进行代码拆分和压缩,生成的 CSS 文件通常也会被拆分为较小的部分,可以结合inlineCriticalCss
将最重要的部分内联,其余部分通过异步方式加载,进一步提升页面性能。 -
使用 Web Vitals 指标监控效果:
为了确保inlineCriticalCss
实际提升了页面加载速度,可以通过 Google 提供的 Web Vitals 指标来监控页面的首屏加载时间、交互延迟等数据,从而持续进行优化。
通过对 inlineCriticalCss
的深入理解及其具体的应用场景分析,我们可以看到它在提升 Angular 应用性能方面的显著效果。尤其是在面向终端用户的项目中,使用内联关键 CSS 是改善用户体验、提升页面渲染速度的有效手段之一。虽然其配置和管理需要一些额外的投入,但带来的性能收益往往是值得的。
- 点赞
- 收藏
- 关注作者
评论(0)