• 重学前端(4) 浏览器是如何工作的(5)


      在之前的几篇文章中,我们已经经历了把 URL 变成字符流,把字符流变成词(token)流,把词(token)流构造成 DOM 树,把不含样式信息的 DOM 树应用 CSS
    规则,变成包含样式信息的 DOM 树,并且根据样式信息,计算了每个元素的位置和大小。
      那么,最后的步骤,就是根据这些样式信息和大小信息,为每个元素在内存中渲染它的图形,并且把它绘制到对应的位置。
     

    渲染

      定义:把元素变成位图的过程(每个元素对应的盒变成位图,一个元素可能对应多个盒(好比 inline 元素,可能分红多行)

      位图:在内存里创建一张二维表格,把一张图片的每一个像素对应的颜色保存进去(位图信息也是 DOM 树中占据浏览器内存最多的信息,咱们在作内存占用优化时,主要就是考虑这一部分)

      分类:图形和文字java

        图形类:盒的背景、边框、SVG 元素、阴影等特性算法

        文字类canvas:  分类:分为像素字形和矢量字形(会在 6px 8px 等小尺寸提供像素字形,比较大的尺寸则提供矢量字形)

      最广泛的状况下,渲染过程生成的位图尺寸跟它在上一步排版时占据的尺寸相同,不少属性会影响渲染位图的大小,好比阴影,为了优化,浏览器实际的实现中会把阴影做为一个独立的盒来处理

      通常的操做系统会提供一个底层库来支持渲染:Android(Skia)Windows(GDI)浏览器会作一个兼容层来处理掉平台差别

      渲染过程:不会把子元素绘制到渲染的位图上的,当父子元素的相对位置发生变化时,能够保证渲染的结果可以最大程度被缓存,减小从新渲染

      输入框实现:渲染过程除了位图,最终绘制上去还产生一个"热区",这个“热区”不但跟你说的input相关,还跟用户选择、鼠标事件和scroll等交互相关(简单了解一下)

    合成(compositing)

      定义:为一些元素建立一个“合成后的位图”(咱们把它称为合成层),把一部分子元素渲染到合成的位图上面,性能优化行为,非浏览器必须  

      合成的策略:最大限度减小绘制次数,“猜想”可能变化的元素,把它排除到合成以外浏览器

    • 主流浏览器通常根据 position、transform 等属性来决定合成策略,来“猜想”这些元素将来可能发生变化
    • 新的 CSS 标准中,规定了 will-change 属性,能够由业务代码来提示浏览器的合成策略
    // 合成策略可以把 a、b 两个 div 合成,而不把 c 合成
    // 在实际场景中,咱们的 b 可能有不少复杂的子元素,因此当合成命中时,性能提高收益很是之高
    <div id="a">
        <div id="b">...</div>
        <div id="c" style="transform:translate(0,0)"></div>
    </div>
    
    document.getElementById("c").style.transform = "translate(100px, 0)";

    绘制

      定义:把“位图最终绘制到屏幕上,变成肉眼可见的图像”的过程,实际上就是按照 z-index 把它们依次绘制到屏幕

      浏览器不处理,把要显示的位图交给操做系统  

      限制绘制的面积(换一个角度理解重绘repaint):缓存

    • 问题:鼠标划过浏览器显示区域。这个过程当中,鼠标的每次移动,都形成了从新绘制,若是咱们不从新绘制,就会产生大量的鼠标残影
    • 解决:“脏矩形”算法--把屏幕均匀地分红若干矩形区域,从新绘制脏矩形区域时,把全部与矩形区域有交集的合成层(位图)的交集部分绘制便可。
  • 相关阅读:
    多线程 wait和sleep区别
    什么是分布式系统,如何学习分布式系统
    Mybatis传多个参数(三种解决方案)
    UML中类之间的几种关系
    前缀、中缀、后缀表达式
    数据库连接池c3p0和dbcp
    代码收藏
    spark教程(12)-生态与原理
    spark教程(10)-sparkSQL
    spark教程(九)-操作数据库
  • 原文地址:https://www.cnblogs.com/lxl0419/p/16115602.html
Copyright © 2020-2023  润新知