浏览器输入url后发生的过程 1、输入一个url地址 url遵守一定的语法规则:scheme://host.domain:port/path/filename scheme:定义因特网服务的类型(协议),常见的有http,https,file,ftp等 host:定义域主机(http一般默认的是www) demain:定义因特网域名,如baidu.com post:端口号(http一般是80,https一般是443) 2、浏览器会先查看浏览器缓存--系统缓存--路由缓存,如有存在缓存,就直接显示。如果没有,接着第三步 3、浏览器查找域名的ip地址(DNS,域名和ip的映射分布式数据库) 大致可以分为几部: 浏览器缓存 浏览器会缓存DNS记录一段时间,且不同的浏览器的缓存时间不同 系统缓存 如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname)。这样便可获得系统缓存(host)中的记录。 路由器缓存 查询请求发向路由器,它一般会有自己的DNS缓存。 ISP DNS 缓存 ISP是互联网服务提供商(Internet Service Provider)的简称,ISP有专门的DNS服务器应对DNS查询请求。 根服务器(递归搜索) ISP的DNS服务器还找不到的话,它就会向根服务器发出请求,进行递归查询(DNS服务器先问根域名服务器其的IP地址,然后再问.com域名服务器,依次类推) CDN(Content Delivery Network)就是利用DNS的重定向技术,DNS服务器会返回一个跟用户最接近的点的IP地址给用户,CDN节点的服务器负责响应用户的请求,提供所需的内容。 针对DNS的优化大致方向是减少DNS解析的时间,即尽量通过浏览器对dns的缓存机制来减少对ip的查询,即减少需要解析的域名的个数 4、浏览器给web服务器发送一个HTTP(HTTPS)请求 TCP三次握手 浏览器获得 IP 地址后,就会对目标服务器发起建立 TCP 连接的请求,建立连接主要有三个步骤,一般称为客户端与服务器端的三次握手: 第一次握手: 建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认; 第二次握手: 服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态; 第三次握手: 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。 TCP四次挥手 客户端或服务器均可主动发起挥手动作 第一次挥手: 主动关闭方,将FIN置为1,Seq设置为Z为上一次对方传送过来的Ack值,Ack设置为X为Seq值+1。设置好以上值后,将数据发送至被动关闭方(这里标记为:B)。然后A进入FIN_WAIT_1状态。 第二次挥手:B收到了A发送的FIN报文段,向A回复,Ack设置为第一次挥手中的Seq值+1,Seq设置为Y第一次挥手中的Ack值。然后B进入CLOSE_WAIT状态,A收到B的回复后,进入FIN_WAIT_2状态。 第三次挥手:B再次向A发送报文,将FIN置为1,Ack设置为X,Seq设置为Y。然后B进入LAST_ACK状态,A收到B的报文后,进入TIME_WAIT状态。 第四次挥手:A收到B发送的FIN报文段,Ack设置为Y,Seq设置为X。然后A进入TIME_WAIT状态,B在收到报文后进入CLOSED状态,A在发送完报文等待了2MSL时间后进入CLOSED状态。 HTTPS(http+ssl)的非对称加密和对称加密 非对称加密 握手过程中,服务器会发出一张证书(带着公钥),客户端用公钥加密了一段较短的数据S,并返回给服务器。服务器用私钥解开,拿到S。此时,握手步骤完成,S成为了一个被安全传输到对方手中的对称加密密钥。此后,服务器与请求响应,只需要用S作为密钥进行一次对称的加密就好。 证书包含公钥,所以拿到证书意味着就拿到了对方的公钥 对称加密 约定加密密钥,请求的数据用密钥加密,服务器用密钥解密 一次完整的https请求: 1、客户端向服务器发送https请求(443端口) 2、tcp三次握手建立tcp连接 2、服务器端返回一个安全证书(公钥) 3、客户端收到,并进行验证,如果没有问题,就用安全证书(公钥)加密一个随机值。并发送给服务端 4、服务端用私钥解密,拿到该随机值 5、后面的通信就可以通过随机值用对称加密的方式进行了 http默认自带cookie 在http请求中,cookie是默认自带的,可以通过设置cookie的HttpOnly和Secure属性来进行控制,详情请移步 请求头自带的与tcp相关的属性 Connection Connection 头(header) 决定当前的事务完成后,是否会关闭网络连接。如果该值是“keep-alive”,网络连接就是持久的,不会关闭,使得对同一个服务器的请求可以继续在该连接上完成。 在http1.0的时候Connection的值默认为close 在http1.1的时候Connection的值默认为Keep-Alive 浏览器会自发做的事 浏览器能安全的添加斜杠,如www.baidu.com ->www.baidu.com/ ,而www.baidu.com/222 ->www.baidu.com/222不会,因为浏览器… 优化 : 通过部署cdn来减缓数据返回的事件 优化握手次数 在头部设置Accept-Encoding类型,通过返回gzip来减少数据体积 通过设置http缓存来优化性能,请移步 5、永久重定向响应 为了优化搜索引擎,把多个域名进行归类,如把baidu.com,www.baidu.com,www.baidu.com归类 返回301,通知浏览器跳转,有利于SEO 6、浏览器跟踪重定向地址,请求头不变 7、服务器“处理”请求 8、服务器发回一个HTML响应 9、浏览器开始显示HTML 处理HTML标记,构建DOM树。 处理CSS标记,构建CSSOM树。 将DOM树和CSSOM树融合成渲染树(会忽略不需要渲染的dom)。 根据渲染树来布局,计算每个节点的几何信息。 在屏幕上绘制各个节点。 中间遇到各种资源时,会进行资源的下载 可能存在问题: 资源下载 css下载时会阻塞渲染(带有media属性除外,不会阻塞浏览器解析)。 遇到 script 标签时,DOM构建停止,此时控制权移交至js,直到脚本(下载)执行完毕,此时浏览器有优化一般会下载其他资源,但是不会解析。如果js中有对CSSOM的操作,还会先确保CSSOM已经被下载并构建。 图片资源下载不会产生阻塞。 重绘重排导致重新进行渲染树的生成 重排(回流) 会重新计算布局,通常由元素的结构、增删、位置、尺寸变化引起,如:img下载成功后,替换填充页面img元素,引起尺寸变化;也会由js的属性值读取引起,如读取offset、scroll、cilent、getComputedStyle等信息。 重绘 简单外观的改变会引起重绘,如颜色变化等。 重排一定重绘。 优化: dom 简化dom结构,减少DOM树和渲染树构建成本,减少页面元素个数 如使用列表表格数据分页,简单表格不要使用复杂第三方组件等方式。 js 将js脚本标签放在页面body底部,减少对其他过程的阻塞。 延迟执行:对不修改页面的外链script使用defer属性,使脚本并行下载不阻塞,下载后不立刻执行,而在所有元素解析之后执行。 这里简单的介绍下defer和async的区别: 相同点: 加载文件时不阻塞页面渲染 对于inline的script(内联脚本)无效 使用这两个属性的脚本中不能调用document.write方法 有脚本的onload的事件回调 不同点: html的版本html4.0中定义了defer;html5.0中定义了async 每一个async属性的脚本都在它下载结束之后立刻执行,可能会打乱原有的顺序 每一个defer属性的脚本都是在页面解析完毕之后,按照原本的顺序执行 减少和合并不必要的dom相关操作,如使用DocumentFragment、修改classname而不是各项style等,减少对重绘和重排的触发。 css 将css放入head中,提前加载,并防止html渲染后重新结合css引起页面闪烁。 减少css层级和css选择器复杂度,提高解析速度,虽然浏览器有优化。 使用更高性能的css样式,如flex代替float。 开启复合层,如使用3d变换、opacity等,使该元素及其子元素不导致外部的重排,但是也有坑。 合理使用脱离文档流的样式,减少对外部重排的影响,如absolute。 文件数量 减少首次下载的文件数量大小. 使用图片懒加载,js的按需加载等方式,使用storage存储进行js、css文件的缓存(PWA)。 拆分页面资源,首屏数据优先加载等。 动态路由、懒加载 10、浏览器发送获取嵌入在HTML中的静态资源 11、浏览器发送异步(AJAX)请求 简单的介绍下fetch相对于ajax的优缺点 优点 内置promise,链式调用,也可以使用async await来解决回调地狱 res提供了多种转换格式的方法,json(),blob() 缺点 默认不带cookie,带cookie需要指定credentials = include 需要底层支持,或者使用第三方兼容包 不能做超时处理,没有abort方法 遇到常见的错误码不会报错,需要手动去封装
作者:传智播客前端与移动开发培训学院 首发:[url]http://web.itcast.cn[/url]
|