前言
在学习前端的过程中,大家都会对浏览器这个神秘的盒子感到好奇
从输入一串url到页面解析渲染完成,浏览器都干了些啥?
为了更好的理解这个过程,我们使用一个工具来帮助我们
Chrome自带的开发工具中的performance(老版本和其他浏览器为timeline)
点击录制,然后在地址栏输入我们的url
这里以百度为例,输入www.baidu.com,回车
然后点击录制结束,就能看到这个东西
我们最先看到的是这个
字面意思就可以理解,浏览器在向服务器发送请求,并接收响应头和响应体
不过实际上在这之前,浏览器还做了一些事
得先知道朝哪个服务器发送请求吧
根据url,先去本地DNS缓存列表里寻找对应的服务器的ip地址和端口号,若没有找到,继续寻找系统缓存和路由缓存,若找到则跳转第三步
还没找到的话则请求本地DNS服务器,没有就将域名发送给其他服务器,递归寻找,从根域名服务器开始不断向下递归,直到返回对应的IP地址和端口号,并将其缓存
根据ip地址和端口号,与目标服务器建立TCP连接(三次握手)
这三步并没有被我们看见,然后接下来的事就被我们观察到了
浏览器向服务器发送http请求,并接收返回的响应头和响应体
继续往下看
黄色部分都是浏览器的一些默认行为,其中包括隐藏本来的标签页内容等等
以及下面的Recalculate Style(重新计算样式),Layout(重排)是为清空本来的页面,为新页面做准备
这些不用管它,不过在这中间我们又一次看到了Receive Data
那是因为服务器在发送数据的时候,可能会进行拆包,分几次发送
浏览器比较勤快,它并不会等html完全接收完才开始解析,而是接受一部分就开始解析一部分
HTML Parser的任务是将HTML标记,解析成DOM Tree,这是一个深度遍历的过程,只有Dom下的子节点都被遍历完成,才遍历下一个同级Dom节点
同时,在解析的过程中,如果遇到了图片,link标签,script标签,都会向服务器发送请求
例如我们上图,遇到了百度的logo图片,就请求下载
遇到js就立即解析下载执行执行
不管是内联的还是外部的,都会阻塞后续dom的解析和渲染
所以一般将标签放在后面
如果是外部的,还可以在标签上加上defer或async属性
defer可以让js的下载不影响html的后续解析,且在html解析完了再执行js文件,且按照原来的下载顺序
async也是让js的下载不影响html的后续解析,但一旦下载完了就立即执行,因此也无法保证按照下载顺序执行
遇到内联的css样式就开始解析
外部的css文件,则在接收到了之后进行解析
两者都会不会阻塞Dom的解析,但会阻塞Dom的渲染
这也是为什么要把css的标签放进中
当css文件放在中时,虽然css解析也会阻塞后续dom的渲染,但是在解析css的同时也在解析dom,所以等到css解析完毕就会逐步的渲染页面了
把css语句解析成为CSSOM
渲染布局与绘制在有了Dom Tree和CSSOM之后
浏览器就会构建Render Tree(渲染树)
其实把DOM Tree和CSSOM进行附加
所以Render Tree实际上就是一个计算好了样式,同时不包含display:none之类,不占据空间的元素的的渲染树。
然后浏览器就根据这个Render Tree进行第一次的布局(Layout)以及绘制(Paint)
完成了第一次绘制之后,浏览器会继续收到服务器发来的数据
图片,css文件,js文件
其中可能会有导致页面布局更改或样式更改的内容,都会添加到我们的Render Tree上去
引起重排(Layout)或重绘(Paint)
其中重排一定会连带着引起重绘,反之则不然
重排(Reflow)引起重排的操作
页面首次渲染
浏览器窗口大小发生改变
元素尺寸或位置发生改变
元素内容变化(文字数量或图片大小等等)
元素字体大小变化
添加或者删除可见的DOM元素
激活CSS伪类(例如::hover)
设置style属性
那是遇到一次就重排一次吗?也不是
浏览器会有一个渲染队列来进行优化
积累了一定量或一定时间的更改内容,才会进行重排
不过当访问了特定属性的时候
比如js文件里遇到一句console.log(body.clientWidth)
会强制刷新渲染队列
以下属性的访问会立即刷新渲染队列
widthheight | margin | padding | display | border |
position | overflow | clientWidth | clientHeight | clientTop |
clientLeft | offsetWidth | offsetHeight | offsetTop | offsetLeft |
scrollWidth | scrollHeight | scrollTop | scrollLeft | scrollIntoView() |
scrollTo() | getComputedStyle() | getBoundingClientRect() | scrollIntoViewIfNeeded() |
所以访问这些属性要谨慎,最好分离读写,以免过多的重排影响性能
重绘引起重绘的一般都是修改元素的属性
color | border-style | visibility | background |
text-decoration | background-image | background-position | background-repeat |
outline-color | outline | outline-style | border-radius |
outline-width | box-shadow | background-size |
从性能优化的角度,我们要尽量减少浏览器的重排和重绘,尤其是重排
尽量不要在布局信息改变时做查询(会导致渲染队列强制刷新)
减少DOM操作,同一个DOM的多个属性改变可以写在一起,在一个局部方法中需要多次访问同一个Dom,则先暂存它的引用。批量添加DOM,可以先让元素脱离文档流,操作完后再带入文档流,这样只会触发一次重排(应用fragment元素)
将需要多次重排的元素,position属性设为absolute或fixed,例如有动画效果的元素
采用更优的API替代消费高的API,转换优化消费高的集合,如用querySelectorAll()替代getElementByXX()。
开启动画的GPU加速
少用HTML集合(类数组)来遍历,因为集合遍历比真数组遍历耗费更高。
用事件委托来减少事件处理器的数量。
避免设置大量的style属性,因为通过每一次设置都会触发一次reflow,所以最好是使用class属性
动画实现的速度太精细平滑,会导致reflow过于频繁
不要使用table布局,因为table中某个元素旦触发了reflow,那么整个表格都会reflow。可以设置table-layout:auto;或者是table-layout:fixed这样可以只reflow一行,
减少通过JavaScript代码修改元素样式,尽量使用修改class名方式操作样式或动画;
隐藏在屏幕外,或在页面滚动时,尽量停止动画;
最后大家可以自己去尝试一下performance的使用,可以更直观的理解浏览器的工作流程
参考文章https://segmentfault.com/a/11...
https://segmentfault.com/a/11...
https://sylvanassun.github.io...
https://www.imooc.com/article...
https://segmentfault.com/a/11...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/55022.html
前言 在学习前端的过程中,大家都会对浏览器这个神秘的盒子感到好奇从输入一串url到页面解析渲染完成,浏览器都干了些啥? 直观展示 为了更好的理解这个过程,我们使用一个工具来帮助我们Chrome自带的开发工具中的performance(老版本和其他浏览器为timeline) showImg(https://segmentfault.com/img/bVbswbe?w=1338&h=920); 点击录...
前言 在学习前端的过程中,大家都会对浏览器这个神秘的盒子感到好奇从输入一串url到页面解析渲染完成,浏览器都干了些啥? 直观展示 为了更好的理解这个过程,我们使用一个工具来帮助我们Chrome自带的开发工具中的performance(老版本和其他浏览器为timeline) showImg(https://segmentfault.com/img/bVbswbe?w=1338&h=920); 点击录...
摘要:需要注意的一点是,面板下的功能,是对于细节中的细节进行的优化。我们可以很清晰明了得分析按照活动,目录,域,子域,和进行分组的前端性能。个人理解的话,前者类似事件冒泡,后者类似事件捕获。同学在点我达,他们正在筹划改组成大前端团队。 对Chrome控制台有一定的了解的朋友都在知道,Network面板会包括很多网络请求方面的东西,包括Http相关的Request信息,Response信息...
摘要:但硬件加速是把双刃剑,过渡的使用硬件加速会适得其反。所以,一定要牢记不要让页面的每个元素都使用硬件加速,当且仅当需要的时候才为元素创建渲染层。参考文档无线性能优化动画及硬件加速高性能动画与页面渲染渲染优化层模型 前言 谈起浏览器的硬件加速,想必大家都知道的一个技巧就是在用CSS3做动画时,给元素添加transform: translateZ(0)或者transform: transla...
摘要:但硬件加速是把双刃剑,过渡的使用硬件加速会适得其反。所以,一定要牢记不要让页面的每个元素都使用硬件加速,当且仅当需要的时候才为元素创建渲染层。参考文档无线性能优化动画及硬件加速高性能动画与页面渲染渲染优化层模型 前言 谈起浏览器的硬件加速,想必大家都知道的一个技巧就是在用CSS3做动画时,给元素添加transform: translateZ(0)或者transform: transla...
阅读 884·2021-10-27 14:19
阅读 1101·2021-10-15 09:42
阅读 1523·2021-09-14 18:02
阅读 737·2019-08-30 13:09
阅读 2981·2019-08-29 15:08
阅读 2080·2019-08-28 18:05
阅读 947·2019-08-26 10:25
阅读 2776·2019-08-23 16:28