浏览器会开启一个线程处理URL请求
url从输入到展示页面的过程
1、输入网址
2、DNS解析
3、建立tcp连接(请求队列queuing、请求等待stalled
4、客户端发送HTPP请求
5、服务器处理请求
6、服务器响应请求
7、浏览器下载资源并展示HTML
8、浏览器发送请求获取其他在HTML中的资源。
1.DNS解析出ip地址
DNS(域名系统,Domain Name System)解析是互联网上将人类可读的域名(例如 www.example.com
)转换为机器可读的 IP 地址(例如 192.0.2.1
)的过程。这个过程对于访问网站至关重要,因为它允许用户的设备找到托管网站的服务器。以下是 DNS 解析的一般步骤:
-
用户输入 URL:
用户在浏览器地址栏输入一个 URL,浏览器首先需要找到这个域名对应的 IP 地址。 -
查询本地 DNS 缓存:
- 浏览器首先检查自己的 DNS 缓存,看看是否已经有了这个域名的 IP 地址。如果缓存中存在,解析过程结束。
-
操作系统 DNS 缓存:
- 如果浏览器缓存中没有找到,操作系统会检查自己的 DNS 缓存。
-
路由器 DNS 缓存:
- 接下来,查询可能会被转发到本地网络路由器的 DNS 缓存。
-
ISP DNS 服务器:
- 如果以上缓存都没有命中,查询会被发送到互联网服务提供商(ISP)的 DNS 服务器。
-
根 DNS 服务器:
- ISP 的 DNS 服务器会检查请求是否属于其缓存中已有的记录。如果没有,它会将请求转发到根 DNS 服务器。
-
顶级域 DNS 服务器:
- 根 DNS 服务器不知道具体的 IP 地址,但可以提供负责该顶级域(如
.com
、.org
等)的顶级域 DNS 服务器的地址。
- 根 DNS 服务器不知道具体的 IP 地址,但可以提供负责该顶级域(如
-
权威 DNS 服务器:
- 顶级域 DNS 服务器接着将请求转发到负责目标域名的权威 DNS 服务器。
-
递归查询:
- 这个过程称为递归查询,因为 ISP 的 DNS 服务器代表用户进行查询,直到找到正确的 IP 地址。
-
返回 IP 地址:
- 一旦找到正确的 IP 地址,该地址会被返回给用户,首先是 ISP 的 DNS 服务器,然后是本地 DNS 缓存和操作系统缓存,最后是浏览器。
-
建立连接:
- 有了 IP 地址后,用户的设备就可以向托管网站的服务器发起连接请求,通常是通过 TCP 协议。
-
使用 IP 地址:
- 浏览器使用这个 IP 地址来请求网站的资源,完成 DNS 解析过程。
DNS 解析是一个快速的过程,通常在几百毫秒内完成。然而,如果 DNS 缓存中没有记录,或者需要进行递归查询,这个过程可能会稍长一些。DNS 缓存的存在大大减少了解析时间,提高了访问速度。此外,DNS 还可以使用诸如 DNS 预取(DNS prefetching)等技术来进一步优化性能。
2. 网络传输
计算机网络的五层协议模型,又称为 OSI 七层模型的简化版本,是一种常见的网络通信抽象模型。以下是五层协议模型的基本概述:
-
物理层(Physical Layer)
- 负责在物理媒介上传输原始的比特流(0和1)。这一层涉及到电气信号、光信号、无线电信号等的传输方式。
- 包括定义物理设备的标准,如电缆和交换器的规格、形状和尺寸。
-
数据链路层(Data Link Layer)
- 确保物理层传输的原始比特流能够被组织成有意义的数据帧,以便于网络层的进一步处理。
- 负责错误检测和纠正,以及数据的同步、寻址和访问控制。
- 包括 MAC(媒体访问控制)地址和交换器、网桥等设备。
-
网络层(Network Layer)
- 负责数据包从源到目的地的传输和路由选择。
- 处理数据包在整个网络中的移动,包括 IP 地址分配、子网划分和路由协议。
- 包括路由器等设备,它们根据数据包的目的地 IP 地址来转发数据。
刚才解析域名拿到的就是网络层的ip地址
-
传输层(Transport Layer)
- 负责在网络中的两个终端之间提供可靠的数据传输服务。
- 定义了两个主要的传输协议:TCP(传输控制协议)和 UDP(用户数据报协议)。
- TCP 提供面向连接、可靠的字节流传输服务;UDP 提供无连接、尽最大努力的数据报传输服务。
-
应用层(Application Layer)
- 为应用软件提供网络服务,如 HTTP、FTP、SMTP、DNS 等。
- 负责处理特定应用程序的细节,如数据的格式化、加密和网络资源的访问。
- 直接与用户的应用程序交互,提供接口以发送和接收数据。
五层协议模型是一个教学和设计工具,它帮助人们理解网络通信的不同方面和层次。每一层都为上一层提供服务,并且依赖于下一层所提供的服务。虽然实际的网络协议和设备可能不严格遵循这个模型,但五层协议模型提供了一个很好的框架来理解和讨论网络通信的原理。
HTTP(超文本传输协议)和HTTPS(安全超文本传输协议)
是用于从网络传输超媒体文档(如HTML页面)的应用层协议。它们在互联网上用于不同的目的和特性:
HTTP(Hypertext Transfer Protocol):
- 定义:HTTP 是互联网上应用最广泛的协议之一,用于分布式、协作式、超媒体信息系统。
- 无状态:HTTP 本身是无状态的,这意味着服务器不会在请求之间保存任何会话信息。
- 简单性:HTTP 协议的语法简单,易于实现和理解。
- 明文传输:HTTP 数据以明文形式传输,不提供加密,因此不适合传输敏感信息。
- 端口:HTTP 默认使用 TCP 协议的80端口。
HTTPS(Hypertext Transfer Protocol Secure):
- 定义:HTTPS 是 HTTP 的安全版本,它在 HTTP 下增加了一层 SSL/TLS(安全套接字层/传输层安全性)协议来加密数据。
- 加密:HTTPS 通过 SSL/TLS 协议对数据进行加密,保护数据免受窃听和篡改,确保数据的安全性和完整性。
- 身份验证:HTTPS 还可以提供身份验证,确保通信双方正在与预期的对方通信。
- 端口:HTTPS 默认使用 TCP 协议的443端口。
- 性能开销:由于加密和解密的过程,HTTPS 通常会比 HTTP 有更高的性能开销。
区别:
- 安全性:HTTP 不提供数据加密,而 HTTPS 提供数据加密和完整性保护。
- 隐私:HTTP 可以被第三方轻易地查看和篡改数据,HTTPS 则能保护数据不被第三方查看或篡改。
- SEO:使用 HTTPS 可以提高网站的搜索引擎排名,因为 Google 等搜索引擎倾向于优先索引和推荐安全的站点。
- 信任度:HTTPS 站点会在浏览器地址栏显示锁形图标,提高用户对网站的信任度。
使用场景:
- HTTP:适用于不需要安全加密的场景,如公开的信息浏览或简单的数据传输。
- HTTPS:适用于需要保护用户隐私和数据安全的场景,如网上银行、在线支付、登录认证等。
随着网络安全意识的提高,越来越多的网站和服务正在从 HTTP 迁移到 HTTPS,以确保所有传输的数据都是安全的。
3.浏览器渲染页面
浏览器接收到服务器的响应后,会根据响应的内容类型(如 text/html)来渲染页面。对于 HTML 文件,浏览器会:
解析 HTML,构建 DOM(文档对象模型)树。
解析 CSS,构建 CSSOM(CSS 对象模型)树。
将 DOM 和 CSSOM 合并成渲染树。
计算布局(Layout),确定每个元素的大小和位置重排(Reflow) 。
绘制(Painting),在屏幕上绘制出最终的页面重绘(Repaint) 。
在浏览器的渲染过程中,重绘(Repaint) 和 重排(Reflow) 是两个重要的概念,它们涉及到页面元素的视觉呈现和性能优化。
重排(Reflow):
- 定义:重排是指浏览器重新计算页面元素的尺寸、位置等属性,并重新排列它们的过程。
- 触发原因:当页面的布局发生变化时,如元素尺寸改变、元素被添加或删除、元素的样式(如宽度、高度、边距、浮动等)发生变化,都可能触发重排。
- 性能影响:重排是一个相对昂贵的操作,因为它可能涉及大量的计算和DOM元素的移动。特别是当重排影响到大面积的DOM树时,它可能导致页面渲染性能下降。
- 优化方法:
- 减少触发重排的操作,例如通过一次性修改多个样式,而不是分开多次修改。
- 使用
documentFragment
或display: none
隐藏大量DOM元素,进行批量修改后再显示,以减少重排次数。 - 使用CSS的
transform
和opacity
属性进行动画,因为这些属性可以触发重绘而不是重排。
重绘(Repaint):
- 定义:重绘是指当页面元素的外观或样式发生变化,但不影响其布局时,浏览器需要重新绘制元素的过程。
- 触发原因:颜色、阴影、边框颜色、背景色或图片等属性的更改,都可能触发重绘。
- 性能影响:重绘通常比重排要快,因为它只影响单个元素的表面,而不涉及布局的计算和元素的移动。
- 优化方法:
- 尽量避免在复杂动画或交互中使用高成本的CSS属性,如
box-shadow
。 - 使用
will-change
属性或transform
属性来优化动画性能。
- 尽量避免在复杂动画或交互中使用高成本的CSS属性,如
区别和联系:
- 范围:重排影响整个布局,可能涉及多个元素;重绘通常只影响单个元素。
- 性能成本:重排通常比重绘更消耗性能,因为它涉及到更多的计算和DOM操作。
- 触发条件:重排通常由影响布局的样式变化触发,而重绘由不影响布局的样式变化触发。
理解重排和重绘的概念对于前端性能优化至关重要。通过合理的方法减少这两种情况的发生,可以提高页面的渲染效率和用户体验。
CSS减少重排(Reflow)
1. 优化布局结构:
- 设计一个高效的布局结构,减少因布局变化导致的重排。
2. 批量修改样式:
- 如果需要修改多个样式属性,尽量一次性修改,而不是分开多次,以减少重排次数。
3. 使用documentFragment
:
- 当需要对DOM进行大量添加、删除或修改操作时,使用
documentFragment
来暂存更改,然后再一次性将这些更改应用到文档中。
documentFragment
是一个轻量级的 DOM 碎片,在它上面进行的任何操作(如添加、删除或修改子元素)都不会影响当前的文档 DOM 树,因此不会引起页面的重排或重绘。一旦完成对documentFragment
的所有更改,你可以将它一次性地添加到文档 DOM 树中的指定位置,这时只触发一次重排。
以下是一个使用 documentFragment
来暂存更改的例子:
// 创建一个 documentFragment
var fragment = document.createDocumentFragment();
// 创建多个 DOM 元素
var newElement1 = document.createElement('div');
var newElement2 = document.createElement('div');
// ...可以继续创建更多元素
// 向 documentFragment 中添加元素
fragment.appendChild(newElement1);
fragment.appendChild(newElement2);
// ...可以继续添加更多元素
// 执行其他 DOM 操作,例如给元素添加文本或类
newElement1.textContent = 'This is a new element.';
newElement2.className = 'new-class';
// ...进行任何需要的修改
// 将 documentFragment 添加到文档中的某个位置
// 假设有一个 ID 为 'container' 的元素
document.getElementById('container').appendChild(fragment);
// 此时,DOM 树只会进行一次重排
在这个例子中,我们首先创建了一个 documentFragment
,然后创建了两个 div
元素并添加到 documentFragment
中。接着,我们修改了这些新元素的文本和类。由于这些操作都是在 documentFragment
上进行的,它们不会触发文档的重排或重绘。最后,我们将整个 documentFragment
添加到 DOM 树中的一个现有元素中,这时只发生一次重排。
使用 documentFragment
可以有效地减少重排次数,特别是在需要批量添加多个 DOM 元素时。这种方法对于提高页面性能非常有帮助。
4. 避免使用昂贵的CSS属性:
- 某些CSS属性如
box-shadow
、border
、width
、height
等修改时可能触发重排。尽量避免在动画或频繁变化的场景中使用这些属性。
5. 使用transform
和opacity
进行动画:
transform
和opacity
属性的变化只触发重绘(Repaint)而不是重排,因为它们不会影响到元素的布局。
6. 利用will-change
属性:
will-change
属性可以告知浏览器哪些属性可能会变化,浏览器可以预先准备,优化性能。例如:will-change: transform, opacity;
。
7. 使用fixed
或absolute
定位:
- 将元素从文档流中脱离出来,这样它们的变化不会影响其他元素,减少重排。
8. 避免使用table
布局:
table
布局的元素在尺寸变化时会触发较大的重排,因为整个表格都需要重新计算布局。
9. 使用CSS变量(Custom Properties):
- 通过CSS变量来调整样式,可以在不触发重排的情况下实现主题或样式的动态变化。
10. 减少使用JavaScript操作DOM:
- 减少JavaScript直接操作DOM的次数,尤其是在循环或频繁调用的函数中。
11. 使用requestAnimationFrame
进行动画:
- 在执行动画时,使用`requestAnimationFrame`可以确保浏览器在每次重绘之前只执行必要的重排和重绘。
12. 隐藏元素进行修改:
- 如果需要对元素进行复杂的样式更改,可以先将元素隐藏(例如设置`display: none`或`visibility: hidden`),修改完成后再显示。
通过这些方法,可以减少浏览器的重排次数和成本,从而提高页面的性能和响应速度。
对比 display: none或visibility: hidden与opacity:0
display: none
、visibility: hidden
和 opacity: 0
都是CSS属性,它们都可以用于控制元素的可见性,但它们之间存在一些关键的区别:
-
渲染和布局:
display: none
:将元素完全从文档流中移除,不占据任何空间,不触发重排,但会触发重绘。visibility: hidden
:元素仍然占据空间,但对用户不可见,会触发重排,因为元素仍占据布局空间,但不触发重绘。opacity: 0
:元素仍然占据空间,并且参与文档流的布局,但透明度变为完全透明,不触发重排或重绘,只是使元素变得看不见。
-
继承性:
display: none
:不会被子元素继承。visibility: hidden
:可以被子元素继承,如果子元素的visibility
属性不是collapse
,则子元素也会不可见。opacity: 0
:透明度可以被子元素继承,但子元素本身不会变为透明,只是透明度会累加。
-
交互性:
display: none
:元素不可见且不可交互。visibility: hidden
:元素不可见但可交互(如可以点击)。opacity: 0
:元素不可见但可交互,因为透明度不会影响鼠标事件。
-
动画性能:
display: none
:由于元素完全从文档流中移除,使用它进行动画可能不是最佳选择。visibility: hidden
:可以使用CSS动画或过渡来改变visibility
属性,但需要注意重排的影响。opacity: 0
:非常适合用于动画,因为它只触发重绘,不触发重排或重绘。
-
使用场景:
display: none
:当你想完全隐藏一个元素,并且不希望它影响布局时使用。visibility: hidden
:当你想隐藏元素,但仍希望它保留布局空间时使用。opacity: 0
:当你想创建一个平滑的显示或隐藏效果,并且不关心元素的可见性时使用。
-
CSS 选择器:
- 当元素应用了
display: none
后,它不会被CSS选择器选中。 - 应用了
visibility: hidden
或opacity: 0
的元素仍然可以被CSS选择器选中。
- 当元素应用了
在选择使用哪个属性时,需要根据具体的场景和需求来决定,以达到最佳的性能和效果。
优化
页面本身的加载性能 + 所有依赖资源的加载性能
浏览器:C 服务器:S
C减少请求数
C优化请求顺序
压缩传输的数据
S提升传输效率
中间
Gzip Components Gzip压缩
几乎所有的浏览器都有解压Gzip格式的能力,而且它可以压缩的比例非常大,一般压缩率为85%。压缩代码体积
设置客户端缓存:Cache-control 强缓存和协商缓存HTTP强缓存与协商缓存
C客户端
代码习惯
Put Stylesheets at the Top 把CSS放顶部:让浏览者能尽早的看到网站的完整样式。
Put Scripts at the Bottom 延迟加载非必要脚本:网站呈现完毕后再进行功能设置,当然这些JS要在你的加载过程中不影响内容表现。
避免CSS Expressions:CSS表达式只被IE支持的东西执行时候的运算量非常大,移动一下鼠标它都要进行重计算的,但有时候为了做浏览器的兼容必须要用到这个(就是在说IE6)
减少DOM的访问次数:JS访问DOM是很慢的,尽量不要用JS来设置页面布局。
减少图片、css、script、flash等元素的数量、把多个JS、CSS在可能的情况下写进一个文件
页面里直接写入图片也是不好的做法,应该写进CSS里,利用 CSS sprites 将小图拼合后利用background来定位。
减少iframe数量,更有效的利用 ifames
iframe 优点:有利于下载缓慢的广告等第三方内容,安全沙箱,并行下载脚本 iframe 缺点:即使为空也会有较大资源消耗,会阻止页面的onload,非语义
尽量用GET方式进行AJAX请求
Get 方法和服务器只有一次交互(发送数据),而 Post 要两次(发送头部再发送数据)。
减小Cookie:Cookie在服务器及浏览器之间的通过文件头进行交换,尽可能减小Cookie体积,设置合理的过期时间,能够很好的提高效率。
S服务器
使用HTTP 1.0/1.1协议,chrome只允许每个源拥有6个TCP连接,因此可以通过划分子域将多个资源分布在不同子域上。3-5个即可
但是需要注意多个子域意味着更多的DNS查询时间
CDN加速
Content Delivery Network,即内容分发网络。CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率
performance
window.performance.:获取网页加载详细性能指标的API
window.performance.timing完整的网页本身加载性能数据
navigationStart属性:在用户代理完成提示卸载上一个文档后立即返回时间。如果没有以前的文档,此属性必须返回与取启动相同的值。
unloadEventStart属性:如果以前的文档和当前文档的来源相同[IETF RFC 6454],则此属性必须在用户代理开始上一文档的卸载事件之前立即返回时间。如果没有以前的文档或以前的文档与当前文档的来源不同,此属性必须返回零。
unloadEventEnd属性:如果以前的文档和当前文档的原点相同,则此属性必须在用户代理完成上一文档的卸载事件后立即返回时间。如果没有以前的文档或以前的文档与当前文档的来源不同或卸载尚未完成,则此属性必须返回零。如果导航时有 HTTP 重定向或等价物,并且并非所有重定向或等价物都来自同一来源,则卸载和卸载必须返回零。
redirectStart属性:如果导航时有 HTTP 重定向或等价物,如果所有重定向或等价物都来自同一来源,则此属性必须返回启动重定向的取件的开始时间。否则,此属性必须返回零。
redirectEnd属性:如果导航时有 HTTP 重定向或等价物,并且所有重定向和等价物都来自同一来源,则此属性必须在收到最后一个重定向响应的最后一个节后立即返回时间。否则,此属性必须返回零。
fetchStart属性:如果要使用 HTTP GET或等价物获取新资源,取件必须立即返回用户代理开始检查任何相关应用程序缓存之前的时间。否则,它必须返回用户代理开始获取资源的时间。
获取资源的第一步是查询是否有相应的缓存,确认需要需要请求资源,然后DNS
domainLookupStart属性:此属性必须在用户代理开始域名查找当前文档之前立即返回时间。如果使用持久连接[RFC 2616]或从相关应用程序缓存或本地资源检索当前文档,此属性必须返回与取启动相同的值。
domainLookupEnd属:用户代理完成域名查找当前文档后立即返回时间。如果使用持久连接[RFC 2616]或从相关应用程序缓存或本地资源检索当前文档,此属性必须返回与取启动相同的值。
connectStart属性(TCP):此属性必须在用户代理开始建立连接到服务器以检索文档之前立即返回时间。如果使用持久连接[RFC 2616]或从相关应用程序缓存或本地资源检索当前文档,此属性必须返回域名查找端的价值。
connectEnd属性:在用户代理完成与服务器的连接以检索当前文档后立即返回时间。如果使用持久连接[RFC 2616]或从相关应用程序缓存或本地资源检索当前文档,此属性必须返回域查找端的价值
如果传输连接失败,用户代理重新打开连接,则连接启动和连接End应返回新连接的相应值。
连接端必须包括建立传输连接的时间间隔以及其他时间间隔,如 SSL 握手和袜子身份验证。
secureConnectionStart属性
此属性是可选的。没有此属性可用的用户代理必须将其设置为未定义的。当此属性可用时,如果当前页面的方案是HTTPS,则此属性必须立即返回用户代理开始握手过程之前的时间,以确保当前连接的安全。如果此属性可用,但未使用 HTTPS,则此属性必须返回零。
requestStart属性:在用户代理开始从服务器或相关应用程序缓存或本地资源请求当前文档之前立即返回时间。
如果在发送请求后传输连接出现故障,并且用户代理重新打开连接并重新发送请求,则请求启动应返回新请求的相应值。
不表示用户代理发送请求的完成
responseStart属性:在用户代理收到服务器或相关应用程序缓存或本地资源响应的第一个要节后立即返回时间。
responseEnd属性:在用户代理收到当前文档的最后一个节后或在传输连接关闭之前立即返回时间,以先到者为准。此处的文件可以从服务器、相关应用程序缓存或本地资源接收。
domLoading属性:解析DOM树
domInteractive属性:在用户代理将当前文档准备设置为"交互式"之前立即返回时间。
domContentLoadedEventStart属性:在用户代理在文档中触发DOM 会议加载事件之前立即返回时间。
domContentLoadedEventEnd属性:在文档的DOM 会议加载事件完成后立即返回时间。
domComplete属性:在用户代理设置当前文档准备"完成"之前立即返回时间。
如果当前文档准备状态多次更改为同一状态,则多米加载、多米时联动、多米定件加载事件开始、多米定件加载事件结束和圆顶完成必须返回相应文档准备更改首次发生的时间。
loadEventStart属性:在当前文档的负载事件被激发之前立即返回时间。尚未发射负载事件时,它必须返回零。
loadEventEnd属性:返回当前文档的负载事件完成的时间。当负载事件未被激发或未完成时,它必须返回零。