一、浏览器概述

  目前的主流浏览器有5个:Internet Explorer、Firefox、Safari、Chrome和Opera浏览器。根据 StatCounter 浏览器统计数据,目前(截止2019 年 5 月)Firefox、Safari 和 Chrome 浏览器的总市场占有率将近 83.66%。由此可见,如今开放源代码浏览器在浏览器市场中占据了非常坚实的部分。
  以上5种浏览器由于有着不同的浏览器内核,造成同样的html页面有着不同呈现。Internet Explorer的内核是Trident;Firefox的内核是Gecko;Chrome、Safari内核是Webkit;Opera的内核则是Presto。

二、浏览器渲染过程

  我们先大致看下浏览器渲染关键路径图:

1、HTML解析,构建DOM树

  浏览器从网络或硬盘中获得HTML字节数据后会经过以下流程将字节解析为DOM树

  • 字符编码:先将HTML的原始字节数据转换为文件指定编码的字符。
  • 令牌化:然后浏览器会根据HTML规范来将字符串转换成各种令牌(如<html><body><p>这样的标签以及标签中的字符串和属性等都会被转化为令牌,每个令牌具有特殊含义和规则)。
  • 生成节点对象:接着每个令牌都会被转换成定义其属性和规则的对象,即节点对象。
  • 构建DOM树:最后将节点对象构建成树形结构,即DOM树。HTML标签之间有复杂的父子关系,树形结构刚好可以诠释这样的关系。

  下面通过一段HTML代码与配图更好的理解“字节 -> 字符 -> 令牌-> 节点对象 -> 对象模型”这个过程:

<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link href="style.css" rel="stylesheet">
    <title>Critical Path</title>
  </head>
  <body>
    <p>Hello <span>web performance</span> students!</p>
    <div><img src="test.png"></div>
  </body>
</html>
复制代码

DOM树构建过程
2、CSS解析,构建CSSOM树

  浏览器解析遇到<link>标签时,浏览器就开始解析CSS,像构建DOM树一样构建CSSOM树。style.css的代码如下:

body { font-size: 16px }
p { font-weight: bold }
span { color: red }
p span { display: none }
img { float: right }
复制代码

CSSOM树
3、Render Tree

  在构建了DOM树CSSOM树之后,浏览器只是拥有2个相互独立的对象集合,DOM树描述的文档结构和内容,CSSOM树描述了对应文档的样式规则,想要渲染出页面,就需要将DOM树CSSOM树结合在一起,构建渲染树。

渲染树
4、Layout

  渲染树构建好后,浏览器得到了每个节点的内容与样式,下一步就是需要计算每个节点在浏览器窗口的确切位置与大小,即layout布局。
  布局阶段,从渲染树的根节点开始遍历,采用盒子模型的模式来表示每个节点与其他元素之间的距离,从而确定每个元素在屏幕内的位置与大小。

盒子模型:包括外边距(margin),内边距(padding),边框(border),内容(content)。标准盒子模型width/height = content;IE盒子模型width/height = content + padding + border。

盒子模型
5、Paint绘制页面

  当Layout布局完成后,浏览器会立即发出Paint事件,开始讲渲染树绘制成像素,绘制所需要的时间跟CSS样式的复杂度成正比,绘制完成后,用户才能看到页面在屏幕中的最终呈现效果。

  如果想更详细地体验浏览器渲染流程,可以使用Chrome开发者工具中的Performance面板,录制浏览器从请求直到渲染完成的过程,如下图所示:

Performance

三、渲染优化方案

1、优化渲染关键路径方案

  通过优化渲染关键路径,可以优化页面渲染性能,减少页面白屏时间。

  • 优化JSJavaScript文件加载会阻塞DOM树的构建,可以给<script>标签添加异步属性async,这样浏览器的HTML解析就不会被js文件阻塞。
  • 优化CSS:浏览器每次遇到<link>标签时,浏览器就需要向服务器发出请求获得CSS文件,然后才继续构建DOM树CSSOM树,可以合并所有CSS成一个文件,减少HTTP请求,减少关键资源往返加载的时间,优化渲染速度。

2、其他优化方案

  • 加载部分HTML
    浏览器先加载主要HTML初始化静态部分,动态变化的HTML内容通过Ajax请求加载。这样可以减少浏览器构建DOM树的工作量,让用户感觉页面加载速度很快。
  • 压缩
    对HTML、CSS、JavaScript这些文件去除冗余字符(例如不必要的注释、空格符和换行符等),再进行压缩,减小文件数据大小,加快浏览器解析文件编码。
  • 图片加载优化
    1)小图标合并成雪碧图,进而减少img的HTTP请求次数;
    2)图片加载较多时,采用懒加载的方案,用户滚动页面可视区时再加载渲染图片。
  • HTTP缓存
    浏览器自带了HTTP缓存的功能,只需要确保每个服务器响应的头部都包含了以下的属性:
    1)ETag: ETag是一个传递验证令牌,它对资源的更新进行检查,如果资源未发生变化时不会传送任何数据。当浏览器发送一个请求时,会把ETag一起发送到服务器,服务器会根据当前资源核对令牌(ETag通常是对内容进行Hash后得出的一个指纹),如果资源未发生变化,服务器将返回304 Not Modified响应,这时浏览器不必再次下载资源,而是继续复用缓存。
    2)Cache-Control: Cache-Control定义了缓存的策略,它规定在什么条件下可以缓存响应以及可以缓存多久。
    a、no-cache: no-cache表示必须先与服务器确认返回的响应是否发生了变化,然后才能使用该响应来满足后续对同一网址的请求(每次都会根据ETag对服务器发送请求来确认变化,如果未发生变化,浏览器不会下载资源)。no-store直接禁止浏览器以及所有中间缓存存储任何版本的返回响应。简单的说,该策略会禁止任何缓存,每次发送请求时,都会完整地下载服务器的响应。
    b、public&private: 如果响应被标记为public,则即使它有关联的HTTP身份验证,甚至响应状态代码通常无法缓存,浏览器也可以缓存响应。如果响应被标记为private,那么这个响应通常只为单个用户缓存,因此不允许任何中间缓存(CDN)对其进行缓存,private一般用在缓存用户私人信息页面。
    c、max-age: max-age定义了从请求时间开始,缓存的最长时间,单位为秒。

小结

  今天浏览器渲染过程和优化方案就介绍到这里,大家如果有更多更好的页面性能优化方案可以多多交流,评论区欢迎留言~~

转载于:https://juejin.im/post/5d136700f265da1b7c6128db

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐