2018-08-22 浏览器渲染过程与优化

https://sylvanassun.github.io/2017/10/03/2017-10-03-BrowserCriticalRenderingPath/

http://www.ruanyifeng.com/blog/2015/09/web-page-performance-in-depth.html

浏览器渲染过程,分为以下几步:

1:构建dom树

2:构建css树,

3:合并dom树以及css树,构建渲染树,在这个过程中,会过滤掉不可见节点。例如使用css设置了display:none属性的节点,但是要注意一点,visibility: hidden这个属性不是不可见属性,他的意思是隐藏dom节点,但是仍然占据布局空间

4:生成布局,遍历每一个节点,计算出dom元素的位置(重排)

5:将节点绘制到屏幕上。(重绘)

如果浏览器渲染一个页面,首先就是要构建dom树以及css树,如果页面非常复杂,这两步就会给页面加载速度带来影响。

dom树优化

所以对于dom树的优化,我们在写页面时,应该应该尽可能的减少dom元素

css树优化

对于css树的优化,可以让css在不同的情况下加载不同的css资源,而不是一次性全部加载,这样就可以减少css树的构建时间。这一步的优化可以使用css的媒体查询来实现。

媒体查询是由媒体类型以及0个或多个检查媒体特定类型的表达式组成。具体如下:


注意:使用媒体查询可以让css文件不会再加载时阻塞渲染,但是浏览器依然会将文件下载下来的。

优化JavaScript脚本

当html解析器遇到一个script标签时,会暂停构建dom树,将控制权交给JavaScript引擎,然后由JavaScript引擎去执行脚本,这会严重阻塞dom树的构建过程。而且在执行JavaScript脚本的过程中,如果操作了css,而这个css文件还没有下载和执行,那么脚本执行以及dom树构建都会被阻塞,等待浏览器下载css文件以及构建完css树后,才会接着执行JavaScript脚本。所以JavaScript脚本的位置放的位置非常重要,不然会严重阻塞浏览器渲染

在执行JavaScript脚本时,如果操作了dom元素,而这个元素还没有构建好,那么就会报错。所以就讲script标签放到页面的最下方,或者使用window.onload()和JQuery中的$(function(){})这两个方法。不过这两个方法还是有区别的,onload是在页面渲染完成以后,执行JavaScript脚本,而jq的方法是在dom树构建完成后就开始执行了。

给script标签加上async属性,可以使这个script脚本异步加载,并不会阻塞dom树的构建,但当这个脚本异步下载完成后,会直接执行这个脚本

总结:

网页请求到渲染的整个过程

浏览器通过url请求到html页面,然后html解析器开始构建dom树,构建的过程中,如果遇到link标签,那么浏览器就会请求这个css文件,然后开始构建css树,如果遇到script标签,那么浏览器就会请求这个脚本文件,html解析器会将控制器权交给JavaScript引擎,执行这个脚本。当dom树与css树都构建出来后,就会合并出渲染树,接着便是计算位置,绘制到屏幕上。

在这个过程中,

优化css树的方法使用媒体查询,根据不同的媒体状态,加载不同的css资源。

优化JavaScript脚本的方法就是异步,使用async这个属性

描述关键渲染路径性能的词汇:

关键资源:指的是html页面、css文件以及JavaScript脚本

关键路径长度:获取资源的往返次数或者总时间

关键字节:所有资源文件的总和

关键路径渲染:浏览器接收到HTML文件、css文件、JavaScript脚本并对其进行解析以及转换成像素的整个渲染过程称为关键路径渲染



其他的优化方案:

1:加载部分HTML,其他的HTML通过ajax请求返回

2:通过对外部资源进行压缩来减少关键路径长度以及关键字节

在进行文件压缩之前,可以先进行一次冗余压缩,比如注释、空格符换换行符

3:http缓存

可以将一些静态的资源缓存起来,然后每次请求的时候带一个标示,后台通过这个标示进行判断资源是否有改变,如果改变则返回新的资源文件,如果没改变,则返回304,复用缓存。

4:资源预加载

资源预加载是推测出用户接下来有可能访问哪些资源,然后对这些资源进行预加载

预加载的方式有以下几种

1:提前进行dns解析,以便之后快速访问另一个主机名  // rel="dns-prefetch" href="other.hostname.com"

2:提前下载好资源文件, 使用的属性不同,优先级不同。prefetch 优先级最低  subresource 优先级最高

3:提前将页面渲染出来 并隐藏 // link rel="prerender" href="//domain.com/next_page.html


网页在生成的时候会渲染一次,而在用户浏览的过程中,还会不断的重新渲染,重新渲染包括两种情况,重新排版布局以及重新绘制到屏幕上。重新排版就是重排,重新绘制就是重绘。所以这个时候就要优化重排以及重绘的时间。

重排一定会重绘,而重绘不一定重排

影响重排的情况如下:

1:修改样式表,例如调整某个dom元素的宽度、高度。。

2:修改dom元素。例如添加、删除、移动dom元素

3:用户事件,例如滚动、输入框、改变窗口大小

总结:只改变了dom元素的‘位置’,就一定会重排

影响重绘的情况就是改变一些元素的颜色。

对于重新渲染的优化就是减少重排以及重绘的次数。如今浏览器已经很智能,会尽量把所有的改变放到一个队列中,然后一次性执行。而我们所要做的优化就是尽量避免浏览器被我们“强制”重排或重绘。

对dom元素的读写操作分开

我们应当知道,只读dom元素的属性或者样式并不会造成重新渲染,而我们先改变dom的元素的样式,再去读dom元素的属性就一定会造成重新渲染。所以我们应该将多个写操作放在一起,将多个读操作放在一起,尽量避免多词重新渲染。

div.style.color='blue'

div.style.marginTop='30px'

以上操作浏览器只会渲染一次


div.style.color='blue'

var margin=parseInt(div.style.marginTop)

div.style.marginTop=(margin+10)+'px'

而这段代码就会使浏览器渲染两次。先做了写操作,然后对dom元素进行读操作的时候就会造成dom元素重新排版,也就是重新渲染。然后获取到值后又进行了写操作,所以会进行两次重新渲染。

改成如下:

var margin=parseInt(div.style.marginTop)

div.style.color='blue'

div.style.marginTop=(margin+10)+'px'

这段代码先进行了读操作,接着进行了两次写操作,所以只会重新渲染一次。

其他提高性能的方法:

1:如果某个样式是重排得到的,建议进行缓存,这样便不用每次获取值都造成重新渲染

2:对dom如果要进行多次读写操作,建议使用虚拟dom。

方法:将一个dom元素进行clone,然后操作完毕后可以插入或替换原节点。

如果进行多次读写操作,有可能造成多次重新渲染,而使用虚拟dom的方式只会在替换或者插入时进行一次重排

3:absolute或fixed的元素重绘的开销比较小,因为不用考虑对别的dom元素的影响

4:display设置为可见时,会进行重绘和重排,因为display为none时,并不占据空间。visibility 从hidden变为可见时,只进行重绘,并不会进行重排。因为visibility 的值为隐藏时,这个dom元素依然占据空间

5:使用 window.requestAnimationFrame()、window.requestIdleCallback() 这两个方法调节重新渲染


浏览器渲染与优化整个流程总结:

网页请求到渲染整个流程:

浏览器通过url请求到html页面,然后html解析器开始构建dom树,构建的过程中,如果遇到link标签,那么浏览器就会请求这个css文件,然后开始构建css树,如果遇到script标签,那么浏览器就会请求这个脚本文件,html解析器会将控制器权交给JavaScript引擎,执行这个脚本。当dom树与css树都构建出来后,就会合并出渲染树,接着便是计算位置,绘制到屏幕上。

整个渲染流程分为五步:

1:构建css树

优化方式:使用媒体查询,将不同的css拆开。让css在不同的情况下,加载不同的css资源。比如:media=print,可以使打印的css资源在用户浏览器的过程中不会阻塞渲染

2:构建dom树

优化方式:布局时尽可能少的dom元素写成所需的UI效果

3:dom树与css树合并,构建渲染树

4:根据渲染树生成布局(如果用户在浏览过程中,改变了dom元素,就会重新布局,也就是重排)

5:布局生成后,就会将dom节点绘制到屏幕上(重新布局后,就是重绘)

第四部和第五步的优化:

1:对dom元素的读写分开操作,因为读取某个dom元素的状态时,并不会造成重绘或者重排,但是如果先使用了写操作,改变了某个dom的属性,那么这个时候在进行读操作时一定会进行重排。

2:对dom节点进行多步操作时,使用虚拟的dom节点。然后在全部操作完成后,将dom节点插入或替换到dom文档中。因为使用虚拟dom节点,只有在插入或者替换的时候,才会造成浏览器重排或者重绘。

3:absolute或fixed的元素重排时开销比较小,因为这种布局方式不用考虑对文档流的影响

对JavaScript的优化:首次加载页面时,JavaScript脚本的执行会影响渲染树的构建,所以可以给不依赖dom节点的JavaScript脚本加上async属性。

其他的优化方式:

关键资源压缩、http缓存

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 大家都知道万维网的应用层使用了HTTP协议,并且用浏览器作为入口访问网络上的资源。用户在使用浏览器访问一个网站时需...
    SylvanasSun阅读 2,135评论 1 12
  • 前端本地调试的问题 基于安全考虑,浏览器对于跨域请求做了严格限制,简单来说就是前端访问后台接口时,要求接口对应的a...
    廊桥梦醉阅读 467评论 0 6
  • 发送 & 接收信息 数据是以“数据包”的形式通过互联网发送,而数据包以字节为单位。当你编写一些 HTML、CSS ...
    mongofeng阅读 901评论 0 0
  • 简介浏览器可以被认为是使用最广泛的软件,本文将介绍浏览器的工 作原理,我们将看到,从你在地址栏输入google.c...
    听风阁阅读 3,270评论 0 7
  • 1. 介绍 浏览器可能是最广泛使用的软件。本书将介绍浏览器的工作原理。我们将看到,当你在地址栏中输入google....
    康斌阅读 2,006评论 7 18