最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 浏览器渲染过程,重绘和回流

    正文概述 掘金(CV菜菜子)   2021-04-05   572

    浏览器渲染原理,重绘和回流

    相关经典题目: 浏览器的输入栏中,输入一个url地址,到呈现页面经历了什么事情?

    1. 浏览器向服务器发送请求。

    1. 包括DNS解析、HTTP、HTTPS、TCP等。
    2. 服务器返回给客户端indecx.html页面中的源码。
    3. 浏览器会分配一个线程“自上而下,自左而右”依次解析和渲染代码。
    4. 浏览器是多线程,页面渲染是单线程(JS是单线程)[具体可以看事件循环的文章]

    2. 向下解析渲染遇到样式(CSS)时

    1.行内样式

    
    <body>
        	<h1 style = "color:white;background-color:blue">
        		This is a line of Text.
        	</h1>
        	<h1 style="color:red;">style属性的应用</h1>
            <p  style="font-size:14px;color:green;">直接在HTML标签中设置的样式</p>
    </body>
    
    
    1. 使用style属性引入CSS样式。
    2. 特点:
    • (1)内联样式放在代码中的HTML元素中。
    • (2)使用内联样式时,样式只会影响你选择的元素。
    • (3)内联样式没有选择器

    2. style内嵌样式

    <!DOCTYPE>
    <html>
    <head>
      <meta charset="utf-8" />
      <title>内部样式表</title>
      <!--使用内部样式表引入CSS-->
      <style type="text/css">
        div{
            background: green;
        }
      </style>
    </head>
    <body>
         <div>我是DIV</div>
    </body>
    </html>
    
    1. 被放置在样式标签<styletype="text/css">编写的网页的头部部分中。

    2. 正常从上到下解析(解析完再继续解析DOM解构)

    3. 同步加载。

    4. 优化:在真实项目中,如果CSS样式代码不是很多(或者是移动端项目),我们应该使用内嵌式,以此来减少HTTP资源的请求,提高页面的渲染速度。 可以先把首屏的样式写内嵌,其他的写link加载。

    5. 嵌入方式的 CSS 只对当前的网页有效。因为 CSS 代码是在 HTML 文件中,所以会使得代码比较集中,当我们写模板网页时这通常比较有利。因为查看模板代码的人可以一目了然地查看 HTML 结构和 CSS 样式。因为嵌入的 CSS 只对当前页面有效,所以当多个页面需要引入相同的 CSS 代码时,这样写会导致代码冗余,也不利于维护。

    3. link导入外部样式资源(链接式)

    <head>
    <link rel="stylesheet" type="text/css" href="css.css">
    </head>
    <body>
        	<h1>
        		This is a line of Text.
        	</h1>
    </body>
    
    
    1. 在页面加载过程中,如果遇到Link, 浏览器会新开辟一个线程,去服务器加载对应的资源(不会阻碍主线程的渲染)
    2. 属于异步加载。
    3. 这是最常见的也是最推荐的引入 CSS 的方式。使用这种方式,所有的 CSS 代码只存在于单独的 CSS 文件中,所以具有良好的可维护性。并且所有的 CSS 代码只存在于 CSS 文件中,CSS 文件会在第一次加载时引入,以后切换页面时只需加载 HTML 文件即可。

    4. @import导入

    
    <head>
    <style>
    	@import url("css.css");
    </style>
    </head>
    <body>
        	<h1>
        		This is a line of Text.
        	</h1>
    </body>
    
    
    1. 此时不会开辟新的线程去加载资源文件,而是让主线程去加载获取,这样阻碍了DOM解构的继续渲染;
    2. 只有等把外部样式导入进来,并且解析后,才会继续渲染DOM解构
    3. 属于同步编程(所以用异步的link 比较好)。如果规定了,先把谁的样式导入进来,才能进行之后的,可以考虑@import。
    4. 两者都是外部引用CSS的方式,但是存在一定的区别:
    • 区别1:link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS。

    • 区别2:link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。

    • 区别3:link是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持。

    • 区别4:link支持使用Javascript控制DOM去改变样式;而@import不支持。

    几种方式的优先级

    答:行内样式>内部样式>外部样式(后两者是就近原则)

    另外一个方面:选择器优先级

    优先级:ID选择器>类选择器>标签选择器

    什么时候用哪种方式比较好??

    网络资源请求数(HTTP最大并发数)?

    浏览器渲染过程,重绘和回流

    1. 大部分浏览器都维持在6个左右。(当超过6个,其他的要排队等着处理了)
    2. 优化:为了避免并发的上线,导致某些资源要延迟加载,页面渲染的速度变慢,我们应该尽可能减少HTTP的请求数量。(减少HTTP的请求数)

    3. 页面加载过程中遇到js(JS中会有操作DOM的代码)

    (1)默认

    1. 主线程会从服务器获取到js资源,并且把js资源进行解析加载,加载完成后再继续渲染DOM结构。
    经典问题:为什么把css(link)写在结构的上面,script写在结构底部?
    => link在顶部:为了让css快点加载回来  
    
    => script 在底部是为了获取DOM元素或者不阻碍DOM的渲染。
    
    1. 现在浏览器的扫描机制:

    如果遇到script需要同步加载和渲染的代码,浏览器在渲染JS的时候,同事会向下继续扫描代码,如果发现有一些异步资源代码,此时开始加载。

    因为在JS中还有可能操作元素的样式,所以哪怕都是异步请求资源的情况下,JS代码先加载回来,也要等到在他之前发送的CSS加载并渲染完成后才会执行JS代码。

    (2)想把js想css一样,用另外一个线程单独处理

    可以设置defer或者async: 都是异步获取资源(不会阻碍DOM的渲染)

    => defer

    如果设置了defer:可以遵循原有的加载顺序,获取后按照顺序去依次渲染JS

    => async

    如果设置async: 是无序的(谁先获取到,谁先执行)

    4. DOMContentLoaded和load事件

    DOMContentLoaded事件

    1. 当DOM结构加载完成,就会触发这个事件
    2. DOM树有了,并且JS也执行加载了,此时触发这个事件

    load事件

    1. 当所有资源都加载完才会触发这个
    2. 包含了需要等待图片等资源也都加载完才触发这个。

    5. jQuery中(function())或者(function())或者(function())或者(document)

    1. 当dom结构加载完,才会执行函数中的代码。
    2. 原理就是应用DOMContentLoaded事件,但在低版本浏览中不兼容。
    3. 可以使用onreadystatechange事件代替,在这个事件中监听document.readyState值,为complete代表DOM结构加载完成。

    回流和重绘

    浏览器渲染的过程

    1. 解析HTML,生成DOM树,解析CSS,生成CSSOM树
    2. 将DOM树和CSSOM树结合,生成渲染树(Render Tree)
    3. Layout(回流): 根据生成的渲染树,计算它们在设备视口(viewport)内的确切位置和大小,这个计算的阶段就是回流
    4. Painting(重绘): 根据渲染树以及回流得到的几何信息,得到节点的绝对像素
    5. Display:将像素发送给GPU,展示在页面上

    浏览器渲染过程,重绘和回流

    Layout(回流):

    1. 定义:元素的大小或者位置发生了变化(当页面布局和几何信息发生变化的时候),触发了重新布局,导致渲染树重新计算布局和渲染。
    2. 举例:
      • 如添加或删除可见的DOM元素 ;
      • 元素的位置发生变化;
      • 元素的尺寸发生变化;
      • 内容发生变化(比如文本变化或图片被另一个不同尺寸的图片所替代);
      • 页面一开始渲染的时候(这个无法避免);
      • 因为回流是根据视口的大小来计算元素的位置和大小的,所以浏览器的窗口尺寸变化也会引发回流....

    Painting(重绘):

    1. 定义:元素样式的改变(但宽高、大小、位置等不变)
    2. 举例:如 outline, visibility, color、background-color等

    注意:回流一定会触发重绘,而重绘不一定会回流

    从输入url到看到页面,一定经过一次回流和重绘

    前端性能优化之:避免DOM的回流

    放弃传统操作dom的时代,基于vue/react开始数据影响视图模式

    mvvm / mvc / virtual dom / dom diff ......
    

    分离读写操作 (现代的浏览器都有渲染队列的机制)

    offsetTop、offsetLeft、offsetWidth、offsetHeight、clientTop、clientLeft、clientWidth、clientHeight
    scrollTop、scrollLeft、scrollWidth、scrollHeight、getComputedStyle、currentStyle....
    会刷新渲染队列
    

    样式集中改变

          div.style.cssText = 'width:20px;height:20px;'
          div.className = 'box';
          
            let nav =document.getElementById('nav')
         // 有渲染队列机制,统一渲染一次,引发一次回流
        nav.style.width = '100px';
        nav.style.height = '100px'
        //触发2次,  
        nav.style.width = '100px';
        console.log(nav.clientWidth)
        nav.style.height = '100px'
    

    缓存布局信息

              div.style.left = div.offsetLeft + 1 + 'px';     div.style.top = div.offsetTop + 1 + 'px';
               =>改为(获取的值用变量存起来了)
              var curLeft = div.offsetLeft;   var curTop = div.offsetTop;
              div.style.left = curLeft + 1 + 'px';    div.style.top = curTop + 1 + 'px';
    

    元素批量修改

    1. 文档碎片:createDocumentFragment
        //10次
        for (let i =0;i <10 ;i++){
            let span = document.createElement('span');
            nav.sppendChild(span)
        }
        // 1次
        let frag = document.createDocumentFragment();
        for (let i =0;i <10 ;i++){
            let span = document.createElement('span');
            frag.appendChild(span)
        }
        nav.sppendChild(frag)
        //1次
        let str =``;
        for (let i =0;i <10 ;i++){
            str + = `<span></span>`;
           
        }
        nacBox.innerHTML = str
    

    动画效果应用到position属性为absolute或fixed的元素上(脱离文档流)

    CSS3硬件加速(GPU加速)

    1. 比起考虑如何减少回流重绘,我们更期望的是,根本不要回流重绘;
    2. transform \ opacity \ filters ... 这些属性会触发硬件加速,不会引发回流和重绘......
    3. 可能会引发的坑:过多使用会占用大量内存,性能消耗严重、有时候会导致字体模糊等

    牺牲平滑度换取速度

    1. 每次1像素移动一个动画,但是如果此动画使用了100%的CPU,动画就会看上去是跳动的,因为浏览器正在与更新回流做斗争。
    2. 每次移动3像素可能看起来平滑度低了,但它不会导致CPU在较慢的机器中抖动

    避免table布局和使用css的javascript表达式


    起源地下载网 » 浏览器渲染过程,重绘和回流

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元