资讯专栏INFORMATION COLUMN

CSS 加载新方式

wthee / 1599人阅读

摘要:二目前最先进的加载方法在上面的代码中,通过一些内联样式我们可以加速初始渲染,同时隐藏起还没有加载完样式的组件,并通过异步地完成加载。

Chrome 浏览器有意改变的加载方式,当其出现在中时,这一变化将更加明显。笔者决定在本文中进行详细说明这种改变可能带来影响与好处。

一.目前CSS文件的加载方式

  


  …content…

CSS 会阻碍渲染,因此在all-of-my-styles.css全部加载完之前,用户就只能面对一片空白的屏幕。

通常,我们将某个站点的所有 CSS 样式合并为一到两个资源,这意味着用户会下载一堆当前页面根本就用不上的规则。这是因为网站可能包含许多不同类型的页面,每个页面都有自己的「组件」;而在组件级别传递 CSS 的话,会降低 HTTP/1 的性能。

然而,对 SPDY 和 HTTP/2 来说,事实却并非如此。在这些协议中,许多小资源只需要很小的代价就能完成递送,并且被独立缓存。


  
  
  
  
  


  …content…

这样一来就解决了冗余问题,但也意味着你需要知道输出时页面将包含的内容,从而防止 streaming。与此同时,浏览器还是只能等待所有 CSS 样式加载完毕,才能开始渲染。如果加载 /site-footer.css的速度不够快,就会耽误所有页面的渲染。

二.目前最先进的 CSS 加载方法

  
  
  



在上面的代码中,通过一些内联样式我们可以加速初始渲染,同时隐藏起还没有加载完样式的组件,并通过 JavaScript 异步地完成加载。剩余的 CSS 加载完后会重写.main-article中的display:none

这个方法受到性能专家的推崇,他们认为这是快速完成初始渲染的好方法,并且经过实地测量确实在加载的时候快了不少。

但也存在一些不足之处。。。。。。

「1.它需要一个(小的)JavaScript 库」

这是由 WebKit 的实现方式造成的。一旦页面中添加了,即使样式表是由 JavaScript 加载的,WebKit 还是会在加载完成之前阻碍渲染。

在 Firefox 和 IE/Edge 浏览器中,通过 JS 加载样式表是完全异步进行的。稳定版本的 Chrome 浏览器是通过 WebKit 的方式加载的,但在 Canary 版本中,仍然是使用 Firefox/Edge 加载方式。

「2.必须经历两个加载阶段」

在上述模式中,内联的 CSS 通过display:none隐藏了没有加载完样式的内容,直到异步加载完剩余的 CSS 样式。如果你将这些样式分派到两个或多个 CSS 文件中,这些文件有可能不按照顺序加载,导致加载过程中出现内容错乱:

内容错乱,就好比弹出广告一样,会导致用户体验挫败,必须全力消灭。

既然有两个加载阶段,你就必须决定渲染的先后顺序。你当然会想首先渲染「位置显要」的内容。但是,所谓的「位置」是根据窗口大小来决定的。因此,问题来了,你得找出一把「万能」钥匙。

三.一个更简单、更好的方法



  
  
  

计划是这样的:针对每个,加载样式表时我们阻止渲染它的后续内容,但是允许渲染它之前的内容。样式表是并行加载的,但是按照一定的顺序显示。这使得的效用与相近。

假设网站 header、正文和 footer 的 CSS 已经加载完毕,但其余内容仍在等待,那么页面会是这样的:

Header:已渲染

正文:已渲染

评论部分:未渲染,它前面的 CSS 还未被加载(/comment.css)。

关于本站:未渲染。它前面的 CSS 还未被加载(/comment.css)。

Footer:未渲染。尽管它本身的 CSS 已加载完成,但它前面的 CSS 还未被加载(/comment.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 并不总是为了中的阻塞渲染,我们得为这个多花点功夫来避免 FOUC。谢天谢地这很容易,因为

此处的

笔者之前做过前端优化的工作,国内外的前端性能优化工具也使用了不少,现阶段可以较好实现这个定位页面慢加载因素的工具有:
OneAPM Browser Insight、AppDynamics、Ruxit,大家有兴趣的话可以去尝试下。

注:本文原文作者为 Jake Archibald,由 OneAPM 运营人员翻译整理

原文地址:https://jakearchibald.com/2016/link-in-b...

Browser Insight 是一个基于真实用户的 Web 前端性能监控平台,能够帮大家定位网站性能瓶颈,网站加速效果可视化;支持浏览器、微信、App 浏览 HTML 和 HTML5 页面。想阅读更多技术文章,请访问 OneAPM 官方技术博客。
本文转自 OneAPM 官方博客

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/115195.html

相关文章

  • 可构造样式表 - 通过javascript来生成css方式

    摘要:可构造样式表是一种使用进行创建和分发可重用样式的新方法。它甚至可以直接用于浏览器解析器直接的接口,无需将他们注入到就可以很轻易的加载样式表。构建一个样式表与引入一个新不同,可构造样式表规范使得其可以通过调用构造函数来强制创建样式表。 可构造样式表是一种使用Shadow DOM进行创建和分发可重用样式的新方法。 使用Javascript来创建样式表是可能的。然而,这个过程在历史上一直是使...

    ConardLi 评论0 收藏0
  • 20道HTML基础面试题(附答案)

    摘要:但有时候我们希望关闭输入框的自动完成功能,例如当用户输入内容的时候,我们希望使用技术从数据库搜索并列举而不是在用户的历史记录中搜索。 以下是我整理的一些HTML的基础面试体,并自己整理了答案。 1 DOCTYPE有什么作用?标准模式与混杂模式如何区分?它们有何意义? 告诉浏览器使用哪个版本的HTML规范来渲染文档。DOCTYPE不存在或形式不正确会导致HTML文档以混杂模式呈现。标准模...

    firim 评论0 收藏0
  • 前端面试【整理更中】:HTML常见题目(带答案)

    摘要:标准模式的排版和运作模式都是以该浏览器支持的最高标准运行。使用之前需要考虑这两个缺点。数据的有效期不同。在设置的过期时间之前一直有效,即使窗口或者浏览器关闭。仅在浏览器窗口关闭之前有效。 一、HTML常见题目01、Doctype作用?严格模式与混杂模式如何区分?它们有何意义?02、 HTML5 为什么只需要写 !DOCTYPE HTML?03、行内元素有哪些?块级元素有哪些?空(voi...

    zhjx922 评论0 收藏0
  • 前端面试【整理更中】:HTML常见题目(带答案)

    摘要:标准模式的排版和运作模式都是以该浏览器支持的最高标准运行。使用之前需要考虑这两个缺点。数据的有效期不同。在设置的过期时间之前一直有效,即使窗口或者浏览器关闭。仅在浏览器窗口关闭之前有效。 一、HTML常见题目01、Doctype作用?严格模式与混杂模式如何区分?它们有何意义?02、 HTML5 为什么只需要写 !DOCTYPE HTML?03、行内元素有哪些?块级元素有哪些?空(voi...

    Freeman 评论0 收藏0

发表评论

0条评论

wthee

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<