JavaScript深入浏览器的渲染原理

news/2024/10/20 1:00:44

网页的解析过程

输入域名-->DNS域名解析-->IP地址-->找到对应的服务器-->服务器会返回一个html文件-->解析html文件如果遇到link标签下载CSS文件并解析,同时继续解析html文件,如果遇到script标签下载js文件并解析等到js文件下载解析好了以后继续解析html并生成DOMTree,等到css解析完成以后会形成CSSOMTree并且与DOMtree结合形成RenderTree-->RenderTree再进行布局和绘制最终出现在屏幕上

渲染页面的详细流程

解析一:HTML解析过程

◼ 因为默认情况下服务器会给浏览器返回index.html文件,所以解析HTML是所有步骤的开始:
◼ 解析HTML,会构建DOM Tree:

解析二–生成CSS规则

◼ 在解析的过程中,如果遇到CSS的link元素,那么会由浏览器负责下载对应的CSS文件:注意:下载CSS文件是不会影响DOM的解析的;
◼ 浏览器下载完CSS文件后,就会对CSS文件进行解析,解析出对应的规则树:我们可以称之为CSSOM(CSS Object Model,CSS对象模型);

script元素和页面解析的关系

◼ 我们现在已经知道了页面的渲染过程,但是JavaScript在哪里呢?事实上,浏览器在解析HTML的过程中,遇到了script元素是不能继续构建DOM树的;它会停止继续构建,首先下载JavaScript代码,并且执行JavaScript的脚本;只有等到JavaScript脚本执行结束后,才会继续解析HTML,构建DOM树;
◼ 为什么要这样做呢?这是因为JavaScript的作用之一就是操作DOM,并且可以修改DOM;如果我们等到DOM树构建完成并且渲染再执行JavaScript,会造成严重的回流和重绘,影响页面的性能;所以会在遇到script元素时,优先下载和执行JavaScript代码,再继续构建DOM树;
◼ 但是这个也往往会带来新的问题,特别是现代页面开发中:在目前的开发模式中(比如Vue、React),脚本往往比HTML页面更“重”,处理时间需要更长;所以会造成页面的解析阻塞,在脚本下载、执行完成之前,用户在界面上什么都看不到;
◼ 为了解决这个问题,script元素给我们提供了两个属性(attribute):defer和async。

defer和async属性

defer属性

◼ defer 属性告诉浏览器不要等待脚本下载,而继续解析HTML,构建DOM Tree。脚本会由浏览器来进行下载,但是不会阻塞DOM Tree的构建过程;如果脚本提前下载好了,它会等待DOM Tree构建完成,在DOMContentLoaded事件之前先执行defer中的代码;
◼ 所以DOMContentLoaded总是会等待defer中的代码先执行完成<script src="./js/test.js" defer></script>◼ 另外多个带defer的脚本是可以保持正确的顺序执行的。
◼ 从某种角度来说,defer可以提高页面的性能,并且推荐放到head元素中;
◼ 注意:defer仅适用于外部脚本,对于script默认内容会被忽略

async属性

◼ async 特性与 defer 有些类似,它也能够让脚本不阻塞页面。
◼ async是让一个脚本完全独立的:浏览器不会因async 脚本而阻塞(与defer 类似);async脚本不能保证顺序,它是独立下载、独立运行,不会等待其他脚本;async不会能保证在DOMContentLoaded之前或者之后执行;
◼ defer通常用于需要在文档解析后操作DOM的JavaScript代码,并且对多个script文件有顺序要求的;
◼ async通常用于独立的脚本,对其他脚本,甚至DOM没有依赖的

解析三–构建Render Tree

◼ 当有了DOM Tree和CSSOM Tree后,就可以两个结合来构建Render Tree了
◼ 注意一:link元素不会阻塞DOM Tree的构建过程,但是会阻塞Render Tree的构建过程这是因为Render Tree在构建时,需要对应的CSSOM Tree;
◼ 注意二:Render Tree和DOM Tree并不是一一对应的关系,比如对于display为none的元素,压根不会出现在render tree中;

解析四–布局(layout)和绘制(Paint)

◼ 第四步是在渲染树(Render Tree)上运行布局(Layout)以计算每个节点的几何体。渲染树会表示显示哪些节点以及其他样式,但是不表示每个节点的尺寸、位置等信息;布局是确定渲染树中所有节点的宽度、高度和位置信息;
◼ 第五步是将每个节点绘制(Paint)到屏幕上在绘制阶段,浏览器将布局阶段计算的每个frame转为屏幕上实际的像素点;包括将元素的可见部分进行绘制,比如文本、颜色、边框、阴影、替换元素(比如img)

回流和重绘解析

回流

◼ 理解回流reflow:(也可以称之为重排)第一次确定节点的大小和位置,称之为布局(layout)。之后对节点的大小、位置修改重新计算称之为回流。
◼ 什么情况下引起回流呢?比如DOM结构发生改变(添加新的节点或者移除节点);比如改变了布局(修改了width、height、padding、font-size等值)比如窗口resize(修改了窗口的尺寸等)比如调用getComputedStyle方法获取尺寸、位置信息;
◼ 理解重绘repaint:第一次渲染内容称之为绘制(paint)。之后重新渲染称之为重绘。
◼ 什么情况下会引起重绘呢?比如修改背景色、文字颜色、边框颜色、样式等;

重绘

◼ 回流一定会引起重绘,所以回流是一件很消耗性能的事情。
◼ 所以在开发中要尽量避免发生回流:
◼ 1.修改样式时尽量一次性修改比如通过cssText修改,比如通过添加class修改
◼ 2.尽量避免频繁的操作DOM我们可以在一个DocumentFragment或者父元素中将要操作的DOM操作完成,再一次性的操作;
◼ 3.尽量避免通过getComputedStyle获取尺寸、位置等信息;
◼ 4.对某些元素使用position的absolute或者fixed并不是不会引起回流,而是开销相对较小,不会对其他元素造成影响。

合成和性能优化

特殊解析–composite合成
◼ 绘制的过程,可以将布局后的元素绘制到多个合成图层中。这是浏览器的一种优化手段;
◼ 默认情况下,标准流中的内容都是被绘制在同一个图层(Layer)中的;
◼ 而一些特殊的属性,会创建一个新的合成层(CompositingLayer),并且新的图层可以利用GPU来加速绘制;因为每个合成层都是单独渲染的;
◼ 那么哪些属性可以形成新的合成层呢?常见的一些属性:3D transformsvideo、canvas、iframeopacity 动画转换时;position: fixedwill-change:一个实验性的属性,提前告诉浏览器元素可能发生哪些变化;animation 或 transition 设置了opacity、transform;
◼ 分层确实可以提高性能,但是它以内存管理为代价,因此不应作为web 性能优化策略的一部分过度使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/73632.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Codeforces Round 979 (Div. 2)题解记录

比赛链接:https://codeforces.com/contest/2030 A. A Gift From Orangutan 肯定最小值和最大值放前面最好,答案得解#include<iostream>#include<string.h>#include<map>#include<vector>#include<set>#include<unordered_set>#include&l…

AI工人操作行为流程规范识别系统

AI工人操作行为流程规范识别系统利用高清监控摄像头覆盖现场作业区域,AI工人操作行为流程规范识别系统通过图像识别和深度学习技术对作业人员的操作行为进行实时分析。AI工人操作行为流程规范识别系统能够准确识别工人的操作行为是否符合作业标准规定的流程和合规SOP,并根据设…

高级程序语言课第三次作业

2024高级语言程序设计:https://edu.cnblogs.com/campus/fzu/2024C 高级语言程序设计课程第三次个人作业:https://edu.cnblogs.com/campus/fzu/2024C/homework/13284 学号:102400115 姓名:洪育豪 作业内容:编写并运行书本第4章4.8编程练习题目中的第2题到第4题,第6题到第8题 编…

传送带下料口堵塞识别检测系统

传送带下料口堵塞识别检测系统利用AI视觉识别算法,传送带下料口堵塞识别检测系统通过现场监控摄像头对传送带的运输物料过程进行实时分析和识别。传送带下料口堵塞识别检测系统能够准确判断下料口是否出现堵塞现象,并及时抓拍有关图像进行记录。传送带下料口堵塞识别检测系统…

React/Vue 实现的前端应用, java/Go/Python 实现的后端应用,前后端分离的应用部署的最佳实践

前后端分离的应用(React 前端 + Java 后端)在部署过程中,需要考虑性能、扩展性、安全性、以及维护方便性等多个方面。下面我将详细介绍前后端分离应用的最佳实践,从架构设计、构建和打包、部署策略、CI/CD 集成、安全性措施等几个角度来描述。 微服务架构图示例壹.总体概述…

gradle配置代理

下载gradle项目 访问:https://start.spring.io/如上图所示,生成代码 配置代理服务器 买个国外的节点,使用 xshell 带代理方式连接,会暴露出 socks://localhost:1080建议开启 BBR 拥塞控制 # 要确保 linux 内核版本是4.9或更高,否则后面不用做了 uname -r # 加载 TCP BBR 模…

《使用Gin框架构建分布式应用》阅读笔记:p88-p100

《用Gin框架构建分布式应用》学习第6天,p88-p100总结,总计13页。 一、技术总结 1.MongoDB CRUD操作 (1)InsertOne(), InsertMany() (2)Find() (3)UpdateOne, UpdateMany() (4)DeleteOne(), DeleteMany() 2.MongoDB primitive p96,recipe.ID = primitive.NewObjectID() 中的…

在blender中打开pmx文件

适用blender版本: 3.6 - 4.0 - 4.1 - 4.2 等 本人使用的blender版本为3.6 和 4.2 这里用3.6作案例下载cats插件在github中查找cats-blender-plugin 比如说这个:https://github.com/absolute-quantum/cats-blender-plugin下载最新的插件 注意: 插件版本只对应相应的blender版本…