页面渲染机制和性能优化总结

一 页面的加载和渲染过程

  • 一 页面的加载和渲染过程
    • 1.1 HTML 加载
    • 1.2 其他静态资源下载
    • 1.3 DOM树构建
    • 1.4 CSSOM 树构建
    • 1.5 渲染树构建
    • 1.6 布局计算
    • 1.7 绘制(Paint)
    • 1.8 重排(Reflow)与重绘(Replain)
  • 二.前段性能优化总结
    • 2.1 页面加载优化
    • 2.2 执行优化
    • 2.3 样式优化
    • 2.4 渲染优化
    • 2.5 JavaScript执行优化

当我们在浏览器地址输入一个URL,最终会呈现一个完整页面,大概会经历以下步骤:

域名解析 --> 发起TCP的3次握手 --> 建立TCP连接后发起http请求 --> 服务器响应http请求,浏览器得到html代码 --> 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) --> 浏览器对页面进行渲染呈现给用户

1.1 HTML 加载

输入URL后首先拿到的是HTML,所以最先下载的是HTML,下载以后会对它进行解析.

1.2 其他静态资源下载

HTML在解析过程中,如果HTML引用其他的外部资源链接,如:JS和CSS和图片时,会启动别的线程来下载这些资源. 特殊的是,当遇到js文件时,HTML的解析会停下来,等JS文件下载完后再进行解析,因为JS有可能改变DOM的结果,重复操作,有白白浪费资源的风险,因此HTML解析器等JS下载完后再进行解析

1.3 DOM树构建

在HTML解析时候,解析器会把HTML解析成一个个DOM对象,而这些DOM最终会构建DOM 树。

1.display的元素,注释存在于DOM树中

2.js会阻塞DOM树的构建从而阻塞其他资源的并发加载,因此最好把JS放在最后加载

3.对可能异步加载的JS使用 async 和defer
复制代码

1.4 CSSOM 树构建

在CSS下载完后,CSS解析器会对CSS进行解析,会CSS解析成CSS对象,最终构建把这些CSS组装起来,构建CSSOM树。

1\. js 会阻塞cssom的构建,只有js访问才会阻塞

2\. cssom树的构建和dom树的构建是并行的

3\. 减少css的嵌套(最好6层以内)和定义合理的css可以提高解析速度
复制代码

1.5 渲染树构建

DOM树和CSS构建完成后,浏览器会根据这两棵树再构建一颗渲染树,它包含了可见的dom节点和节点的样式

1.渲染树的根节点是HTML节点

2.renderObject和dom不是完全对应的,不可见元素display:none是不会放入渲染树中的

3.visibility:hidden 的元素在Render Tree中
复制代码

1.6 布局计算

渲染树构建完成后,所有的元素关系需要和应用样式关联,计算器会计算元素的大小和绝对位置.

1.float,flexd,absolute的元素会发生偏移

2.我们常说的脱离文档流,就是脱离布局。
复制代码

1.7 绘制(Paint)

布局计算完成后,浏览器就可以在页面上渲染了,整个页面就呈现在屏幕上了.

1.8 重排(Reflow)与重绘(Replain)

渲染树是动态构建的,DOM节点和CSS节点的任何改变都会导致渲染树的重新构建,渲染树的改动就会导致重排与重绘

  • 重排

    当我们在DOM树中新增,修改,删除,或者改变某些元素大小,位置,布局方式的时候,都要重新计算. 在改动发生时,要重新经历DOM的改动,CSSOM的构建,渲染树的构建,布局计算和绘制整个流程,这个过程就叫 "重排" ,有点也就 "回流"

回流的触发

1.dom元素的位置和大小发生改变

2.dom元素的增加和删除

3.伪类的激活

4.窗口大小的改变

5.增加和删除class样式

6.动态计算修改class样式

浏览器并不会每一次reflow都会执行,而是会积攒一部分,这个过程也被成为异步reflow,或者增量异步reflow. 但是有些情况浏览器是不这样做的,比如 resize 窗口,改变页面默认的字体等这些操作,浏览器会马上 reflow
复制代码
  • 重绘

    重绘是我们改动元素的字体颜色,背景色等外观元素时候,并不会改变它的大小,也不会影响其他元素的布局,这个时候就不需要重新构建渲染树。浏览器会对元素的样式重新绘制,这个过程叫做 "重绘"

重绘的触发: 任何对元素样式,如color,background-color等熟悉的改变,JS和CSS都会引起重绘。

二.前段性能优化总结

2.1 页面加载优化

  • 减少HPPT 请求

    尽量减少 页面的请求数(首次加载同时请求数不能超过4个),移动设备浏览器同时响应请求为四个请求(Android支持四个,IOS 5+ 支持6个)

    合并JS和CSS

    使用 CSS 精灵图

  • 使用CDN

    CDN(内容发布网络)是一组分布在多个不同地理位置的Web服务器,用于更加有效地向用户发布内容。在优化性能时,向特定用户发布内容的服务器的选择基于对网络慕课拥堵的测量

  • 缓存资源 添加Expires头

    使用缓存可减少向服务器的请求数,节省加载时间,所有的静态资源都要在服务器端设置缓存,并且使用长缓存(使用时间戳更新缓存)

  • 压缩代码

    减少资源大小可以加快网页显示速度,对代码进行压缩,并在服务器端设置Gzip

  • 无阻赛

    头部内联的样式的样式和脚本会阻塞页面的渲染,样式放在头部并用 link 方式引入,脚本放在尾部 并用异步方式加载

  • 按需加载

    讲不影响首屏的资源和当前屏幕不用的资源放在用户需要时才加载,可大大提升显示速度和降低总体流量

  • 减少Cookie

    Cookie会影响加载速度,静态资源域名不适用Cookie

  • 避免重定向

    当页面发生了重定向,就会延迟整个HTML文档的传输。在HTML文档到达之前,页面中不会呈现任何东西,也没有任何组件会被下载。

2.2 执行优化

  • CSS 写在头部,JS写在尾部异步执行

    将样式表放在头部对于实际页面加载的时间并不能造成太大影响,但是这会减少页面首屏出现的时间,使页面内容逐步呈现,改善用户体验,防止“白屏”

    脚本放在底部对于实际页面加载的时间并不能造成太大影响,但是这会减少页面首屏出现的时间,使页面内容逐步呈现。

    js的下载和执行会阻塞Dom树的构建(严谨地说是中断了Dom树的更新),所以script标签放在首屏范围内的HTML代码段里会截断首屏的内容。

  • 避免img,iframe 等的src为空,为空会重新加载当前页面,影响速度和效率

  • 尽量避免重置图像大小:多次重置图像大小会引发图像的多次重绘,影响性能

  • 图像尽量避免使用DataURL

2.3 样式优化

  • 避免在HTML 中书写style

  • 避免CSS 表达式

  • 使用flexbox 代替传统的布局模型

  • 正确使用 display熟悉

  • 不声明过多的 font-size

  • 值为0时不需要任何单位

  • 避免让选择符看起来像正则表达式:高级选择符执行耗时长且不易读懂,避免使用

2.4 渲染优化

  • HTML 使用 viewport :viewport 可以加速页面的渲染

  • 减少 DOM 节点:DOM 节点太多影响页面的渲染,应尽量减少 DOM 节点

  • 动画优化 尽量使用 CSS3 动画

  • 合理使用 requestAnimationFrame 动画代替 setTimeout

  • 使用 requestAnimationFrame 监听帧变化,使得在正确的时间进行渲染;

  • 高频事件优化:Touchmove 和 Scroll 事件可导致多次渲染

    函数节流

    函数防抖

    使用requestAnimationFrame监听帧变化:使得在正确的时间进行渲染

    增加响应变化的时间间隔:减少重绘次数

  • GPU加速:使用某些HTML5标签和CSS3属性会触发GPU渲染,请合理使用(过渡使用会引发手机耗电量增加)

    HTML标签:video、canvas、webgl

    CSS属性:opacity、transform、transition

2.5 JavaScript执行优化

  • 减少重绘和回流

  • 减少不必要的DOM操作

  • 尽量改变class 而不是Style,使用classList 代替 className

  • 缓存DOM与计算,每次DOM 选择都要计算,用一个变量保存这个值

  • 尽量使用事件代理

转载自:https://juejin.im/post/6844904004300832775#11-html-%E5%8A%A0%E8%BD%BD

你可能感兴趣的:(页面渲染机制和性能优化总结)