当客户端获取代码之后的操作...

52 阅读4分钟

总的来说就是
【开辟一个‘GUI’渲染线程,自上而下解析代码,最后绘制出对应页面】
接下来详细说
自上而下解析代码的过程是同步的,但是有些操作是异步的

  1. 遇到css资源的加载

    • 遇到的是<style> “内嵌样式” =>“同步” 交给GUI渲染线程解析,(大哥自己亲自去渲染)
    • 遇到的是<link> 外链样式 =>“异步” 开辟一个新的“HTTP网络请求线程” (派小弟去,不等小弟,自己的渲染完再去解析小弟的) 
      注意:同一个源下,根据不同的浏览器,最多只允许同时开辟4~7个HTTP线程 “HTTP的并发数” ,可以把http线程想象成小弟,GUI线程是大哥。 不等待资源信息请求回来,GUI渲染线程继续向下渲染
      GUI渲染线程同步操作都处理完成后,再把基于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渲染完成后,才会把请求回来资源信息进行渲染解析;(派小弟去,不等小弟,自己的渲染完再去解析小弟的)

页面的渲染步骤

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

性能优化【CRP关键渲染路径】

  • 生成dom树
    • 减少层级嵌套
    • 不使用非标准的标签
  • 生成om树
    • 尽可能不使用@import
    • 如果css代码较少,尽可能使用‘style内嵌样式’
    • 如果使用link,尽可能把所有的样式资源合并为一个,且压缩(因为http并发性,渲染css的时候也不需要再计算依赖关系)
    • css的选择链短一些(css选择器渲染是从右向左的)
    • 把link等导入css的操作放在head中(一加载就开始请求资源)
  • 对于其他资源的优化
    • 对于script ,尽可能放置再页面底部,防止阻碍GUI渲染
    • 对于img,懒加载,第一次加载页面的时候不要加载请求图片,占据了HTTP的并发数量
  • 重排/重绘
    • 对于第一次绘制,都会经历重排和重绘
    • 重排必然引起重绘,重绘不会引起重排,所以优化重点在重绘
  • 重绘优化
    • 总方法,不要自己去操作Dom,例如vue/react
    • 样式读写分离,把修改样式和获取样式的代码分离开
    • 新增元素:a.文档碎片b.把动画等频发的样式改变的操作,运用到position:fixed/absolute上,脱离文档流,单独一层
    • 修改样式的transform/opacity...,不会引发DOM的回流【弊端是消耗浏览器的内存】