前端学习篇一:从URL到页面开启重学前端之路
文章来源之前的学习,文中若有错误理解,还请各位大佬指正
认识 URL,认出月老的红线
- 我们认识的
url(Uniform Resource Locator)- 这里感兴趣可以翻译一下英文名顾名思义,嘻嘻
- 格式:
scheme://host.domain:port/path/filename?xxx、- scheme:定义因特网服务的类型,如常见的
http、https - host:定义域主机,
http默认为www - domain:定义因特网域名, xxx.cn xxx.com
- :port:定义主机上的端口号,省略则默认,如http 的默认端口号是 80
- path:定义服务器上的路径,省略则默认根路径
- 这里的 ? 后的
xxx即我们路由跳转时需要携带的一些参数
- scheme:定义因特网服务的类型,如常见的
分析该url后开始DNS解析,抓住月老的红线向前找寻
客户端向DNS请求解析该url的IP地址
- 客户端 以
UDP的形式向 本地域名服务器 发出DNS请求报文 (递归查询) - 本地域名服务器 收到请求后,查询本地缓存,若没有记录,则以 DNS客户的身份向 根域名服务器 发出解析请求报文 (迭代查询)
- 根域名服务器 收到请求后, 判断该域名属于什么域,将对应的 顶级域名服务器 的 IP 地址返回给 本地域名服务器
- 本地域名服务器 向 顶级域名服务器 发起解析请求报文 (迭代查询)
- 顶级域名服务器 收到请求后,判断该域名属于什么域,因此将对应的 授权域名服务器 的 IP地址 返回给 本地域名服务器
- 本地域名服务器 向 授权域名服务器 发起请求解析报文 (迭代查询)
- 授权域名服务器 接收到请求后 将查询结果返回给 本地域名服务器
- 本地域名服务器 将查询结果保存到 本地缓存 ,同时返回给客户机
上面的这些步骤真是让人头大,这里上一张通用的图片助您一臂之力
看着这些眼花缭乱的递归、迭代。
- 其实
DNS查询很容易成为影响前端性能的一个瓶颈,并且每次的DNS查询,都要经历从手机到移动信号塔,再到认证DNS服务器的过程,这需要很长的时间。所以如果有本地缓存,那该多好。幸好我们的浏览器有一个DNS预获取的接口,我们打开浏览器的同时进行就进行配置。请求解析时,即可检查到服务器缓存,不需要在去DNS服务器查询了。- 本地缓存静态资源加载更快,可要让本地缓存发挥上述的作用,需要现在服务器上进行配置
- 本地缓存实现: 本地缓存一般包括强缓存和协商缓存两种
- 强缓存是指浏览器在加载资源时,根据请求头的
expires和cache-control判断是否匹配到客户端的缓存,如果匹配命中,则直接从缓存中读取资源,不发送请求到服务器 - 协商缓存是指浏览器发送请求到服务器后,通过
last-modified和etag验证资源是否命中匹配到客户端的缓存,如果命中,服务器会将请求返回,单单是将这个数据请求返回,浏览器的数据是直接从缓存中读取。若没命中,无论是否是因数据过期还是没有相关的数据,浏览器都需将请求继续发送,等待服务器将数据返回
- 所以为提高 DNS 查询效率,并减少查询报文数量,可在域名服务器 中广泛地使用高速缓存。
域名系统 DNS 解析出 IP 地址的服务器,建立TCP连接(默认端口号为80)
回想我们当初愉快的握手,无情的挥手环节
三次握手
- 客户端向远程的那个服务端发送数据请求:是你吗?
- 服务端接收到请求,向客户端请求响应:没错,是我!
- 客户端接收到响应,向服务端发送确认连接:众里寻你千百度,那我们开始聊天吧!
四次挥手
- 客户端向服务端发送释放连接请求:差不多得了,分手吧!
- 服务端告知应用层要发送TCP释放连接了,并向客户端发送
ACK包并进入CLOSE_wait状态(完成后是服务端无法接收到客户端发送数据了,可TCP连接是双向的,此时服务端还是可以给客户端发送数据的):行吧,ACK给你的分手费,咱俩儿和平分手! - 服务器会继续将没有传完的数据,传给客户端:就当这是上辈子我欠你的,当初说在一起的是你,突然说分手的也是你
- 客户端接收到最后一次数据后,向服务端发起确认断开请求,2ms后如果没有得到应答就自动断开连接:您拨打的电话暂时无人接听。
在一起的日子并不简单 HTTP的请求阻塞 服务端面对客户端的请求:太难啦!
- 浏览器为了保证访问速度,会默认对同一域下的资源保持一定数量的连接数,
HTTP请求过多时就会对请求进行阻塞,浏览器同域名连接的限制请求数一般在6个左右,最多并发6个请求,其他的只能等到一个请求返回后,才能进行下一个。所以域名规划很重要,特别是首屏中需要的域名 - 还有想要解决同域名下的拥塞,可以做域名散列,通过不同的域名,增加请求并行连接数(此处小编并不太懂,请多多指教)。
- 服务端数据处理阶段,将数据从数据存储层取到数据,再返回给客户端。服务端接收到
HTTP请求后,会做一些请求参数的处理和权限的校验校验完,把请求的参数发送到数据存储服务,然后服务端程序会从数据存储中取到数据,进行处理加工,再通过jsonp或ajax接口返回给客户端,这一过程中,存在瓶颈:- Gzip压缩:服务端通常通过Gzip压缩处理文本资源到原来大小的1/3左右,可大大提升客户端页面的展示
- 数据缓存处理:数据缓存分两种,一种借助Service Worker,另一种借助本地接口缓存和CDN。
- Service Worker:其实是浏览器的一个高级属性,本质上是一个请求代理层,它存在的目的就是拦截和处理网络数据请求,避免请求每次都直接落到
WebServer上,而需要走一次后端数据存取链路的流程,延长页面打开时间的问题。 - 本地接口缓存和CDN:借助本地接口缓存,即客户端第一次请求到数据后,就将数据存储到本地存储(
local和localStorage、甚至客户端本身的存储),下一次请求该数据,即可直接到缓存中取,CDN是通过在网络的节点处安装服务器,构造虚拟网络,用户可直接在最近的网络节点上请求数据。此处的瓶颈即是,当请求数据时,每次都需要到后端服务器,再到后端的数据存储层去取数据,再一层一层返回数据给客户端,若请求能够少一层多好
- Service Worker:其实是浏览器的一个高级属性,本质上是一个请求代理层,它存在的目的就是拦截和处理网络数据请求,避免请求每次都直接落到
- 重定向:指网络站点的资源迁移时,用户访问站点时,程序将用户的请求自动迁移到另一个页面。在服务端处理阶段的重定向有三类:(此处小编也不太懂,所以不详解)
- 服务端发挥的302重定向
- META标签实现的重定向
- 前端JavaScript通过window.location实现的重定向 这些都会导致DNS查询到HTTP请求的过程,期间都将更新,严重影响客户端性能
结束这段伤感,浏览器得到了一笔分手费,开始学会渲染自己的生活
浏览器拿到数据进行词法分析(生活的精打细算)
- 分析为一段一段的字符串,并打上标记,标记出那些
div、p、a、i等标签 - 以这些标签作为
node节点,根据这些节点之间的联系构建出DOM树 - 以此也对
CSS文件进行分析,对应的类名、标签名作为节点,根据这些节点的联系,构建出CSSOM树 - 对
CSSOM树进行递归确定具体的元素到底是什么样式 DOM树和CSSOM树即构成了渲染树(render),GPU进程根据该渲染树绘制页面布局,渲染树只包括需要显示的节点