压缩CSS有助于提高网站性能。但是作为开发者,我们真的不再讨论压缩CSS了。 为什么?
简而言之,现代技术栈已经改进了CSS的传输和优化,使其实际上不再是一个问题。HTTP/2和现代压缩算法在很大程度上解决了CSS的高效和性能传输问题,而现代前端框架则负责处理诸如代码分割和压缩之类的枯燥优化工作。过去,设置一个新的前端项目需要花费数小时来令人沮丧地手动配置Grunt文件或Gulp文件来编译、压缩和后处理CSS文件。
为什么你应该压缩CSS文件
CSS中的压缩是删除所有不必要的空白,使文件体积更小,但浏览器仍然可以理解的过程。 简而言之,压缩你的CSS有助于优化你的首次内容绘制(FCP)。
FCP是一个核心Web指标,用于衡量网页的感知加载速度,它标志着在页面加载期间用户可以在屏幕上看到任何内容的第一点。良好的FCP得分以1.8秒或更少来衡量,并向用户保证“正在加载某些内容”,以便他们不会反弹。为了确保良好的FCP得分,你的样式表或内联CSS应该尽可能小(即压缩和压缩),以便它们下载时间更短,可以更快地被处理,允许浏览器更快地在页面上绘制内容。上述所有内容也有助于优化关键渲染路径(浏览器将HTML、CSS和JavaScript转换为屏幕上像素的步骤)。这对于有较慢互联网速度的用户尤其重要。
此外,CSS是一个渲染阻塞资源,这意味着浏览器在下载CSS并结合DOM(文档对象模型)构建CSSOM(CSS对象模型)之前不会显示任何内容。这是有意义的;大多数现代网页没有CSS就无法正确工作。此外,如果CSS在HTML在页面上呈现后加载并应用,用户在CSS规则应用之前会经历未样式内容的闪烁(FOUC)。在加载后对内容进行样式设置和排列也可能会对您的CLS得分产生负面影响(我们已经有足够的CLS要担心字体、图片和其他意外问题!)。在页面的<head>
标签中以样式表和内联CSS形式提供的CSS都是渲染阻塞的。
CSS压缩工具
有许多工具可用于开发中或作为构建管道的一部分压缩CSS,包括但不限于cssnano和Vite。如果你使用sass,只需在sass
命令中添加--style=compressed
即可。你获得的结果可能会根据你的CSS复杂性而变化,但你可能会看到类似于此的数字(用sass处理):
原始 (kB) | 压缩后 (kB) | 节省 (kB) |
---|---|---|
78 | 65 | 13 |
然而,有趣的是,这些数字适用于存储在磁盘上的文件。从服务器交付的文件实际上会更小。这就是压缩的用处。
现代HTTP压缩算法
HTTP压缩由Web服务器和客户端(浏览器)使用,以提高资源传输速度,并有助于节省带宽成本和开销。有许多压缩算法可用,但并非所有算法都得到现代浏览器的支持。
服务器可能支持多种压缩类型,目前网络上最常用的压缩类型是gzip和Brotli。在进行HTTP请求时,浏览器会告诉服务器它们能够解码的压缩方法,服务器随后发送适当压缩的文件版本。不支持可用压缩方法的浏览器将接收未压缩的数据。虽然在2024年发送和接收未压缩数据可能并不常见,但对于使用较旧或更小众设备且不接收自动软件更新的人来说,这一点值得注意。
你可以在浏览器开发工具中检查网络请求的HTTP请求和响应头,以了解更多上述内容。这是一个例子:
请求头(发送到服务器):
Accept-Encoding
列出了客户端/浏览器支持的压缩方法
响应头(从服务器接收):
Content-Encoding
描述了用于解码传输数据的压缩方法Content-Length
提供压缩文件的字节大小
如果你使用Sentry性能来监控你的应用程序,你还可以检查每个网络请求的响应头在相关span中。
有趣的是,未压缩压缩文件和压缩文件之间的大小差异并不那么显著。以我个人网站的CSS文件为例,节省了只有1kB。
原始 (kB) | 压缩后 (kB) | 节省 (kB) | |
---|---|---|---|
磁盘上 | 78 | 65 | 13 |
压缩后 | 11 | 10 | 1 |
虽然1kB看起来不多,但从更大的范围来看,节省肯定会对你和你的用户提供好处。截至2024年3月,全球移动设备的互联网速度中位数为52.98Mbps。虽然这相当于每秒可以下载6625kB(在这里计算并四舍五入到53Mbps),如果你可以从每个页面加载的100个资源中减少1kB,那么对于这些用户,你的页面速度可以提高15ms:
在6.625 kB/ms传输速度下,传输100kB需要多长时间?
6625kB/s传输
6625 ÷ 1000 = 6.625 kB/ms传输
100 kB ÷ 6.625 kB/ms = 15ms*
*
_这是一个非常基本的计算,没有考虑TCP慢启动或任何其他影响数据传输的网络效应,但它仍然作为一个例子。
同时,你将作为开发者或组织节省带宽成本。虽然1kB的节省对于单个用户来说并不多,对于1000个用户来说,这相当于传输了1MB更少的数据。
HTTP/2多路复用
可能意味着CSS压缩不再那么重要的另一个进步是HTTP/2。自2015年发布并逐渐采用以来,HTTP/2允许服务器使用单个连接并行传输多个请求和响应(多路复用)。为了利用这一点,前端打包工具和框架提供了“代码分割”或“块”更大的CSS文件和JavaScript包,以便同时传输更小的文件,而底层技术将这些文件组合在客户端以使网页正确工作。
如果一个未压缩的压缩CSS文件只有10kB,然后分成大约2kB的更小块,那么压缩就变得有点无关紧要了。此外,许多现代前端框架已经为我们处理了这个问题。
前端框架中的CSS压缩和代码分割
如果你使用现代前端框架,你通常会得到CSS压缩和/或代码分割。框架为CSS后处理提供了自己的意见化(但合理的)默认配置,如果你愿意,你可以选择进一步优化这些选项。此外,通过从现代托管平台和CDN提供你的网站和应用程序,你将无需考虑就能从HTTP/2、缓存和压缩中受益。
以下是现代基于JavaScript的框架如何处理CSS的一些例子。
Astro
Astro自动压缩并合并你的CSS到块中,并进一步优化页面之间共享的CSS以重用。Astro的另一个优化是它“内联”任何小于4kB大小的CSS块(即在页面的<head>
中的<style>
标签中放置CSS),以防止对小样式表进行太多网络请求。这提供了“额外请求数量和可以缓存在页面之间的CSS体积之间的平衡”。
Next.js
Next.js带有一系列预配置优化,用于使用CSS模块、Tailwind、Sass和CSS-in-JS。例如,当使用CSS模块时,许多较小的文件将自动捆绑成较少的压缩代码分割CSS文件,以减少网络请求的数量。
Nuxt
Nuxt带有postcss
和一系列预配置的CSS压缩和优化插件,包括postcss-import
、postcss-url
、autoprefixer
和cssnano
。
SvelteKit
SvelteKit使用Vite作为底层构建和捆绑项目的工具。这带有可配置的CSS代码分割和压缩。
在Astro内联所有小于4kB大小的CSS文件的地方,SvelteKit带有inlineStyleThreshold配置,允许你明确指定要内联的CSS文件的最大长度(以UTF-16代码单元为单位)。所有页面所需的CSS,且小于这个值的CSS,都将被合并并内联在一个<style>
块中。
Angular
Angular的构建过程带有--optimization
标志,该标志启用CSS压缩和关键CSS的内联。为了节省更多的字节,你还可以选择在构建期间使用removeSpecialComments
标志来删除CSS和其他多余字符的注释。
结论
有了现代Web托管平台和CDN缓存和快速向全球用户交付文件的便利,强大的压缩算法和HTTP/2的广泛采用,我想我们不再真的需要考虑CSS压缩了。它通常在我们现代前端工具中被处理——尽管是以意见化的方式。话虽如此,作为前端开发者,我们理解CSS是如何在我们的应用程序中被传递到浏览器的,以便监控它对我们生产中应用程序性能的影响,这是非常重要的。
是的,这些现代框架为我们做了很多。但我们能做得更多吗?