我该以编程方式内联所有CSS文件以优化页面加载速度吗?

53

Google PageSpeed通常建议优化CSS传递。我想到如果像这样内联所有CSS,它将减少网络往返次数:

<style type="text/css">

    @{ 
        var bootstrap = File.ReadAllText(Server.MapPath("bootstrap.min.css"));
        var bootstrapTheme = File.ReadAllText(Server.MapPath("theme.min.css"));
        var fontAwesome = File.ReadAllText(Server.MapPath("font-awesome.min.css"));
        var bigfont = File.ReadAllText(Server.MapPath("bigfont.min.css"));
        var bigfontPrint = File.ReadAllText(Server.MapPath("bigfont-print.min.css"));
    }

    @Html.Raw(bootstrap)
    @Html.Raw(bootstrapTheme)
    @Html.Raw(fontAwesome)
    @Html.Raw(bigfont)
    @Html.Raw(bigfontPrint)

</style>

这似乎是解决页面加载缓慢问题的一个合理方案,并且将我的PageSpeed分数从88提高到了95。

暂时不考虑代码样式,如果有的话,有哪些技术原因不能以这种方式内联所有CSS?


2
好的,这就是为什么我加了免责声明的原因。我以为你在谈论将所有CSS作为字符串添加到C#程序中,因为那是一个标签,而我在这方面完全无知。糟糕?我相信理解你所说的内容的人会有更好的答案。 - D. Ben Knoble
3
有趣的问题。JS 也可以这样做,对吧?@BenKnoble, 他是在说CSS是以编程方式内联的,所以你仍然可以以同样的方式编辑资源文件。 - Orun
2
@OrunBhuiyan 是的。这就是我所想的。它为我的页面加载做得非常出色。我的移动端和桌面端都达到了99/100。 - Shaun Luttin
4
所以PageSpeed忽略了你在页面中塞入几百千字节的CSS的事实。奇怪。 - Salman A
6
这似乎是个不好的主意。CSS永远不会被缓存。此外,在内容之前塞入额外的kB数据肯定会使页面加载变慢。你可以说link也会这样做,但是link可能会被某些供应商异步加载链接的文件。而将CSS内容塞入HTML页面中则无法实现这一点。脚本标签最后才会被委派执行的原因是有道理的 - 同样的逻辑也适用于所有内容。 - Dan
显示剩余6条评论
4个回答

75
将所有CSS内联化意味着无法缓存,因此每个页面加载都包含所需的所有CSS,当您使用大型库时,这可能会浪费大量带宽。例如,Bootstrap约为120k。请注意,您分享的Google链接指定了以下内容(重点是我自己加的):

如果外部CSS资源很小,您可以将它们直接插入HTML文档中,这称为内联。

因此,单个页面加载可能更快,但总体上可能会变慢。
就我个人而言,我会避免这样做。不过,您可以将所有CSS捆绑成一个请求(您正在使用MVC,所以相对简单),因此您只需要为CSS进行一次额外的服务器请求,浏览器请求的所有未来页面都不需要再次请求。

2
按照这个逻辑,它根本不会缓存CSS。 - Martheen
4
和任何指标一样,了解其缺点非常重要。对于网页速度测试,我倾向于使用http://www.webpagetest.org/,因为它运行的测试更符合"真实世界"的情况。 - DavidG
2
一旦实现了其“捆绑”功能的良好支持,就可以使用HTML/2。 - 小太郎
9
好的,我会尽力进行翻译。您需要我将以下内容翻译成中文:“@ 小太郎, you mean HTTP 2”。我会尽力使翻译通顺易懂,但不会改变原意或添加解释。 - ysdx
4
值得记住的是,通常情况下,随着项目的推进,事物往往会变得越来越大,而不是越来越小。令人遗憾的是,原先只有5行CSS的东西更常见地会变成50行,而不是原先50行变成5行。因此,可以假设许多小代码将变成大代码(因此应该成为单独的资源),或者至少要留意它们增长的时机,考虑是否应该将它们移动。 - Jon Hanna
显示剩余6条评论

17
没有人提到这种技术的预期用途,它绝对不是为了加载你100%的css。相反,这种技术的目的是让用户认为页面已经加载得更快了。
当我们讨论让页面加载更快时,真正的目标通常是让页面的加载看起来更快。从用户体验的角度来看,这比实际上减少加载时间要重要得多。如果整个页面需要500毫秒才能加载完成,那并不重要,因为人类无法在那么短的时间内解析它。重要的是页面加载的速度。
因此,这种技术的适当使用方法是立即加载绝对必要的css,以使页面正确呈现。也就是说,有一些css规则可以使图像大小正确,正确地浮动,避免页面内容在Facebook SDK完成其业务时在页面上跳来跳去的恶劣外观。那些代码需要与标记同时存在。解决方案:内联关键css。
但绝对不要内联所有的css。如果该css仅对异步加载的内容进行样式设置,则可以稍后再加载另外100kb的css。但如果有页面结构必须在25ms后呈现正确的形式,则应内联该css。

11
您误解了PageSpeed的建议。该建议是针对小型CSS文件的:
如果外部CSS资源很小,可以直接将其插入到HTML文档中,这称为内嵌。但请记住,如果CSS文件很大,则完全内嵌CSS可能会导致PageSpeed Insights通过优化可见内容警告您的页面上方折叠部分太大。
事实上,该文章后面还提出了一种针对大型CSS文件的平衡方法:内联关键CSS并推迟加载剩余的CSS文件。
即使在内联大型CSS文件后,PageSpeed给出了一个不错的得分,这仍然可能不是一个好主意:
冗余性:
内联CSS文件意味着您在页面之间重复使用< style >… < /style >标签。这意味着您为后续或重复页面查看提供了冗余数据。冗余数据会增加带宽成本并增加下载时间。
独立的CSS文件以及强缓存头文件可以让您消除冗余数据。缓存头文件指示浏览器在第一次页面查看时缓存CSS文件并在后续或重复页面查看时重用。
内容与数据:
内联CSS文件减少了页面上“实际”内容的比例。 内联CSS文件要求您将CSS插入内容之上,而我们大多数人都努力将实际内容放在HTML的顶部。
内联CSS还会导致浏览器在允许下载其他资源(例如JavaScript和图像)之前下载额外的字节。
压缩成本:
如果您的HTML页面是动态生成的,则很可能会以未压缩的形式提供。一些服务器(例如IIS)和软件(例如WordPress)允许压缩动态内容,但与压缩静态内容(例如CSS文件)相比需要更多的CPU +内存。这是为什么您应该将CSS保留在单独的文件中的另一个原因。
基于以上原因,即使对于仅有一个页面的网站,我仍然会将我的CSS组合,缩小,压缩并缓存到单独的文件中。

* 不要将其与内联样式混淆


5

这段内容太长了,无法适应评论区。在我的工作场所中,我们使用内容安全策略头部指令(具体为style-src),明确禁止使用内联CSS。在这种情况下不使用内联CSS的理由是最小化动态创建页面的CSS注入风险。OWASP有关于此主题的详细信息,包括攻击样本:https://www.owasp.org/index.php/Testing_for_CSS_Injection_(OTG-CLIENT-005)。如果只提供静态内容给浏览器,则不应存在风险。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接