0

0

未来CSS文件加载方式_html/css_WEB-ITnose

php中文网

php中文网

发布时间:2016-06-24 11:26:32

|

1152人浏览过

|

来源于php中文网

原创

Chrome打算改变 的加载方式,当 link 出现在

中时,就变得非常明显了。在blink-dev的文章中,它的影响和性能尚不明确,所以我想在这里深入讲讲。

当前加载CSS的方法

<head>  <link rel="stylesheet" href="/all-of-my-styles.css"></head><body>  …content…</body>

CSS会阻塞渲染,用户需要等待 all-of-my-styles.css 整个加载完,否则屏幕一直是白色的。

一个网站的CSS样式分成一个两个文件存放是非常正常的,也就是说用户必须额外加载一大堆的并不会应用于当前页面的样式规则。因为网站会包含很多类型的页面,其中包含的“组件”也非常多,在组件级别整理CSS文件的话,对于HTTP/1协议会影响性能。

立即学习前端免费学习笔记(深入)”;

对于SPDY和HTTP/2来说则并非如此,许多小规模的资源可以以较小的开销生成,以及独立缓存。

<head>  <link rel="stylesheet" href="/site-header.css">  <link rel="stylesheet" href="/article.css">  <link rel="stylesheet" href="/comment.css">  <link rel="stylesheet" href="/about-me.css">  <link rel="stylesheet" href="/site-footer.css"></head><body>  …content…</body>

这解决了冗余加载的问题,但意味着你需要先知道:当你输出

时,页面将包含什么内容,可以防止streaming。另外,浏览器在渲染页面内容之前,还是需要先下载所有的CSS文件。一个 loading /site-footer.css 文件的缓慢加载,就可以导致页面所有内容的渲染延迟。

查看DEMO

当前加载CSS最先进的方式

<head>  <script>    // https://github.com/filamentgroup/loadCSS    !function(e){"use strict"    var n=function(n,t,o){function i(e){return f.body?e():void setTimeout(function(){i(e)})}var d,r,a,l,f=e.document,s=f.createElement("link"),u=o||"all"    return t?d=t:(r=(f.body||f.getElementsByTagName("head")[0]).childNodes,d=r[r.length-1]),a=f.styleSheets,s.rel="stylesheet",s.href=n,s.media="only x",i(function(){d.parentNode.insertBefore(s,t?d:d.nextSibling)}),l=function(e){for(var n=s.href,t=a.length;t--;)if(a[t].href===n)return e()    setTimeout(function(){l(e)})},s.addEventListener&&s.addEventListener("load",function(){this.media=u}),s.onloadcssdefined=l,l(function(){s.media!==u&&(s.media=u)}),s}    "undefined"!=typeof exports?exports.loadCSS=n:e.loadCSS=n}("undefined"!=typeof global?global:this)  </script>  <style>    /* The styles for the site header, plus: */    .main-article,    .comments,    .about-me,    footer {      display: none;    }  </style>  <script>    loadCSS("/the-rest-of-the-styles.css");  </script></head><body></body>

上面的代码中,有一些内联样式使得我们可以进行快速的初始渲染,然后隐藏我们还没有加载样式的内容,接着使用JavaScript异步加载剩下的CSS。剩下加载的CSS会重写 .main-article 中的 display: none 。

这种方法是 性能方面 的 专家 建议 的,以获得快速的初始渲染,也不无道理:

查看DEMO

在现实世界中,我做了这个 wiki-offline ,是有效果的 :

在3g网络中,初始渲染快了0.6秒。完整的结果 前 对比结果 后 对比。

但也有一些不足:

它需要一个(小)JavaScript库

不幸的是,这是由于WebKit的实现情况。一旦页面加了 ,WebKit会阻塞渲染,直到样式表加载完成,即使是通过JavaScript加载样式表。

在Firefox和IE/Edge中,通过JS加载样式表是完全异步的。稳定版的Chrome目前还是WebKit的方式,但在Chrome的Canary版本中,我们切换成了和Firefox/Edge一样的方式。

你被限制在两个阶段加载

在上面的模式中,内联CSS使用 display:none 隐藏没有样式的内容,然后异步加载CSS来解决。如果你的CSS文件多于两个或者更多,它们可能不会按照顺序加载,这会导致加载过程中内容错乱:

查看DEMO

内容错乱,还带有 弹出式广告 ,是非常糟糕的用户体验。

因为你被限制了只能在两个阶段加载,你必须选择第一次渲染加载什么,然后再加载什么。你当然希望“显眼”的内容被快速渲染,但是“页面排版”是依赖于窗口的。相当艰难,你必须选择一个适合所有情况的解决方案。

Flowith
Flowith

一款GPT4驱动的节点式 AI 创作工具

下载

更新:如果你想要让事情变得复杂,你可以使用CSS自定义属性建立一个类似渲染依赖树的东西,这里有一篇使用自定义属性控制CSS加载的 文章 。

一种更简单更好的方法

<head></head><body>  <!-- HTTP/2 push this resource, or inline it, whichever's faster -->  <link rel="stylesheet" href="/site-header.css">  <header>…</header>  <link rel="stylesheet" href="/article.css">  <main>…</main>  <link rel="stylesheet" href="/comment.css">  <section class="comments">…</section>  <link rel="stylesheet" href="/about-me.css">  <section class="about-me">…</section>  <link rel="stylesheet" href="/site-footer.css">  <footer>…</footer></body>

这个方法是,对于每个 ,加载样式表时,阻塞渲染其后续内容,但允许在它之前的内容先渲染。样式表是并行加载的,但是按照顺序应用。这样 也变得和 <script src="%E2%80%A6"></script> 有点像了。

我们来看看如果上面这个网站的标题header,正文内容article和footer,这些内容的CSS先加载,然后其它的挂起,页面结果会如何:

  • 标题:渲染
  • 正文:渲染
  • 评论:没有渲染,它前面的CSS还没有加载( /comment.css )
  • 关于我:没有渲染,它前面的CSS还没有加载( /comment.css )
  • Footer:没有渲染,它前面的CSS还没有加载( /comment.css ),尽管它本身的CSS已经加载,但是被阻塞了

这是一个顺序渲染的页面。你不需要决定什么内容是“明显位置”,只需要在页面组件实例化之前引入该组件的CSS即可。它完全兼容streaming,因为你不需要输出 ,直到你需要它。

当使用内容决定布局的布局系统(如表格和flexbox)时,你需要注意避免加载过程中内容错位。这并不是新出现的问题,但渐进式渲染会导致这个问题更频繁地暴露。你可以hack flexbox来解决,但是CSS grid对于整体页面布局是 更好的系统 (flexbox对于较小组件依旧是非常棒的)。

Chrome的改变

HTML规范 没有包含页面被CSS阻塞时如何渲染,它不鼓励在 body 中写 ,但是所有的浏览器都允许这一写法。当然,浏览器都有自己解决 body 中的 link 的方式。

  • Chrome & Safari :一旦发现 ,立刻停止渲染,直到所有已发现的样式表都加载完成再继续渲染。这通常会导致 前面尚未渲染的内容也被阻塞。
  • Firefox : head 中的 会阻塞渲染,直到所有已发现的样式表加载。body中的 不会阻塞渲染,除非 head 中的样式表已经阻塞渲染。这会导致页面无样式内容闪烁(FOUC)。
  • IE/Edge :阻塞解析器直到样式表加载完成,但允许 前面的内容渲染。

在Chrome,我们也喜欢IE/Edge的行为,所以我们将向它看齐。也就是上面描述的CSS渐进式渲染的模式。我们正努力把它变为标准,从允许

中加入 开始。

目前,Chrome/Safari的行为是向下兼容,它只会阻塞它需要的渲染时间更长。Firefox的行为稍微复杂,但有一个解决方法...

Firefixing

因为Firefox并不经常因为 body 中的 link 阻塞渲染,我们需要解决它以避免FOUC。值得庆幸的是,这并不难,因为 <script> 可以阻塞解析, 这样就可以等待挂起的样式表加载完成: </script>

<link rel="stylesheet" href="/article.css"><script> </script><main>…</main>

该脚本元素必须是非空的,放个空格就好了。

看看实际的应用情况

查看DEMO

Firefox和Edge/IE会给你一个可爱的渐进式渲染,而Chrome和Safari在所有CSS加载完成之前都是无样式的白色屏幕。目前Chrome/Safari并不比你把所有的样式表放在

中更糟糕,所以你现在可以开始使用这个方法。在接下来的几个月里,Chrome将迁移到Edge模型,用户将得到更快的渲染。

所以我们可以尝试了!一个更简单的只需加载你需要的CSS的方法,然后得到一个更快的渲染的过程。

感谢 @lukedjn 、Paul Lewis和Domenic Denicola的改正建议。特别感谢Boris Zbarsky帮我理解了Firefox的行为。还有Paul想出的“Firefixing”的技巧。

本文根据 @Jake 的《 The future of loading CSS 》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处: https://jakearchibald.com/2016/link-in-body/ 。

彦子

在校学生,本科计算机专业。逗比一枚,热爱前端热爱生活,喜欢CSS喜欢JavaScript喜欢SVG,爱玩PS玩AI玩啊逗比的软件。努力向上,厚积薄发。

相关文章

HTML速学教程(入门课程)
HTML速学教程(入门课程)

HTML怎么学习?HTML怎么入门?HTML在哪学?HTML怎么学才快?不用担心,这里为大家提供了HTML速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

5

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

12

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

33

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

25

2026.03.03

Golang 测试体系与代码质量保障:工程级可靠性建设
Golang 测试体系与代码质量保障:工程级可靠性建设

Go语言测试体系与代码质量保障聚焦于构建工程级可靠性系统。本专题深入解析Go的测试工具链(如go test)、单元测试、集成测试及端到端测试实践,结合代码覆盖率分析、静态代码扫描(如go vet)和动态分析工具,建立全链路质量监控机制。通过自动化测试框架、持续集成(CI)流水线配置及代码审查规范,实现测试用例管理、缺陷追踪与质量门禁控制,确保代码健壮性与可维护性,为高可靠性工程系统提供质量保障。

77

2026.02.28

Golang 工程化架构设计:可维护与可演进系统构建
Golang 工程化架构设计:可维护与可演进系统构建

Go语言工程化架构设计专注于构建高可维护性、可演进的企业级系统。本专题深入探讨Go项目的目录结构设计、模块划分、依赖管理等核心架构原则,涵盖微服务架构、领域驱动设计(DDD)在Go中的实践应用。通过实战案例解析接口抽象、错误处理、配置管理、日志监控等关键工程化技术,帮助开发者掌握构建稳定、可扩展Go应用的最佳实践方法。

60

2026.02.28

Golang 性能分析与运行时机制:构建高性能程序
Golang 性能分析与运行时机制:构建高性能程序

Go语言以其高效的并发模型和优异的性能表现广泛应用于高并发、高性能场景。其运行时机制包括 Goroutine 调度、内存管理、垃圾回收等方面,深入理解这些机制有助于编写更高效稳定的程序。本专题将系统讲解 Golang 的性能分析工具使用、常见性能瓶颈定位及优化策略,并结合实际案例剖析 Go 程序的运行时行为,帮助开发者掌握构建高性能应用的关键技能。

48

2026.02.28

Golang 并发编程模型与工程实践:从语言特性到系统性能
Golang 并发编程模型与工程实践:从语言特性到系统性能

本专题系统讲解 Golang 并发编程模型,从语言级特性出发,深入理解 goroutine、channel 与调度机制。结合工程实践,分析并发设计模式、性能瓶颈与资源控制策略,帮助将并发能力有效转化为稳定、可扩展的系统性能优势。

26

2026.02.27

Golang 高级特性与最佳实践:提升代码艺术
Golang 高级特性与最佳实践:提升代码艺术

本专题深入剖析 Golang 的高级特性与工程级最佳实践,涵盖并发模型、内存管理、接口设计与错误处理策略。通过真实场景与代码对比,引导从“可运行”走向“高质量”,帮助构建高性能、可扩展、易维护的优雅 Go 代码体系。

20

2026.02.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Css3入门视频教程
Css3入门视频教程

共21课时 | 3.9万人学习

CSS3进阶视频教程
CSS3进阶视频教程

共11课时 | 2.5万人学习

燕十八mongodb视频教程
燕十八mongodb视频教程

共15课时 | 4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号