浏览器页面渲染机制及简单优化

浏览器的内核是指支持浏览器运行的最核心的程序,分为两个部分:

  1:渲染引擎

  2:JS引擎

目前市面上常见的浏览器内核可以分为这四种:Trident(IE)、Gecko(火狐)、Blink(Chrome、Opera)、Webkit(Safari)

页面加载过程要点如下:

  1:浏览器根据DNS服务器得到域名的IP地址

  2:向这个IP的机器发送HTTP请求

  3:服务器收到、处理并返回HTTP请求

  4:浏览器得到返回内容

浏览器渲染过程:

  1:浏览器会解析三个东西:

    ①、HTML/SVG/XHTML,HTML字符串描述了一个页面的结构,浏览器会把HTML结构字符串解析转换DOM树形结构

    ②、解析CSS会产生CSS规则树,他和DOM结构比较像

    ③、Javascript脚本,等到Javascript脚本文件加载后,通过DOM API和CSSOM API来操作DOM Tree和Rule Tree

  2:解析完成后,浏览器引擎会通过DOM Tree和CSS Rule Tree来构造Redering Tree

    ①、Rendering Tree渲染树并不等同于DOM树,渲染树只会包括需要显示的节点和这些节点的样式信息

    ②、CSS的Rule Tree主要是为了完成匹配并把CSS Rule附加上Rendering Tree上的每个Element(也就是每个Frame)

    ③、然后,计算每个Frame的位置,这又叫layout和reflow过程

  3:最后通过调用操作系统Native GUI的API绘制

构建DOM:

  1:浏览器读取HTML的原始字节,并根据 文件的制定编码(例如UTF-8)将他们转换成字符串

  2:将字符串转换成Token

  3:生成节点对象并构建DOM

构建CSSOM:

  DOM会捕获页面的内容,但浏览器还需要知道页面如何展示,所以需要构建CSSOM。(与构建DOM的过程相似)

  注意:CSS匹配HTML元素是一个相当复杂和有性能问题的事情,所以,DOM树要小,CSS尽量用id和class,千万不要过渡层叠下去。

构建渲染树:

  当我们生成DOM树和CSSOM树以后,就需要将这两棵树组合为渲染树。在这一过程中,不是简单的将两者合并就行了。渲染树只会包括需要显示的节点和这些节点的样式,如果某个节点是display:none的,那么久不会再渲染树中显示。

浏览器如果渲染过程中遇到JS文件怎么处理:

  渲染过程中,如果遇到<script>就停止渲染,执行JS代码。因为浏览器渲染和JS执行共用一个线程,而且这里必须是单线程操作,多线程会产生渲染DOM冲突。JavaScript的加载、解析与执行回阻塞DOM的构建,也就是说,在构建DOM时,HTML解析器若遇到了JavaScript,那么它会暂停构建DOM,将控制权移交给JavaScript引擎,等JavaScript引擎运行完毕,浏览器再从中断的地方恢复DOM构建。

  也就是说,如果你想首屏渲染的越快,就越不应该在首屏中加载JS文件,这也是都建议将script标签放在body标签底部的原因,当然在当下,并不是说script标签必须放在底部,因为你可以给script标签添加defer或者async属性

JS文件不只是阻塞DOM的构建,他也会导致CSSOM也阻塞DOM的构建:

  因为JavaScript不只是可以改DOM,还可以更改样式,也就是他可以更爱CSSOM。因为不完整的CSSOM是无法使用的,如果JavaScript想访问CSSOM并更改他,那么在执行JavsScript时,必须要能拿到完整的CSSOM。所以就导致了一个现象,如果浏览器善为完成CSSOM的下载和构建,而我们却想在此时运行脚本,那么浏览器将延迟脚本执行和DOM构建,直至完成CSSOM的下载和构建。也就是说,在这种情况下,刘安琪会先下载和构建CSSOM,然后再执行JavaScript,最后在继续构建DOM。

布局与绘制:

  当浏览器生成渲染树以后,就会根据渲染树来进行布局(也可以叫做回流)。这一阶段浏览器要做的事情是要弄清楚各个节点在页面中的确切位置和大小。通常这一行为也被称为“自动重排”。布局流程的输出是一个“盒模型”,它会精确的捕获每个元素在视口内的确切位置和尺寸,所有相对测量值都将转换为屏幕上的绝对像素。布局完成后,浏览器会立即发出“Paint Setup”和"Paint"时间,将渲染树转换成屏幕上的像素

补充说明:

  1、async和defer的作用是什么?有什么区别

    ①:<script src="script.js"></script>

      没有defer或async,浏览器会立即加载并执行制定的脚本,也就是说不等后续载入的文档元素,读到就加载并执行。

    ②:<script async src="script.js"></script>

      async属性表示异步执行引入的JavaScript,与defer的区别在于,如果已经加载好,就会开始执行-----如论此刻是HTML解析阶段还是DOMContentLoaded触发之后。需要注意的是,这种方式加载的JavaScript依然会阻塞load时间。换句话说,async-script可能在DOMContentLoaded触发之前或之后执行,但一定在load触发之前执行

    ③:<script defer src="script.js"></script>

      defer属性表示延迟执行引入的JavaScript,即这段JavaScript加载时HTML并未停止解析,这两个过程是并行的。整个document解析完毕且defer-script也加载完成之后(这两件事的顺序无关),会执行所有由defer-script加载的JavaScript代码,饭后触发DOMContentLoaded事件。

    defer与普通script相比,有两点区别:载入JavaScript文件时不阻塞HTML的解析,执行阶段被放到HTML标签解析完成之后;在加载多个JS脚本的时候,async是无顺序的加载,而defer是有顺序的加载。

为什么操作DOM慢

  因为DOM是属于渲染引擎中的东西,而JS又是JS引擎中的东西,当我们用JS去操作DOM的时候,本质上就是JS引擎和渲染引擎之间进行了“跨界交流”,而这个交流需要依赖桥接接口作为“桥梁”,所以我们每次操作DOM(不管是为了修改还是仅仅为了访问其值),都要过一次“桥”,就会产生比较明显的性能问题。因此现在很多js框架都会减少DOM节点操作也存在这个原因。

说说两个概念,一个是Reflow,另一个是Repaint

  重绘:当我们对DOM的修改导致了样式的变化、却并未影响其集合属性(比如修改了颜色或背景)时,浏览器不需要重新计算元素的集合属性、直接为该元素绘制新的样式(跳过了回流环节)

  回流: 当我们队DOM的修改引发了DOM几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,浏览器需要重新计算元素的几何属性(其他元素的几何属性和位置也会因此受到影响),然后再将计算的结果绘制出来,这个过程就是回流(也叫重排)

  回流必定会发生重绘,重绘不一定会引发回流

常见引起回流属性的方法:

  1、添加或删除可见的DOM元素

  2、元素尺寸改变----边距、填充、边框、宽度和高度

  3、内容变化,比如用户在input框中输入文字

  4、浏览器窗口尺寸改变----resize事件发生时

  5、计算offsetWidth和offsetHeight属性

  6、设置style属性的值

常见引起重绘属性和方法:

  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

如何减少回流、重绘:

  1、使用transform替代top

  2、使用visibility替换display:none,因为前者只会引起重绘,后者会引发回流(改变了布局)

  3、不要把节点的属性值放在一个循环里当成循环里的变量

  4、不要使用table布局,可能很小的一个改动会造成整个table的重新布局

  5、动画实现的速度的选择,动画速度越快,回流次数越多,也可以选择使用requestAnimationFrame

  6、CSS选择符从右往左匹配查找,避免节点层级过多

  7、将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点。比如对于video标签来说,浏览器会自动将该节点变为图层

性能优化策略:

  1、JS优化:<script>标签加上defer属性或async属性,用于在不阻塞页面文档解析的前提下,控制脚本的下载和执行。。defer属性:用于开启新的线程下载脚本文件,并使脚本在文档解析完成后执行。

  2、CSS优化:<link>标签的rel属性中的属性值设置为preload能够让你在你的HTML页面中可以指明那些资源是在页面加载完成后即刻需要的,最优的配置加载顺序,提高渲染性能

总结:

  1、浏览器工作流程:构建DOM->构建CSSOM->构建渲染树->布局->绘制

  2、CSSOM会阻塞渲染,只有当CSSOM构建完毕后才会进入下一个阶段构建渲染树

  3、通常情况下DOM和CSSOM是并行构建的,但是当浏览器遇到一个不带defer或async属性的script标签时,DOM构建将暂停,如果此时又恰巧浏览器尚未完成CSSOM的下载和构建,由于JavaScript可以修改CSSOM,所以需要等CSSOM构建完毕后再执行JS,最后才重新DOM构建。

原文地址:https://www.cnblogs.com/chao202426/p/10717689.html

时间: 2024-12-10 05:02:50

浏览器页面渲染机制及简单优化的相关文章

转---JS 一定要放在 Body 的最底部么?聊聊浏览器的渲染机制

作者:德来 segmentfault.com/a/1190000004292479 如有好文章投稿,请点击 → 这里了解详情 一.从一个面试题说起 面试前端的时候我喜欢问一些看上去是常识的问题.比如:为什么大家普遍把<script src=""></script>这样的代码放在body最底部?(为了沟通效率,我会提前和对方约定所有的讨论都以chrome为例) 应聘者一般会回答:因为浏览器生成Dom树的时候是一行一行读HTML代码的,script标签放在最后面就不

浏览器的渲染机制,白屏和FOUC

关于浏览器的渲染机制,先要了解一些基本概念: DOM:浏览器解析html构建DOM树 CSSOM:浏览器解析CSS构建CSSOM规则树 Render Tree:DOM和CSSOM合并后生成Render Tree layout:layout:有了Render Tree,浏览器已经能知道网页中有哪些节点.各个节点的CSS定义以及他们的从属关系,从而去计算出每个节点在屏幕中的位置 painting:按照算出来的规则,通过显卡,把内容画到屏幕上 reflow(回流):当浏览器发现某个部分发生了点变化影响

浏览器的渲染机制

Google Web Fundamentals 是一个非常优秀的文档,里面讲到了跟web.浏览器.前端的方方面面.我总结一下其中的 Ilya Grigorik 写的 Critical rendering path 浏览器渲染机制部分的内容如下: 几个概念 1.DOM:Document Object Model,浏览器将HTML解析成树形的数据结构,简称DOM. 2.CSSOM:CSS Object Model,浏览器将CSS代码解析成树形的数据结构. 3.DOM 和 CSSOM 都是以 Byte

你该了解的页面渲染原理与性能优化

首先,你应该了解的就是,浏览器是如何渲染一个页面的. 先看一个大致的流程图 它的总体流程是这样的: 1)浏览器解析这三个东西: 解析HTML/XHTML/SVG,生成DOM树(事实上,Webkit有三个C++的类对应这三类文档以用于解析). 解析css文件产生CSS Rule树(css规则树). 解析javascript,通过DOM API和CSSOM API来操作DOM树和CSS Rule树. 2)解析完成后,浏览器会根据DOM树和CSS Rule树来构造渲染树(Rendering Tree)

html页面渲染的原理及优化

一个html网页载入的大概过程 1.用户输入网址,(假定是第一次访问),浏览器向服务器发出请求,服务器返回html文件. 2.浏览器开始载入html代码,发现head标签内有一个link标签引用外部css文件. 3.浏览器又发出css文件的请求,服务器返回这个css文件. 4.浏览器继续载入<body>里面的代码,并且css代码已经拿到手了,开始渲染界面了. 5.浏览器在代码中发现了一个<img>标签引用了一张图片,向服务器发出请求,浏览器不会等到图片下载完,而是继续渲染后面的代码

前端进阶——浏览器页面渲染过程

一 .构建 DOM 和 CSSOM 树 浏览器渲染页面前需要先构建 DOM 和 CSSOM 树. 浏览器解析过程大概经过:字节 → 字符 → 令牌 → 节点 → 对象模型. 浏览器处理html页面的方式如下图: 1.转换:浏览器从磁盘或网络读取HTML的原始字节,并根据文件指定的编码将它们转换成各个字符 2.令牌化:浏览器将字符串转换成W3C HTML5标准规定的各种令牌(节点) 3.词法分析:发出的令牌转换成定义其属性和规则的对象 4.DOM构建:根据标记之间的关系构建dom 整个流程的最终输

浏览器的渲染机制— (js基础复习第3期)

一:几个问题 什么是DOCTYPE 及作用 浏览器渲染过程 重排refolw.重绘repaint.布局Layout 输入url经历了什么? 二:整理 1. 什么是DOCTYPE 及作用 浏览器使用DTD(文档类型定义)来判断文档类型,决定使用何种协议来解析, 以及切换浏览器模式 DOCTYPE是用来声明文档类型和DTD规范的,一个主要用途是文件的合法性验证.如果文件代码不合法,那么浏览器解析时便会出一些差错. html5 <!DOCTYPE html> 2.浏览器渲染过程 html->

JS一定要放在Body的最底部么? 聊聊浏览器的渲染机制

请参看文章 https://segmentfault.com/a/1190000004292479 网上的回答: 1.js加载会阻塞其它内容加载,使页面加载时间更长,尤其是js文件太大,有的页面js文件数兆/客户端网速太慢/服务器网速太慢,甚至不能访问等情况. 2.dom操作,页面没提前加载,dom操作会失败,报错. 3.搜索引擎优化.

从文档流角度理解浏览器页面渲染引擎对元素定位的解析

文档流:将窗体自上而下分成一行一行,并在每行中按从左至右的挨次排放元素,即为文档流. 我们在排列元素时,遵循"流式结构",即元素遵循从上向下,从左向右堆叠的规则,所以我们在排列元素时如果每行从左往右的元素的总宽度大于窗口的宽度时,就会默认换行. 有三种状况将使得元素离开文档流而存在,分别是浮动.绝对定位.固定定位. 浮动时,离开文档流后的元素,不占用文档流的空间,不会被文档流中的元素发现,离开文档流元素后面的还在文档流上元素会自动上来填补位置接上文档流.此时,离开文档流的元素如同浮在文