起因
看了一篇文章《阿里面试官的”说一下从url输入到返回请求的过程“问的难度就是不一样!》
打算好好补一下这方面的细节和计算机网络的知识
从进程的角度看问题
浏览器进程:
用户输入内容,进行URL 解析(编码)
- 如果是文本,则拼接成默认搜索引擎加关键字的 URL 进行搜索(现代浏览器功能)
- 如果是 URL 就进行页面访问请求,并加上协议头(http、https 的区别)
网络进程:
- 查询缓存(缓存相关知识)
- 如果有浏览器本地缓存可用则使用本地缓存
- DNS 解析(DNS 相关)
- 通过 DNS 来查询 IP 地址
- DNS 先查本地、后查运营商、逐级网上查。(域名解析是从后往前查的)
- 拿到 IP 地址发起 HTTP 请求(这块可以问网络相关各种基础知识,TCP、IP、UDP、HTTPS、HTTP2)
- 建立 TCP 三次握手连接
- 如果是 HTTPS 建立 TLS 安全通道连接(HTTPS 加密方式)
- 发送 HTTP 请求,这个请求可能回到代理服务器或者源服务器。(服务器代理)
- 拿到 HTTP 响应(HTTP 响应码)
- 根据 Content-Type 来判断响应文件类型(常用 HTTP 响应头的作用)
• stream 类,浏览器启动下载界面下载文件。
• text、图片类,浏览器直接展示在页面上
• html 类型,浏览器会进行页面解析。
渲染进程:
- 页面解析
- 网络进程向渲染进程传输 HTML 数据
- 对 HTML 进行词法分析,通过堆栈算法构建 DOM 树。(AST语法树)
- 如果遇到外部资源,浏览器会交给网络进程去下载。
- 构建完 DOM 树的同时,将 CSS 代码转为浏览器可以理解的 StyleSheets
• 标准化样式属性值(单位、大小)
• 计算出 DOM 树每个节点的具体样式
• 计算每个 DOM 节点的父节点们的样式(样式继承) - DOM 树构建完成后,合并 StyleSheets 构建出 CSSOM 渲染树。
- 排版:遍历渲染树,计算元素的坐标位置。
- 分层:为节点生成图层
- 绘制:用浏览器指令逐条绘制页面元素。(如何避免重绘重排)
- 栅格化
- 合成
文章评论区有人总结的点,我觉得比较清晰了
要点
-
为什么要进行URL解析?
网络标准规定了URL只能是数字和字母还有一些特殊符号,如果不转义会出现歧义。 -
url编码的规则是什么?
URL编码又称百分号编码,交给浏览器自己决定。使用Javascript先对URL编码,然后再向服务器提交,不要给浏览器插手的机会。因为Javascript的输出总是一致的,所以就保证了服务器得到的数据是格式统一的。(参考阮老师的《关于URL编码》) -
dns的解析流程(浅析DNS域名解析过程)
第一步:检查浏览器缓存中是否缓存过该域名对应的IP地址
第二步:如果在浏览器缓存中没有找到IP,那么将继续查找本机系统是否缓存过IP
第三步:向本地域名解析服务系统发起域名解析的请求(校园网、移动、电信或联通运营商)大部分的解析工作到这里就差不多已经结束了,负责了大部分的解析工作。
第四步:向根域名解析服务器发起域名解析请求
第五步:根域名服务器返回gTLD域名解析服务器地址(Generic top-level domain通用顶级域)gTLD是国际顶级域名服务器,如.com、.cn、.org等,全球只有13台左右
第六步:向gTLD服务器发起解析请求
第七步:gTLD服务器接收请求并返回Name Server服务器(找到对应的域名服务器将承担域名解析的任务,例如用户在某个域名服务提供商申请的域名)
第八步:Name Server服务器返回IP地址给本地服务器
第九步:本地域名服务器缓存解析结果
第十步:返回解析结果给用户 -
如何做html的dns优化?
<link rel="dns-prefetch" href="http://www.spreadfirefox.com/">
// a标签默认启动在https无效需要设置开启
<meta http-equiv="x-dns-prefetch-control" content="on">
DNS Prefetch 是一种DNS 预解析技术,当你浏览网页时,浏览器会在加载网页时对网页中的域名进行解析缓存,这样在你单击当前网页中的连接时就无需进行DNS的解析,减少用户等待时间,提高用户体验。
- 从网卡把数据包传输出去到服务器发生了什么?(OSI参考模型Open System Interconnection Model)(OSI参考模型解析)
问题本质就是搞懂OSI参考模型的职能:
- 物理层的主要功能是完成相邻节点之间原始比特流的传输,用物理信号来表示数据。物理层常用的网络设备有中继器和集线器。
- 数据链路层的主要功能是在不可靠的物理线路上进行数据的可靠传输,为了保证数据的可靠传输,发送方把数据封装成帧的形式。数据链路层的常用网络设备有网桥,交换机,网卡等。
- 网络层的主要功能是完成网络中主机间的报文传输,它对应的是网络主机到网络主机的报文传输。该层常用的网络设备有路由器,三层交换机等。
- 传输层的主要功能是完成网络中不同主机上的用户进程之间可靠的数据通信,传输层是真正的端到端的连接。实质也是传输数据,只不过它对应的直接是进程与进程之间的数据传输,它依据的是进程的端口号。
- 会话层允许不同机器上的用户之间建立会话关系。会话层提供的服务之一是管理对话控制。
- 表示层关心的是所传送信息的语法和语义。表示层就是对数据的解码,解释成程序都能理解的程序语言。
- 应用层的功能就是将解码后的计算机程序语言表示出来,从而展示给用户,实现用户操作计算机程序的目的。
参考:探究!一个数据包在网络中的心路历程
- 关于缓存
- HTTP缓存:强缓存(Expires、Cache-Control)协商缓存(Etag/If-None-Match、Last-Modified/If-Modified-Since)
- 浏览器缓存:本地小容量缓存(Cookie、LocalStorage、SessionStorage)本地大容量缓存(WebSql、IndexDB)
- 应用程序缓存:应用缓存、PWA
from memory cache和from disk cache分别指从内存和硬盘读取缓存,浏览器会优先去内存里读取缓存。隐私模式、base64图片等通常从内存读取,特征快、时效性。
- 解析html
cssom + doomTree = html,然后布局和绘制
- 构建DOM树(DOM tree):从上到下解析HTML文档生成DOM节点树(DOM tree);
- 构建CSSOM(CSS Object Model)树:加载解析样式生成CSSOM树;
- 执行JavaScript:加载并执行JavaScript代码(包括内联代码或外联JavaScript文件);
- 构建渲染树(render tree):根据DOM树和CSSOM树,生成渲染树(render tree);
- 渲染树:按顺序展示在屏幕上的一系列矩形,这些矩形带有字体,颜色和尺寸等视觉属性;
- 布局(layout):根据渲染树将节点树的每一个节点布局在屏幕上的正确位置;
- 绘制(painting):遍历渲染树绘制所有节点,为每一个节点适用对应的样式,这一过程是通过UI后端模块完成;
- 页面渲染优化
- HTML文档结构层次尽量少,最好不深于六层;
- 脚本尽量后放,放在前即可;
- 少量首屏样式内联放在标签内;
- 样式结构层次尽量简单;
- 在脚本中尽量减少DOM操作,尽量缓存访问DOM的样式信息,避免过度触发回流;
- 减少通过JavaScript代码修改元素样式,尽量使用修改class名方式操作样式或动画;
- 动画尽量使用在绝对定位或固定定位的元素上;
- 隐藏在屏幕外,或在页面滚动时,尽量停止动画;
- 尽量缓存DOM查找,查找器尽量简洁;
- 涉及多域名的网站,可以开启域名预解析
心得
确实是比较全面的一道题了,典型的从点到面。牵扯到网络请求、缓存、渲染等等问题,甚至可以聊tcp的三次握手,水太深了。
P.S.懒狗本质太久没整理了,忙碌起来还是要抽个时间沉淀一下,后面可能想到啥写啥吧。
网友评论