美文网首页
理解关键的渲染路径

理解关键的渲染路径

作者: 百里少龙 | 来源:发表于2017-03-07 22:16 被阅读0次

    当浏览器从服务器接收到一个HTML页面的请求时,到屏幕上渲染出来要经过很多个步骤。浏览器完成这一系列的运行,或者说渲染出来我们常常称之为 “关键渲染路径”(Critical Rendering Path)。

    理解CRP(Critical Rendering Path)相关的知识可以更好的提高网站的性能。那么理解我们从下面六个部分来理解CRP相关的知识:

    • 构建DOM树
    • 树建CSSOM树
    • 运行JavaScript
    • 创建Render树
    • 生成布局
    • 绘制(Painting)
    image

    构建DOM树

    DOM(文档对象模型)树是一个完全解析的HTML页面对象。从<html>根元素开始到页面中每个元素和文本的节点。元素嵌套在其他元素内则表示为子节点,每个节点包含完整的属性元素。例如一个元素,它就有与之相关的href节点。

    来看下面这个简单的DOM示例:

    <html>  
    <head>  
      <title>Understanding the Critical Rendering Path</title>
      <link rel="stylesheet" href="style.css">
    </head>  
    <body>  
      <header>
          <h1>Understanding the Critical Rendering Path</h1>
      </header>
      <main>
          <h2>Introduction</h2>
          <p>Lorem ipsum dolor sit amet</p>
      </main>
      <footer>
          <small>Copyright 2017</small>
      </footer>
    </body>  
    </html>  
    

    这将会创建一个像下面这样的DOM树:


    image

    HTML比较好的是它可以执行部分。完整的文档不需要加载的内容会在页面的开始呈现。然而,比如CSS和JavaScript可以阻止页面的呈现。

    构建CSSOM树

    CSSOM(CSS对象模型)是一个表示DOM样式的对象。它类似于DOM,但是是每个节点相关的样式,包括他们是否显式声明或隐式继承。

    比如,在style.css文件中对上面的DOM有这样的一些样式:

    body { font-size: 18px; }
    
    header { color: plum; }  
    h1 { font-size: 28px; }
    
    main { color: firebrick; }  
    h2 { font-size: 20px; }
    
    footer { display: none; } 
    

    这将会构建像下面这样的一个CSSOM树:

    image

    CSS被认为是 “渲染阻塞资源”。这意味着渲染树(见下文)的构建离不开延续一个资源的解析完成度。不像HTML,CSS不能只用部分,因为CSS是具有继承层叠特性。文档后面定义的样式可以覆盖前面定义的样式。所以,如果我们开始使用CSS时,之前的样式表会被认为已经全部解析完。这也意味着CSS必须充分解析才能继续下一个阶段。

    如果只运用于当前设备,CSS文件只被认为阻塞。==<link rel="stylesheet">== 标签可以接受一个media属性,可以用来指定样式适用于何种媒体。例如,我们有一个样式表,它的media属性设置为orientation:landscape时,如果在portrait模式下查看页面,那么这个样式表不会被认为是一个阻塞资源。

    CSS还会阻塞JavaScript。那是因为JavaScript文件必须要等CSSOM构建完才会执行。

    运行JavaScript

    JavaScript被认为是一个 “解析器阻塞资源”。这意味着解析的HTML文档本身就会被JavaScript阻塞。

    当解析器读到<script>标记,不管是内部的还是外部的,它停止获取(如果是外部的)并运行它。这个为什么,如果我们有一个JavaScript文件,该文件引用文档中的元素,那么它必须放在这个元素的后面。

    为了避免JavaScript解析器造成阻塞,可以添加==async==属性,异步加载它。

    <script async src="script.js">  
    

    创建Render树

    Render树是DOM和CSSOM的组合。这个树代表最终在页面上呈现的东西。这意味着它只抓住了可见的内容,将不包括设置了hidden的元素和CSS设置了display:none的元素。

    使用上面的DOM和CSSOM,构建的Render树如下图所示:

    image

    生成布局

    布局根据CSS样式设置的大小来决定页面在窗口中的尺寸。视窗的大小是由<head>中viewport标记来决定,如果没有提供这个标记,默认使用的视窗宽度是980px。

    例如,常见的设置视窗的meta标签,指定的大小对应设备宽度:

    <meta name="viewport" content="width=device-width,initial-scale=1">  
    

    如果用户访问页面宽度是基于设备的宽度1000px。那一半的视窗就是500px,10vw就是100px。

    绘制(Painting)

    最后就是绘制(Painting)步骤,把页面可见的内容转化为像素在屏幕上显示。

    绘制需要多少时间这取决于DOM的大小以及应用的样式。有一些样式需要更多的执行时间。例如,一个复杂的渐变背景图像比一个单一颜色背景绘制需要更多的时间。

    把它们结合起来

    我们可以在DevTools中看到关键渲染路径的过程。在Chrome浏览器中,点击Timeline选项。

    拿文章前面的示例(这里添加了<script>标签):

    <html>  
    <head>  
      <title>Understanding the Critical Rendering Path</title>
      <link rel="stylesheet" href="style.css">
    </head>  
    <body>  
      <header>
          <h1>Understanding the Critical Rendering Path</h1>
      </header>
      <main>
          <h2>Introduction</h2>
          <p>Lorem ipsum dolor sit amet</p>
      </main>
      <footer>
          <small>Copyright 2017</small>
      </footer>
      <script src="main.js"></script>
    </body>  
    </html>  
    

    如果我们看页面的加载日志,将看到如下这样的数据:

    image
    • 发送请求:发送GET,请求index.html
    • 解析HTML并发送请求:解析HTML并且构建DOM树,发送GET请求,请求style.css和main.js
    • 解析样式:根据style.css创建CSSOM
    • 脚本评估:main.js评估
    • 布局:基于HTML中的视窗meta生成布局
    • 绘制:绘制页面

    基于这些信息,我们可以决定如何优化关键渲染路径。

    相关文章

      网友评论

          本文标题:理解关键的渲染路径

          本文链接:https://www.haomeiwen.com/subject/wasvgttx.html