一个页面从输入URL到加载显示完成,发生了什么?

面试经典题——URL加载

一、涉及基本知识点:

1. 计算机网络

  1. 五层因特尔协议栈:

    • 应用层(dns、http):DNS解析成IP并完成http请求发送;
    • 传输层(tcp、udp):三次握手四次挥手模式建立tcp连接;
    • 网络层(IP、ARP):IP寻址;
    • 数据链路层(PPP):将请求数据封装成帧;
    • 物理层:利用物理介质传输比特流(传输的时候通过双绞线、电磁波等)
    • OIS七层框架:多了两层即,会话层(处理两个通信系统中交换信息的表示方式)和表示层(管理不同用户和进程之间的对话)。
  2. get和post的区别

    • get产生一个tcp数据包,post产生两个
    • get请求时会把headers和data数据一起发送出去;
    • post请求时,浏览器先发送headers,服务器100继续,浏览器再发送data。
  3. DNS查询得到IP

    1. 请求信息:首先查看域名的本地DNS缓存,该缓存存储计算机最近检索到的信息,如果计算机不知道答案,那么就需要执行一个DNS查询来查找答案;
    2. 询问递归式DNS服务器:

      • 如果信息不存储在本地,计算机会联系您的ISP(网络提供商)的递归DNS服务器;
      • 这些专用计算机会为你执行一个DNS查询工作;
      • 递归服务器有自己的缓存,所以这个查询过程通常在这里完成,并将信息还回给用户;
    3. 询问根域名服务器

      • 如果递归服务器没有答案,他们会查询根域名服务器;
      • 根域名服务器是一种计算机,它扮演着一种DNS的电话接线员的角色,他们不知道答案,但可以将我们的疑问指向知道在哪里可以找到答案的人。
    4. 询问TLD域名服务器:

      • 根域名服务器将查看请求的第一部分,按从右到左的顺序,从www.dyn.com中找到.com,并将请求指向.com对应的顶级域名服务器(TLD).com;
      • 每个TLD,如(.com,.org,.us)都有自己的顶级域名服务器,
      • 这些服务器没有我们需要的信息,但他们可以直接将我们引导到有信息的服务器。
    5. 询问权威的DNS服务器

      • TLD域名服务器会继续检查请求的下一部分(dyn)www.dyn.com,并将查询指向负责此特定域名的服务器;
      • 这些权威的服务器将负责了解关于特定域的所有信息,并将信息存储在DNS记录。
    6. 找回记录:
      -递归服务器从权威服务器中检索dyn.com的记录,并将记录存储在本地缓存;

      • 如果其他任何人请求dyn.com的主机记录,递归服务器已经有答案了,并不需要再次进行查找;
      • 所有记录都有一个期限,一段时间后,递归服务器将需要要求一个新的记录副本,以确保信息不回过时。
    7. 接收答案:

      • 有了答案,递归服务器将记录返回到计算机,
      • 您的计算机将记录存储在缓存中,从记录中读取IP地址,然后将这些信息传递给浏览器;
      • 然后浏览器就可以根据IP地址和服务器进行连接建立。
  4. TCPIP请求

    • http的本质就是TCPIP请求;
    • 需要经历3次握手建立连接,4次挥手断开连接;
    • TCP将http长报文划分为短报文,通过三次握手与服务器端建立连接,进行可靠传输。
    • 三次握手:

      • 客户端:你是XXX服务端吗?
      • 服务端: 我是XXX服务端,你是客户端吗?
      • 客服端: 是的,我是客户端
      • 建立连接成功后,接下来就可以进行正式的传输数据。
    • 四次挥手断开连接

      • 主动方:我已经关闭了向你那边的信息发送通道,只能被动接受信息了;
      • 被动方: 收到通道关闭的信息;
      • 被动方: 我现在也关闭了向你那边发送信息的通道
      • 主动方: 左后收到信息,连接断开,之后双方无法通信
  5. TCP/IP的并发限制:

    • 浏览器对同一个域名下并发的TCP连接是有限制的(2-10个不等)
    • 而且在http1.0中往往一个资源的下载就需要一个tcp/ip请求

2. 浏览器机制

(1)进程和线程的概念

  1. 进程是CPU资源分配的最小单位,是能拥有资源和独立运行的最小单位;
  2. 线程是CPU调度的最小单位,线程是建立在进程的基础上的一次程序运行单位,一个进程可以拥有多个线程;
  3. 通俗的讲:进程是一个工厂,工厂有它独立的资源,工厂之间相互独立->进程之间相互独立,线程是工厂中的工人,多个工人之间可以协作完成任务,工厂内有一个或多个工人,工人之间共享空间。

(2)多进程的浏览器

浏览器是多进程的,有一个主控进程,以及每一个tab页面都会开一个进程(某些情况下多个tab由于优化策略会合并)
  • 浏览器主要进程:
  1. Browser进程:浏览器的主进程,负责协调、主控,只有一个,作用:

    • 负责浏览器界面的显示、与用户交互(如前进、后退等)
    • 负责各个页面的管理,创建和销毁其他进程;
    • 将Renderer进程得到的内存中的Bitmap绘制到用户界面上
    • 网络资源的管理和下载等
  2. 第三方插件进程: 每种类型的插件对应一个进程,仅当该插件使用时才创建;
  3. GPU进程: 最多一个,用于3D绘制等;
  4. 浏览器渲染进程(Renderer进程、浏览器内核、内部是多线程)

    • 默认没打开一个tab页面,就会启动一个Renderer进程;
    • 负责页面的渲染,脚本的执行,事件的处理。
  • 浏览器多进程的优势

    1. 避免单个page crash影响整个浏览器;
    2. 避免第三方插件crash影响整个浏览器
    3. 多进程充分利用多核优势;
    4. 方便使用沙盒模型隔离插件等进程,提高浏览器稳定性
简单点理解:如果浏览器是单进程,那么某个tab页或第三方插件崩溃了,就会导致整个浏览器崩溃,体验度极差,不过多进程内存消耗会更大,有点用空间换时间。

浏览器内核(渲染进程)

  • 浏览器渲染进程内部是多线程,包含主要线程有:

1.GUI渲染线程:

  • (1)负责浏览器界面的渲染,解析HTML、CSS,构建DOM树和RenderObject树,布局和绘制等;
  • (2) 当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时该线程会执行;
  • 注意:GUI渲染线程和JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会保存在一个队列中等JS引擎空闲时立即执行。

2.JS引擎线程:

  • JS内核,负责处理JavaScript脚本程序(V8引擎)
  • 负责解析JavaScript脚本,运行代码;
  • JS引擎一直等待着任务队列中的任务到来,然后加以处理,一个tab页面(renderer进程)中无论什么时候都只有一个JS线程在运行JS程序;
  • 注意:由于GUI渲染线程和JS引擎线程是互斥的,所以如果JS程序运行时间过长,这样会导致页面渲染不连贯,导致页面渲染加载阻塞;

3.事件触发线程:

  • 归属于浏览器,而不是JS引擎,用来控制事件循环;
  • 当JS引擎执行代码块如setTimeOut时(也可以来自浏览器内核的其他线程,如鼠标单击事件、AJAX异步请求等),会将对应的任务添加到事件线程中;
  • 当对应的事件符合触发条件被触发时,该线程就会把事件添加到JS的待处理队列的队尾,等待JS引擎的处理;
  • 注意:由于JS的单线程的关系所以这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去执行)。

4.定时触发器线程:

  • setTimeOut与setInterval所在的线程;
  • 浏览器的定时计数器并不是由JavaScript引擎计数的,(因为JavaScript是单线程,如果处于阻塞状态就会影响计时的准确)因此通过单独的线程来计时并触发定时(计时完毕后,添加到事件队列,等待JS引擎空闲时执行)

5.异步http请求线程:

  • 在XMLHttpRequest在连接后是通过浏览器新开一个线程请求的
  • 将检测到状态变更时,如果设置有回调函数,异步线程就将产生状态变更事件,将这个回调在放到事件队列中,再由JavaScript引擎执行。

一、 一个页面从输入URL到加载显示完成,这个过程发生了什么?

  • 简洁版:

    • 浏览器根据请求的URL交给DNS域名解析,找到真实的IP,向服务器发起请求;
    • 服务器交给后台处理完成后返回数据,浏览器接收文件(HTML、CSS、JavaScript等);
    • 浏览器对加载到的资源(HTML、CSS、JavaScript等)进行语法解析,构建相应的内部数据结构(DOM树、CSS树、render树等);
    • 载入解析到的资源文件、渲染页面、完成。
  • 详细版:

    1. 首先浏览器开启一个线程来处理这个请求,对URL分析判断,如果是http协议就按照Web方式来处理;
    2. 其次浏览器会对URL进行解析,一般包括(协议头、主机域名或IP地址、端口号、请求路径、查询参数、hash等),然后开启网络线程发出一个完整到http请求;
    3. 当然一般我们输入的URL是服务器域名,这时就需要DNS通过域名查询得到对应的IP;
    4. DNS首先会查看浏览器DNS缓存,没有就查询计算机本地DNS缓存,还没有就询问递归式DNS服务器(即网络提供商,一般这个服务器都会有自己的缓存,所以IP查询一般在这里完成),如果没有缓存,那就需要通过根域名和TLD域名服务器指到对应的权威DNS服务器找回记录,并缓存到递归式服务器,然后递归服务器在将记录返回给本地。
    5. 有了IP地址,此时网络层便会通过IP地址寻的对应服务器的物理地址
    6. 寻得服务器地址,客户端在网络传输层便可以和服务器通过三次握手建立tcpip连接
    7. 连接建立后网络数据链路层将数据包装成帧;
    8. 最后物理层利用物理介质进行传输;
    9. 到了服务器,就会通过相反的方式将数据一层一层的还原回去;
    10. 请求到了后台服务器,一般会有统一的验证,如安全验证、跨域验证等,验证未通过就直接返回相应的http报文
    11. 验证通过后,就会进入后台代码,此时程序收到请求,然后执行对应的操作(如查询数据库等);
    12. 如果浏览器访问过,且缓存上有对应的资源,便会与服务器最后修改时间对比,一致便返回304,告诉浏览器可使用本地缓存;
    13. 前端浏览器接收到响应成功的报文后便开始下载网页
    14. 下载完的网页将被交给浏览器内核(渲染进程)进行处理:

      1. 根据顶部定义的DTD类型进行对应的解析方式;
      2. 渲染进程内部是多线程的,网页的解析将会被交给内部的GUI渲染线程处理;
      3. 首先渲染线程中的HTML解释器,将HTML网页和资源从字节流解释转换成字符流;
      4. 再通过词法分析器将字符流解释成词语;
      5. 之后经过语法分析器根据词语构建成节点;最后通过这些节点组建一个DOM树;
      6. 这个过程中,如果遇到的DOM节点是JavaScript代码,就会调用JavaScript引擎对JavaScript代码进行解释执行,此时由JavaScript引擎和GUI渲染线程的互斥,GUI渲染线程就会被挂起,渲染过程停止;如果JavaScript代码的运行中对DOM树进行了修改,那么DOM的构建需要从新开始;
      7. 如果节点需要依赖其他资源,如(图片,CSS等),便会调用网络模块的资源加载器来加载它们,但它们是异步的,不会阻塞当前DOM树的构建;
      8. 如果遇到的是JavaScript资源URL(没有标记异步),则需要停止当前DOM的构建,直到JavaScript的资源加载并被JavaScript引擎执行后才继续构建DOM;
      9. 对于CSS,CSS解释器会将CSS文件解释成内部表示结构,生成CSS规则树;
      10. 然后合并CSS规则树和DOM树,生成render渲染树;
      11. 最后对render树进行布局和绘制,并将结果通过IO线程传递给Browser控制进程进行显示。

原文地址:https://segmentfault.com/a/1190000014872028


更多专业前端知识,请上 【猿2048】www.mk2048.com

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

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

相关文章

mysql文件软连接失败,解决打包软链接打包失败问题

一般情况下打包文件时,如果直接打包软连接会导致打包失败,即没有将要打包的内容打包进去,这里提供tar打包参数-h[rootlocalhost ~]# ll /etc/rc.locallrwxrwxrwx. 1 root root 13 Nov 24 00:45 /etc/rc.local -> rc.d/rc.local[rootlocalh…

快速掌握前端 专为Java程序员定制

Javascript 例子 修改页面内容 js 代码位置 <script>// js 代码 </script>引入 js 脚本 <script src"js脚本路径"></script>注意&#xff0c;到了框架之后&#xff0c;引入方式会有不同 1. 变量与数据类型 声明变量 1) let ⭐️ l…

实施Jersey 2 Spring集成

Jersey是Oracle提供的出色的Java JAX-RS规范参考实现。 去年&#xff0c;当我们开始为大容量网站构建RESTful后端Web服务时&#xff0c;我们选择使用JAX-RS API作为我们的REST框架和Spring框架来进行依赖项注入。 泽西岛是我们选择的JAX-RS实现。 项目启动时&#xff0c;JAX-R…

Solidity中如何判断mapping中某个键是否为空呢?

Solidity中如何判断mapping中某个键是否为空呢&#xff1f; 一.比较标准的做法是建立一个专门和value相关的结构体&#xff0c;用一个布尔型变量来看是否这个key所对应的value被赋过值 代码如下&#xff1a; pragma solidity ^0.4.19;contract UserTest {struct User{string na…

Angular网络请求的封装

很多时候&#xff0c;我很喜欢angular的编码风格&#xff0c;特别是angular支持typescript之后&#xff0c;完整的生命周期&#xff0c;完美的钩子函数&#xff0c;都是别的语言所无法替代的。这里我来说说我自己的网络请求封装&#xff0c;某种意义上来说&#xff0c;angular自…

mac安装了多版本php 卸载,mac 安装多版本PHP

前言相信大家在mac 安装PHP多版本的时候也遇到了很多坑# brew install php56# brew install php70这样安装的话肯定会报错的&#xff0c;因为brew存在软连接这个时候我们第一步&#xff1a;brew unlink php56 或者 brew unlink php70这个步骤是关闭掉PHP的软连接第二步&#x…

新国标电动自行车目录库

浙江&#xff1a;https://xzsp.zjidb.com/api/bicycle 上海&#xff1a;http://www.shbicycle.com/info.asp 北京&#xff1a;http://wfcxjk1.bjjtgl.gov.cn/fjdcml/fjdcListM.jsp 安徽&#xff1a;http://ddch.aqi.ah.cn/index_GB17761-1999.asp 3C查询&#xff1a;http://ccc…

HTML | CSS | JavaScript 常见错误

持续更新 超链接鼠标悬浮后的状态 a:hover 拼写图片文件的路径问题转载于:https://www.cnblogs.com/lcchy/p/10139389.html

隐藏的东西? 您需要HiddenSidesPane

我的甘特图用户之一希望在屏幕上使用尽可能多的空间&#xff0c;并询问是否可以删除滚动条。 但是&#xff0c;如何在没有滚动条的情况下进行导航&#xff1f; 好的&#xff0c;有各种各样的键盘快捷键&#xff0c;当然还有FlexGanttFX支持的普通鼠标拖动&#xff0c;但是大多数…

jQuery的on绑定click和直接绑定click区别

状况之外 在之前的公司并没有遇到这个问题&#xff0c;也就没有深究。直到自己换了现在的公司&#xff0c;刚来第二天就开始写别人写到一半的项目&#xff0c;很无奈&#xff0c;不是原生就是jquery&#xff0c;由于项目急&#xff0c;已经来不及切换框架重新布局&#xff0c;只…

php教程哪个软件好,写php用哪款软件好?解决方法

写php用哪款软件好&#xff1f;现在用php-eclipse&#xff0c;但是感觉不太好用js、html、css的提示功能没有&#xff0c;要装插件&#xff0c;装了很久没装上。想问一下现在开发php哪款软件好大家指导一下&#xff0c;谢谢------解决方案--------------------如果要js、html、…

循环数组对象 php,PHP循环遍历stdClass对象的数组

我有一个在MySQL中运行的查询,它返回一个结果作为stdClass对象,如下所示&#xff1a;array(8){[0]>object(stdClass)#36(1){["color"]>string(7)"#a0a0a0"}[1]>object(stdClass)#35(1){["color"]>string(7)"#e0e0e0"}[2]&…

js实现复制粘贴功能

在项目中使用到复制粘贴功能&#xff0c;虽然网上有很多大牛封装了很多的插件&#xff0c;但是还是想不去使用插件&#xff0c;就像自己来实现这个功能。 初步想法&#xff1a; 1. 获取到需要复制的内容&#xff0c;这里我可以将需要复制的内容放在input或者textarea的value中&…

Thymeleaf与Spring集成(第1部分)

1.引言 本文重点介绍如何将Thymeleaf与Spring框架集成。 这将使我们的MVC Web应用程序能够利用Thymeleaf HTML5模板引擎&#xff0c;而不会丢失任何Spring功能。 数据层使用Spring Data与mongoDB数据库进行交互。 该示例包含在酒店的单页Web应用程序中&#xff0c;从中我们可以…

html注释快捷键

1.选中需要注释的内容--->ctrlshift/ 2.取消注释--->ctrlshift\ 转载于:https://www.cnblogs.com/wyhluckdog/p/10131898.html

Java中转发(Forward)和重定向(Redirect)的区别

从URL来说&#xff0c;转发的地址栏没有发生改变&#xff0c;而重定向则是新的URL从数据共享来说&#xff0c;转发可以共享request域里面的数据&#xff0c;而重定向则不能。效率来说转发效率高&#xff0c;重定向效率低转发一般用来登陆后转发到对应模块&#xff0c; 重定向一…

oracle 老白,老白学编程 - Netdata学习 - numa

Numa 介绍NUMA,即Non-Uniform Memory Access Architecture&#xff0c;非统一内存访问架构。背景传统的SMP中&#xff0c; 所有处理器共享系统总线&#xff0c;当cpu数目增大时&#xff0c; 系统总现竞争就相应增加&#xff0c;会成为系统的瓶颈&#xff0c;所以SMP系统的CPU数…

几个非常实用的JQuery代码片段

jQuery是一个兼容多浏览器的javascript库&#xff0c;核心理念是write less,do more(写得更少,做得更多)。jQuery使用户能更方便地处理HTML&#xff08;标准通用标记语言下的一个应用&#xff09;、events、实现动画效果&#xff0c;并且方便地为网站提供AJAX交互。jQuery还有一…

编码的喜悦……以及Java中的变异测试

多年以来&#xff0c;为源代码编写单元测试一直是一种好习惯。 并且还可以使用测试覆盖率报告来查看测试覆盖了多少代码。 尽管行分支覆盖率报告非常有用&#xff0c;但是它并不能告诉您单元测试的实际效果。 因此&#xff0c;甚至在测试中没有一个断言的情况下&#xff0c;甚至…

错误1083:配置成在该可执行程序中运行的这个服务不能执行该服务 【解决办法】...

一直好用的服务程序&#xff0c;今天遇到这个问题&#xff0c;搜了一下各位给出的解决办法&#xff1b; 1.程序里多添加serviceInstaller组件的&#xff0c;然而我并没改代码&#xff0c;也没重新编译&#xff0c;不是解决我问题的办法&#xff1b; 2.修改注册表的&#xff0c;…