Skip to content

CSS:Network Performance #192

Open
Open
@yaofly2012

Description

@yaofly2012

一、为啥优化CSS

1. 阻塞渲染树构建

未构建完的CSSOMTree是不准确的,浏览器必须等到CSSOMTree构建完毕后才能进入下一阶段

阻塞渲染的 CSS说道:

CSS 是阻塞渲染的资源。需要将它尽早、尽快地下载到客户端,以便缩短首次渲染的时间

Defer non-critical CSS

This means that the browser needs to wait for all CSS to load and get processed before painting a single pixel on the screen

2. 阻塞DOM树构建(主要是首屏渲染)

讲故事:

  1. 页面里只有HTML和CSS时,CSSOM和DOM是各自创建的,互不干扰。
  2. 后来有了JS(即使是空script标签)。
    JS可以除了可以操作DOM外,还可以操作CSSOM啊,并且CSSOM必须完全构建后才能使用。所以JS等待CSSOM构建。JS不执行完DOM树构建也被阻塞了(此时CSSOM构建间接地阻塞DOM树构建渲染)。
  3. JS优化了:asnc/deferscript标签声明不操作DOM,也不操作CSSOM。

二、优化手段

  1. 关键CSS直接写到页面里
    不使用外部文件加载关键CSS可减少http请求数量,但这样会增加文档体积,增加了DOM解析时间。

  2. 非关键CSS延迟加载

<link rel="preload" as="style" href="styles.css" onload="this.rel='stylesheet';this.onload=null;">
  • 媒体查询
    不符合媒体查询的CSS都不阻塞渲染,只是异步下载,但不会解析CSS(即不应于页面)。
<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'; this.onload=null;">

本质上preload和媒体查询这两种方式异曲同工。

  1. 外部CSS文件压缩。

总之:减小CSS文件体积,尽早、尽快地下载到客户端,以便缩短首次渲染的时间。

Demo1

知乎 浏览器的渲染过程有个间接阻塞的例子

Demo2

阻塞DOM构建

<!DOCTYPE html>
<html>
    <head>
        <title>Normal</title>
        <link rel="stylesheet" href="./lib/style.css"/>
    </head>
    <body>
        <p>...content before scripts...</p>
        <p>...content after scripts...</p>
        <p>...content after document.write scripts...</p>
        <script src="./lib/normal.long.js"></script>
    </body>
</html>

image
DOMContentLoaed事件触发的很晚。

优化(给scriptdefer)后不阻塞DOM树构建:

<!DOCTYPE html>
<html>
    <head>
        <title>Normal</title>
        <link rel="stylesheet" href="./lib/style.css"/>
    </head>
    <body>
        <p>...content before scripts...</p>
        <p>...content after scripts...</p>
        <p>...content after document.write scripts...</p>
        <script defer src="./lib/normal.long.js"></script>
    </body>
</html>

image

检测关键CSS(一般首屏渲染依赖的CSS)

工具

案例分析

淘宝

  1. CSS 直接写入页面,并且样式图片和字体文件也是base64数据
  2. 没有外部CSS

JD

  1. 样式直接在组件模块里
  2. 也有外部样式

FB

  1. 部分CSS利用了repload
  2. CSS数据居然使用base64数据;

总体看下来大部分首屏样式直接写到页面里了,但是利用preload加载样式的比较少,到时利用preload加载js的比较多。

参考

  1. Eliminate render-blocking resources
  2. Defer non-critical CSS
  3. CSS and Network Performance
  4. Tool: Test a website's performance
  5. MDN Preloading content with rel="preload"

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions