web前端高级JavaScript - 浏览器底层渲染机制及性能优化

浏览器遇到各种资源的加载机制

客户端从服务器获取到需要渲染页面的源代码后,会开辟一个“GUI渲染线程”,自上而下解析代码,最后绘制出对应的页面。
自上而下渲染解析代码的过程是【同步】的,但是有些操作也是异步的:

  • 1.关于CSS资源的加载
    • 遇到的是【style】"内嵌样式”,则“同步”交给GUI渲染线程解析
    • 遇到的是【link】“外链样式”, 则会异步开辟一个新的HTTP网络请求线程,不等资源信息请求回来,而是GUI渲染线程继续往下渲染;等GUI渲染线程同步操作都处理完后,再把基于HTTP网络请求回来的资源文件进行解析渲染(注意:同一个源下,根据不同浏览器,最多只允许同时开辟4~7个HTTP线程“HTTP的并发数”)
    • 遇到@import“导入式样式”,则是“同步”开辟一个新的HTTP网络请求线程去请求资源,但是在资源文件没有请求回来之前,GUI渲染线程会被“阻塞”,不允许其继续向下渲染
  • 2.遇到【script】资源的请求
    • 默认都是同步的,必须基于HTTP网络请求线程,把资源请求回来之后,并且交给“JS渲染线程”渲染解析完成后,GUI渲染线程才能继续向下渲染,所以【script】默认也是“阻塞”GUI渲染的。
    • async属性:遇到【script async】首先也是开辟一个HTTP网络请求线程去请求加载资源文件,但是与此同时GUI渲染线程继续向下渲染[把默认的同步改为异步了],但是一旦当资源请求回来之后,会中断GUI的渲染,先把请求回来的JS进行渲染解析
    • defer属性:遇到【script defer】和async类似,都是新开辟HTTP网络请求线程去请求加载资源文件,与此同时GUI渲染线程还会继续渲染【异步】,但是不一样的是:defer和link类似,是在GUI同步的代码渲染完成后,才会渲染解析请求回来的JS代码
  • 3.遇到【img】或者音频资源
    • 遇到这些资源,也会发送新的HTTP网络线程,请求加载对应的资源文件,不会阻塞GUI的渲染【异步】;当GUI渲染完成后,才会把请求回来的资源进行渲染解析;
  • Webkitl浏览器预测解析:chrome的预测加载扫描器html-preload-scanner通过扫描节点中的“src”、“link”等属性,找到外部连接资源后进行预加载,避免了资源加载的等待时间,同样实现了提前加载以及加载和执行的分离。也就是说在GUI渲染线程渲染之前,浏览器预先找到link等资源预先去请求加载

在这里插入图片描述
在这里插入图片描述

页面渲染步骤

  • DOM TREE(DOM树):自上而下渲染完页面,整理好整个页面的DOM结构关系
  • CSSOM TREE(样式树):当把所有样式资源请求加载回来后,按照引入的CSS顺序,一次渲染样式代码,生成样式树
  • RENDER TREE(渲染树):把生成的DOM树和CSSOM树合并在一起,生成渲染树(设置display:none的元素是不进行处理的)
  • Layout布局/回流/重排:根据生成的渲染树,计算它们在设备视口(viewport)内确切的位置和大小
  • 分层处理:按照层级定位分层处理,每一个层级都会详细规划出具体的绘制步骤
  • Painting:按照每一个层级计算出来的绘制步骤,开始绘制页面

前端性能优化

CRP:关键渲染路径

  • 生成DOM TREE
    • 减少DOM的层级嵌套
    • 不要使用“非标准”标签
  • 生成CSSOM TREE
    • 尽可能不使用@import,会阻塞GUI渲染
    • 如果css代码比较少,尽可能使用style内嵌样式(尤其是移动端开发)
    • 如果使用link,尽可能把所有样式资源合并成一个CSS且压缩,减少HTTP请求数量,以及渲染CSSOM树的时候也不需要再计算依赖关系
    • CSS选择器链短一些,因为CSS选择器渲染是从右到左的
    • 把link等导入CSS的操作放在HEAD中,目的是:一加载页面就开始请求资源,同时GUI去生成DOM树,CSS等资源预先加载
  • 对于其它资源优化
    • 对于script尽可能放在页面底部(防止阻塞GUI渲染);对于部分script需要使用async或defer
      • async是不管JS的依赖关系的,哪一个资源先获取到,就先把这个资源代码渲染执行
      • defer则和link一样,是等待所有script defer都请求回来后,按照导入顺序/依赖关系依次渲染执行
    • 对于img资源
      • 懒加载:第一次加载页面时不要加载图片,哪怕它是异步的,也占据了HTTP并发的数量,导致其它资源延后加载
      • 图片的BASE64:不用请求加载图片,BASE64码基本上代表就是图片,而且页面渲染图片的时候速度也会更快。但慎用(会使代码变很长很长)
    • Layout/Painting:重要的优化手段:减少DOM的回流和重绘
      • 第一次加载页面必然会有一次回流和重绘
      • 触发回流操作后,也必然会触发重绘,如果只是单纯的重绘则不会触发回流;性能优化点重点都在回流上;
      • 样式分离读写,把修改样式和获取样式代码分开
      • 不要自己直接操作DOM,例如VUE/REACT
      • 批量添加DOM元素时尽量不要使用for循环和createElement去一个个添加,可以使用字符串拼接或者使用文档碎片(documentFragment,临时容器)一次性添加,这样只会引发一次回流
      • 把动画等频繁操作样式的操作,运用到position:fixed/absolute上(脱离文档流,单独一层);利用分层机制,如果只改变一个层面上的位置大小信息,浏览器回流和重绘的速度回快很多
      • 修改元素的transform/opacity(filters)不会引发DOM的回流(浏览器硬件加速,缺点耗内存)

在这里插入图片描述

当代浏览器关于回流的渲染队列机制:在当前上下文操作中,遇到一行修改样式的代码,并没有立即通知浏览器渲染,而是把其放在渲染队列中,接下来看是否还有修改样式的代码,如果有继续放在队列中等待,一直到再也没有修改样式的代码后者“遇到一行获取样式的操作”,则会刷新浏览器的渲染队列(也就是把现在队列中修改样式的操作,统一告诉浏览器渲染,这样只会引发一次回流)

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值