现代浏览器性能优化-CSS篇

标签: 性能优化 javascript css html | 发表时间:2017-12-29 19:00 | 作者:GeoffZhu
出处:https://segmentfault.com/blogs

我来填坑了,CSS篇终于写出来了,如果你没看过前面的JS篇,可以 在这里观看

众所周知,CSS的加载会阻塞浏览器渲染或是引起浏览器重绘,目前业界普遍推荐把CSS放到 <head>中,防止在CSS还没加载完,DOM就已经绘制出来了,造成CSS加载完成后的重绘。那在现代浏览器中我们有没有办法提高首屏渲染速度那?

你是不是经常在第一次打开某个网站的时候看到这种情况,本来的页面是这样的

实际上刚加载出来的是这样的

字体文件没加载出来,或者加载的太慢了

理解CSS解析过程

以下面这段HTML为例,解释一遍CSS加载解析的过程。

  <html>
<head>
  <!-- headStyle.css中存在字体文件webfont.woff2 -->
  <link rel="stylesheet" type="text/css" href="/headStyle.css">
</head>
<body>
  <p>Text</p>
  <link rel="stylesheet" type="text/css" href="/bodyEndStyle.css">
</body>
</html>

浏览器自上而下读取HTML文档,当发现headStyle.css的时候,停止Parser HTML,开始下载headStyle.css,解析headStyle.css的过程中发现字体文件webfont.woff2,开始下载webfont.woff2,并继续解析css生成CSSStyleSheet。解析完毕后,继续Parser HTML,当发现p标签时,会将p标签结合当前的CSSStyleSheet展示出来,此时用户屏幕中已经有p标签的内容了。当浏览器发现bodyEndStyle.css时,就会下载headStyle.css,解析CSS,然后更新CSSStyleSheet,这时会引起一次重绘。当字体下载完毕的时候也会引起一次重绘。

这个过程中,有两个非常严重的问题。一、如果headStyle.css文件很大,浏览器需要解析很多行CSS后才能还有个字体文件需要下载,其实此时已经很晚了,字体下载时间稍长一点,就会出现我前面截图提到的问题。二、bodyEndStyle.css中如果存在p标签对应的样式,那p标签的样式会在bodyEndStyle.css解析完成后,改变一次样式,很影响体验。

如何解决这些问题那?其中也会用到一些JS篇中提到的点,如果没看过,建议先看看。

优化核心依旧是减少下载时间

JS篇中的预先解析DNS(dns-prefetch)依旧适用,提前解析CSS文件所在域名的DNS。

Preload

因为CSS已经在head中,我们不需要为css加preload属性了,但是css中用到的字体文件,一定要在所有css之前proload上。

  <link rel="preload" href="/webfont.woff2" as="font">

首页CSS内联,非必要CSS异步加载

首页用到的CSS内联写在 <head>中,其余CSS均采用异步加载,可以采用这种自己实现的加载CSS的方法,在合适的需要时加载需要的css

  function LoadStyle(url) {
  try {
    document.createStyleSheet(url)
  } catch(e) {
    var cssLink = document.createElement('link');
    cssLink.rel = 'stylesheet';
    cssLink.type = 'text/css';
    cssLink.href = url;
    var head = document.getElementsByTagName('head')[0];
    head.appendChild(cssLink)
  }
}

如果你使用webpack,那就更轻松了,使用import函数,大致如下

  // 在a.js模块中直接引入css
import 'style.css'
  // 在需要a.js模块的地方
improt('path-of-a.js').then(module => {})

webpack打包后,其实是把style.css打包进了a.js,在异步加载a.js的时候,会将style.css中的代码插入 haed标签中。

终极完美结构

  <!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Faster</title>
  <link rel="dns-prefetch" href="//cdn.cn/">

  <link rel="preload" href="//cdn.cn/webfont.woff2" as="font">
  <link rel="preload" href="//cdn.cn/Page1-A.js" as="script">
  <link rel="preload" href="//cdn.cn/Page1-B.js" as="script">
  
  <link rel="prefetch" href="//cdn.cn/Page2.js">
  <link rel="prefetch" href="//cdn.cn/Page3.js">
  <link rel="prefetch" href="//cdn.cn/Page4.js">

  <style type="text/css">
    /* 首页用到的CSS内联 */
  </style>
</head>
<body>

<script type="text/javascript" src="//cdn.cn/Page1-A.js" defer></script>
<script type="text/javascript" src="//cdn.cn/Page1-B.js" defer></script>
</body>
</html>

JS篇)中,我已经解释过这套结构中JS的执行顺序了,本篇只是加入了CSS和字体。至此,我心中终极完美的页面HTML结构就是这样了。

如果你对异步加载CSS的方案感兴趣,欢迎留言与我讨论!

扩展阅读

相关 [现代 浏览器 性能优化] 推荐:

现代浏览器性能优化-CSS篇

- - SegmentFault 最新的文章
我来填坑了,CSS篇终于写出来了,如果你没看过前面的JS篇,可以 在这里观看. 众所周知,CSS的加载会阻塞浏览器渲染或是引起浏览器重绘,目前业界普遍推荐把CSS放到 中,防止在CSS还没加载完,DOM就已经绘制出来了,造成CSS加载完成后的重绘. 那在现代浏览器中我们有没有办法提高首屏渲染速度那.

[转]浏览器的加载与页面性能优化

- Allen - linux大棚-roclinux.cn
本原创文章属于《Linux大棚》博客,博客地址为http://roclinux.cn. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. 文章部分转自“百度泛用户体验平台”,本文地址为:http://www.baiduux.com/blog/2011/02/15/browser-loading/.

浏览器的加载与页面性能优化

- 彦强 - 百度泛用户体验
本文将探讨浏览器渲染的loading过程,主要有2个目的:. 了解浏览器在loading过程中的实现细节,具体都做了什么. 研究如何根据浏览器的实现原理进行优化,提升页面响应速度. 由于loading和parsing是相互交织、错综复杂的,这里面有大量的知识点,为了避免过于发散本文将不会对每个细节都深入研究,而是将重点放在开发中容易控制的部分(Web前端和Web Server),同时由于浏览器种类繁多且不同版本间差距很大,本文将侧重一些较新的浏览器特性.

[转]现代浏览器揭秘(2)

- - 小彰
解析 Parsing-general. 既然解析是渲染引擎中一个非常重要的过程,我们将稍微深入的研究它. 解析一个文档即将其转换为具有一定意义的结构――编码可以理解和使用的东西. 解析的结果通常是表达文档结构的节点树,称为解析树或语法树. 例如,解析“2+3-1”这个表达式,可能返回这样一棵树. 解析基于文档依据的语法规则――文档的语言或格式.

现代浏览器的web音频javascript类库 - Howler.js

- - CSDN博客Web前端推荐文章
日期:2013-2-6  来源: GBin1.com. 浏览器这个玩意儿并不是个新鲜事,但是随着HTML5的发展激起了浏览器技术的巨大发展. 但是浏览器上对于音频控制技术来说仍旧非常的落伍. 庆幸的是 Google积极的开发和创建了web audio API,这使得基于浏览器的音频控制更加的简单并且直观.

MySQL性能优化

- sun - IT程序员面试网
在笔试面试中,尤其是像百度,淘宝这些数据量非常大,而且用LAMP架构的公司,数据库优化方面就显得特别重要了. 此外,除了数据库索引之外,在LAMP结果如此流行的今天,数据库(尤其是MySQL)性能优化也是海量数据处理的一个热点. 下面就结合自己的经验,聊一聊MySQL数据库优化的几个方面. 首先,在数据库设计的时候,要能够充分的利用索引带来的性能提升,至于如何建立索引,建立什么样的索引,在哪些字段上建立索引,上面已经讲的很清楚了,这里不在赘述.

Hebernate 性能优化

- - 企业架构 - ITeye博客
文章分为十三个小块儿对Hibernate性能优化技巧进行总结性分析,分析如下:. 一、在处理大数据量时,会有大量的数据缓冲保存在Session的一级缓存中,这缓存大太时会严重显示性能,所以在使用Hibernate处理大数 据量的,可以使用session. clear()或者session. evict(Object) 在处理过程中,清除全部的缓存或者清除某个对象.

Hbase 性能优化

- - CSDN博客云计算推荐文章
因 官方Book Performance Tuning部分章节没有按配置项进行索引,不能达到快速查阅的效果. 所以我以配置项驱动,重新整理了原文,并补充一些自己的理解,如有错误,欢迎指正. 默认值:3分钟(180000ms). 说明:RegionServer与Zookeeper间的连接超时时间.

JavaScript性能优化

- - ITeye博客
互联网泡沫让投资者长了记性:态度更加谨慎.         如今主流浏览器都在比拼JavaScript引擎的执行速度,但最终都会达到一个理论极限,即无限接近编译后程序执行速度. 这种情况下决定程序速度的另一个重要因素就是代码本身. 在这里我们会分门别类的介绍JavaScript性能优化的技巧,并提供相应的测试用例,供大家在自己使用的浏览器上验证, 同时会对特定的JavaScript背景知识做一定的介绍.