url上接收到 el表达式 不渲染_一文摸透从输入URL到页面渲染的过程

一文摸透从输入URL到页面渲染的过程

从输入URL到页面渲染需要Chrome浏览器的多个进程配合,所以我们先来谈谈现阶段Chrome浏览器的多进程架构。

一、Chrome架构

目前Chrome采用的是多进程的架构模式,可分为主要的五类进程,分别是:浏览器(Browser)主进程、 GPU 进程、网络(NetWork)进程、多个渲染进程和多个插件进程;

79190409e46e762bef110ba118e810d8.png
  • 浏览器进程。主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。
  • 渲染进程。核心任务是将HTML、CSS 和 JavaScript转换为用户可以与之交互的网页,排版引擎Blink和JavaScript引擎V8都是运行在该进程中,默认情况下,Chrome会为每个Tab标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
  • GPU进程。其实,Chrome刚开始发布的时候是没有GPU进程的。而GPU的使用初衷是为了实现3D CSS的效果,只是随后网页、Chrome的UI界面都选择采用GPU来绘制,这使得GPU成为浏览器普遍的需求。最后,Chrome在其多进程架构上也引入了GPU进程。
  • 网络进程。主要负责页面的网络资源加载,之前是作为一个模块运行在浏览器进程里面的,直至最近才独立出来,成为一个单独的进程。
  • 插件进程。主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响

了解了Chrome的多进程架构,就能够从宏观上理解从输入URL到页面渲染的过程了,这个过程主要分为导航阶段渲染阶段

二、导航阶段

Ⅰ.浏览器主进程

1.用户输入URL

  • **1、**浏览器进程检查url,组装协议,构成完整的url,这时候有两种情况: 输入的是搜索内容:地址栏会使用浏览器默认的搜索引擎,来合成新的带搜索关键字的URL。 输入的是请求URL:地址栏会根据规则,给这段内容加上协议,合成为完整的URL;
  • **2、**浏览器进程通过进程间通信(IPC)把url请求发送给网络进程;

Ⅱ.网络进程

2.URL请求过程

  • **3、**网络进程接收到url请求后检查本地缓存是否缓存了该请求资源,如果有则将该资源返回给浏览器进程;

这里涉及到浏览器的缓存策略问题,有兴趣的可以上网查阅相关资料。

  • **4、**准备IP地址和端口:进行DNS解析时先查找缓存,没有再使用DNS服务器解析,查找顺序为: 浏览器缓存; 本机缓存; hosts文件; 路由器缓存; ISP DNS缓存; DNS递归查询(本地DNS服务器 -> 权限DNS服务器 -> 顶级DNS服务器 -> 13台根DNS服务器)
  • **5、**等待TCP队列:浏览器会为每个域名最多维护6个TCP连接,如果发起一个HTTP请求时,这 6个 TCP连接都处于忙碌状态,那么这个请求就会处于排队状态;解决方案: 采用域名分片技术:将一个站点的资源放在多个(CDN)域名下面。 升级为HTTP2,就没有6个TCP连接的限制了;
  • **6、**通过三次握手建立TCP连接: **第一次:**客户端先向服务器端发送一个同步数据包,报文的TCP首部中:标志位:**同步SYN**为1,表示这是一个请求建立连接的数据包;序号Seq=x,x为所传送数据的第一个字节的序号,随后进入SYN-SENT状态; 标志位值为1表示该标志位有效。 **第二次:**服务器根据收到数据包的SYN标志位判断为建立连接的请求,随后返回一个确认数据包,其中标志位SYN=1,ACK=1,序号seq=y,确认号ack=x + 1表示收到了客户端传输过来的x字节数据,并希望下次从x+1个字节开始传,并进入SYN-RCVD状态; 这里要区分标志位ACK和确认号ack; **第三次:**客户端收到后,再给服务器发送一个确认数据包,标志位ACK=1,序号seq=x+1,确认号ack=y+1,随后进入ESTABLISHED状态; 服务器端收到后,也进入ESTABLISHED状态,由此成功建立了TCP连接,可以开始数据传送; 为什么要第三次挥手?避免服务器等待造成资源浪费,具体原因: 如果没有最后一个数据包确认(第三次握手),A先发出一个建立连接的请求数据包,由于网络原因绕远路了。A经过设定的超时时间后还未收到B的确认数据包。 于是发出第二个建立连接的请求数据包,这次网路通畅,B的确认数据包也很快就到达A。于是A与B开始传输数据; 过了一会A第一次发出的建立连接的请求数据包到达了B,B以为是再次建立连接,所以又发出一个确认数据包。由于A已经收到了一个确认数据包,所以会忽略B发来的第二个确认数据包,但是B发出确认数据包之后就要一直等待A的回复,而A永远也不会回复。 由此造成服务器资源浪费,这种情况多了B计算机可能就停止响应了。
  • **7、**构建并发送HTTP请求信息;
  • **8、**服务器端处理请求;
  • **9、**客户端处理响应,首先检查服务器响应报文的状态码: 如果是301/302表示服务器已更换域名需要重定向,这时网络进程会从响应头的Location字段里面读取重定向的地址,然后再发起新的HTTP或者HTTPS请求,跳回第4步。 如果是200,就检查Content-Type字段,值为text/html说明是HTML文档,是application/octet-stream说明是文件下载;
3f1fdd41ec8a43c650c03c8f84fac363.png
  • **10、**请求结束,当通用首部字段Conection不是Keep-Alive时,即不为TCP长连接时,通过四次挥手断开TCP连接:
3e1c0205c7040f62746af768235ebd33.png
  • **第一次:**客户端(主动断开连接)发送数据包给服务器,其中标志位FIN=1,序号位seq=u,并停止发送数据;
  • **第二次:**服务器收到数据包后,由于还需传输数据,无法立即关闭连接,先返回一个标志位ACK=1,序号seq=v,确认号ack=u+1的数据包;
  • **第三次:**服务器准备好断开连接后,返回一个数据包,其中标志位FIN=1,标志位ACK=1,序号seq=w,确认号ack=u+1;
  • **第四次:**客户端收到数据包后,返回一个标志位ACK=1,序号seq=u+1,确认号ack=w+1的数据包。

由此通过四次挥手断开TCP连接。

详细过程参见:详解TCP连接的“三次握手”与“四次挥手”(上)

  • **为什么要四次挥手?**由于服务器不能马上断开连接,导致FIN释放连接报文与ACK确认接收报文需要分两次传输,即第二次和第三次"挥手";

3.准备渲染进程

  • **11、**准备渲染进程:浏览器进程检查当前url是否与之前打开了渲染进程的页面的根域名相同,如果相同,则复用原来的进程,如果不同,则开启新的渲染进程;

4.提交文档

  • **12、**提交文档: 渲染进程准备好后,浏览器渲染进程发起“提交文档”的消息,渲染进程接收到消息后与网络进程建立传输数据的“管道渲染进程接收完数据后,向浏览器发送“确认提交浏览器进程接收到确认消息后更新浏览器界面状态:安全状态地址栏url前进后退的历史状态更新web页面
dc01b784db2682eeefbd5b592c2c07e4.png

三、渲染阶段

在渲染阶段通过渲染流水线在渲染进程的主线程和合成线程配合下,完成页面的渲染;

Ⅲ.渲染进程

86d007a525db64d59ed5d76150fe7a63.png

渲染进程中的主线程部分

5.构建DOM树

  • 13、先将请求回来的数据解压,随后HTML解析器将其中的HTML字节流通过分词器拆分为一个个Token,然后生成节点Node,最后解析成浏览器识别的DOM树结构。 可以通过Chrome调试工具的Console选项打开控制台输入document查看DOM树;

渲染引擎还有一个安全检查模块叫 XSSAuditor,是用来检测词法安全的。在分词器解析出来 Token 之后,它会检测这些模块是否安全,比如是否引用了外部脚本是否符合 CSP 规范是否存在跨站点请求等。如果出现不符合规范的内容,XSSAuditor 会对该脚本或者下载任务进行拦截

首次解析HTML时渲染进程会开启一个预解析线程,遇到HTML文档中内嵌的JavaScript和CSS外部引用就会同步提前下载这些文件,下载时间以最后下载完的文件为准。

cbf7af1c77c1f2028f96801a0459b7d0.png

6.构建CSSOM

  • 14、CSS解析器将CSS转换为浏览器能识别的styleSheets也就是CSSOM:可以通过控制台输入document.styleSheets查看; 这里要考虑一下阻塞的问题,由于JavaScript有修改CSS和HTML的能力,所以,需要先等到 CSS 文件下载完成并生成 CSSOM,然后再执行 JavaScript 脚本,最后再继续构建 DOM。由于这种阻塞,导致了解析白屏

优化方案:

移除js和css的文件下载:通过内联 JavaScript、内联 CSS; 尽量减少文件大小:如通过 webpack 等工具移除不必要的注释,并压缩 js 文件; 将不进行DOM操作或CSS样式修改的 JavaScript 标记上 sync 或者 defer异步引入; 使用媒体查询属性:将大的CSS文件拆分成多个不同用途的 CSS 文件,只有在特定的场景下才会加载特定的 CSS 文件。

可以通过浏览器调试工具的Network面板中的DOMContentLoaded查看最后生成DOM树所需的时间;

ab2f19cabfb52480a8729cea40955571.png
28783baf269642fccfc5a7b24bf3a638.png

7.样式计算

  • **15、**转换样式表中的属性值,使其标准化。比如将em转换为px,color转换为rgb;
  • **16、**计算DOM树中每个节点的具体样式,这里遵循CSS的继承和层叠规则;可以通过Chrome调试工具的Elements选项的Computed查看某一标签的最终样式;
31b5287edd48a7fd1cd38ade15a9bc9a.png

8.布局阶段

  • **17、**创建布局树,遍历DOM树中的所有节点,去掉所有隐藏的节点(比如head,添加了display:none的节点),只在布局树中保留可见的节点。
  • **18、**计算布局树中节点的坐标位置(较复杂,这里不展开);

9.分层

  • **19、**对布局树进行分层,并生成分层树(Layer Tree),可以通过Chrome调试工具的Layer选项查看。分层树中每一个节点都直接或间接的属于一个图层(如果一个节点没有对应的层,那么这个节点就从属于父节点的图层)
6854f4599126459294e44bd7a167e0ee.png

10.图层绘制

  • **20、**为每个图层生成绘制列表(即绘制指令),并将其提交到合成线程。以上操作都是在渲染进程中的主线程中进行的,提交到合成线程后就不阻塞主线程了;
ddd1b33b2f0077e776d066bca6d1ae04.png

渲染进程中的合成线程部分

48820c83e6cf19e190bf58a652d193f4.png

11.切分图块

21、合成线程将图层切分成大小固定的图块(256x256或者512x512)然后优先绘制靠近视口的图块,这样就可以大大加速页面的显示速度;

c1311881440615c66d2528450519fdd7.png

Ⅳ.GPU进程

12.栅格化操作

  • 22、在光栅化线程池中将图块转换成位图,通常这个过程都会使用GPU来加速生成,使用GPU生成位图的过程叫快速栅格化,或者GPU栅格化,生成的位图被保存在GPU内存中。
dd1fa916b1c76be8c6e8ca7ab67a84b3.png

Ⅴ.浏览器主进程

13.合成与显示

  • **23、**合成:一旦所有图块都被光栅化,合成线程就会将它们合成为一张图片,并生成一个绘制图块的命令——“DrawQuad”,然后将该命令提交给浏览器进程。

注意了:合成的过程是在渲染进程的合成线程中完成的,不会影响到渲染进程的主线程执行;

  • **24、**显示:浏览器进程里面有一个叫viz的组件,用来接收合成线程发过来的DrawQuad命令,然后根据DrawQuad命令,将其页面内容绘制到内存中,最后再将内存显示在屏幕上。

到这里,经过这一系列的阶段,编写好的HTML、CSS、JavaScript等文件,经过浏览器就会显示出漂亮的页面了。


作者:AhuntSun
链接:https://juejin.im/post/5e8be3f2f265da47d12914fc
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模拟弱网工具的使用

https://zhuanlan.zhihu.com/p/98185153 https://www.jianshu.com/p/5e35a3585df5 今年5G技术开始铺开并进入商用。随着5G的到来,不知道大家有没有和我一样的感受,希望是我心理作用吧,我发现作为一个4G用户,最近我的手机网速是不…

c语言计算a+aa+aaa_物业服务企业信用等级公布,42家获AAA级!你家小区物业怎么样?...

杭州住保房管 根据《浙江省物业服务企业信用信息管理办法》和《浙江省行业信用监管责任体系构建工作方案》,日前,省建设厅公布了 2020年度浙江省物业服务企业信用等级结果名单,杭州165家物业服务企业上榜,绿城物业服务集团有限公司…

python 可视化_python可视化基础

常用的python可视化工具包是matplotlib,seaborn是在matplotlib基础上做的进一步封装。入坑python可视化,对有些人来说如同望山跑死马,心气上早输了一节。其实学习一门新知识,首先要掌握的是这门知识的最少最核心知识,剩…

使用post访问不到接口_Postman工具使用说明

一、工具说明接口测试工具,支持post,get,请求的接口测试;支持参数中带token,带cookie等接口测试。印度阿三开发的产品,稳定性较好,强烈推荐,屡试很爽。适用:前后端分离的…

java正则表达式判断手机号_正则表达式学习之简单手机号和邮箱练习

正则表达式的组成规则在java中,正则表达式的编译是类java.util.regex.Pattern正则表达式的构造摘要1.字符x包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号的普通字符。比如之前的例子可以将[1-9][0-9]{4,12}改成1[0-9]{4,12}或者a[0-9]{4,12}此时就…

unity 解决引入dlopen api的问题

打包出来的ipa在腾讯的wetest的ios预审中报以下错误。 对于dlopen api, 是苹果禁用的,对Unity项目痛苦的挨个二分排查后,发现很多都有可能引入。 1.和XML或Excel相关的C# API极有可能引入。https://blog.csdn.net/qq_36622009/article/details/10388285…

运营体系_用户运营系统论:解构复杂产品的大规模用户运营体系

本文介绍了大规模用户运营体系中的三大原则——数据驱动、精细化运营、自动化(或叫产品化),以及用户运营体系中的三个子系统——用户生命周期管理系统、用户分层运营系统、用户行为激励系统。我们在实际的产品工作中,经常会用到各种各样的运营体系&#…

ShaderToy效果学习(转成Unity URP) - MathEye

来自IQ大神的小教程,效果图: shaderToy源码:https://www.shadertoy.com/view/lsfGRr 教程视频:https://www.bilibili.com/video/BV1KK4y1K7wM/ Unity项目代码Git地址:https://github.com/Dejavu0709/Graphics.git Sh…

asp 退出登录修改cookie能进入后台_深入浅出让你理解跨域与SSO单点登录原理与技术...

一:SSO体系结构SSOSSO英文全称Single Sign On,单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制。它是目前比较流行的企业业务…

是可改写的随机存储器_关于存储器的一些基础知识整理

RAMRandom-Access-Memory,随机存储存储器,可读可写,分为SRAM和DRAM,即静态随机存储器和动态随机存储器,理解上静动态主要体现是否需要刷新,通常DRAM需要刷新,否则数据将丢失;SRAM的效率较好,而成…

fpga供电电压偏低会怎样_[走近FPGA]之开发板介绍篇

开发板概述在走近FPGA预告篇中,我们已经提到了系列文章使用的开发平台,硬木课堂Xilinx Artix 7 FPGA板,如下图所示。它使用的FPGA芯片型号为Xilinx Artix-7 XC7A75T,具有电平开关、LED、矩阵键盘、数码管等基本外设,同…

使用arm-linux-androideabi-addr2line 定位Unity Android 段错误

arm-linux-androideabi-addr2line是NDK中提供的将内存地址转换成行号的一个工具,通俗具体点就是根据各种日志,譬如trace日志和tomestone日志中包含的so库日志的中偏移内存地址,定位到具体是在那个文件的那一行。Unity的安装目录中&#xff0c…

springboot几种注入_Spring Boot中使用JdbcTemplate访问数据库

本文介绍在Spring Boot基础下配置数据源和通过JdbcTemplate编写数据访问的示例。数据源配置在我们访问数据库的时候,需要先配置一个数据源,下面分别介绍一下几种不同的数据库配置方式。首先,为了连接数据库需要引入jdbc支持,在pom…

搜索重复代码_LeetCode专题——详解搜索算法中的搜索策略和剪枝

今天是LeetCode专题第20篇文章,今天讨论的是数字组合问题。描述给定一个int类型的候选集,和一个int类型的target,要求返回所有的数字组合,使得组合内所有数字的和刚好等于target。注意:所有的元素都是正数所有元素没有…

Unity内实现Android APK版本更新

最近做项目有个需求是要Android应用内强更包体。Google一波直接选了一个android原生开源项目 GitHub - yangchong211/YCUpdateApp: 轻量级版本更新弹窗,弹窗上支持更新进度条,可以设置普通更新或者强制更新。解决8.0以上通知栏不显示问题,解…

a标签隐藏真实地址_家庭影院布线非常杂乱应该怎么补救?A/V电缆管理的7个技巧...

家庭影院应该是给人带来快乐的东西,不管是声音还是外观,但是如果您布的线很杂乱,那么想必整个影院也好看不到哪去,如果你想要整理的话,那么这篇文章应该能帮助到您。有没有整理过家庭影院的电线,观感是完全…

螺钉装弹垫平垫机器人_【经验总结】什么时候用平垫,什么时候用弹垫?

很多人为了节约成本想省了平垫或者弹垫,其实在螺栓使用过程中平垫和弹垫各自起着不可或缺的作用。今天咱们来针对平垫和弹垫给大家介绍一下。左 平 垫 右 弹 垫 平垫,形状一般是一个平垫圈,中间有一个孔,主要是用铁板冲压出来的&a…

生成FaceBook所需的散列哈希值

Hex to base64 converter FaceBook后台发布应用时,需要填入hash值,今天自己用openssl生成的时候只有24位并不正确,与其费劲巴拉的自己折腾openssl,还是感谢国外的大佬们吧,工具网址直接输入hex的sha1值*(从…

打开方式中选择默认方式无反映_「Windows」得看,更改文件的默认应用,告别“打开方式”...

前言:你有没有在使用电脑过程中,打开各种各样格式的文件时,电脑有没有很准确的用你想用的那个软件将其打开?还是说你还在用“打开方式”手动选择你想使用的软件打开你想打开的这个文件。如何设置默认应用:步骤&#xf…

Z深度相关知识

渲染中深度信息很重要,但是也很让人迷惑,透视投影是什么,为什么要做透视除法,view空间,clip空间,ndc空间对应的z值又代表什么,这里简单总结下。 一.顶点变换的完整过程 二.View空间下的顶点和Z…