2022.3.3 前端性能优化

面试中
  • 了解性能优化吗?
  • 输入URL 到看到整个页面经历了什么过程?
工作中
  • 页面加载好慢,不知道是前端问题还是后端问题。
  • 页面交互卡顿,不知道具体哪里出了问题

什么是web性能

  • 打开速度
  • 动画效果
  • 表单提交
  • 列表滚动
  • 页面切换
MDN上的 Web性能定义: Web性能是网站或应用程序的客观度量和可感知的用户体验。

·

  • 减少整体加载时间:减小文件体积、减少HTTP请求、使用预加载
  • 使网站尽快可用:仅加载首屏内容,其它内容根据需要进行懒加载·平滑和交互性:使用CSS替代JS动画、减少UI重绘
  • 感知表现:你的页面可能不能做得更快,但你可以让用户感觉更快。耗时操作要给用户反馈,比如加载动画、进度条、骨架屏等提示信息
  • 性能测定:性能指标、性能测试、性能监控持续优化

如何进行Web 性能优化?

  • 首先需要了解性能指标-多快才算快?
  • 使用专业的工具可量化地评估出网站或应用的性能表现;
  • 然后立足于网站页面响应的生命周期,分析出造成较差性能表现的原因;
  • 最后进行技术改造、可行性分析等具体的优化实施。
  • 迭代优化

性能指标

  • RAlL 性能模型
  • 基于用户体验的核心指标
  • 新一代性能指标:web Vitals

性能测量

如果把对网站的性能优化比作一场旅程,它无疑会是漫长且可能还略带泥泞的,那么在开始之前我们有必要对网站进行性能测量,以知道优化的方向在何处。通常我们会借助一些工具来完成性能测量。

  • 浏览器DevTools 调试工具
  • 灯塔(lighthouse)
  • WebPageTest

优化方案

经过对网站页面性能的测量及渲染过程的了解,相信你对于糟糕性能体验的原因已经比较清楚了,那么接下来便是优化性能,这也是本课程所要呈现给读者的大部分篇幅。本节先简单扼要地介绍一些优化方面的思路。

  • 从发出请求到收到响应的优化,比如DNS查询、HTTP长连接、HTTP 2、HTTP压缩、HTTP缓存等。
  • 关键渲染路径优化,比如是否存在不必要的重绘和回流。
  • 加载过程的优化,比如延迟加载,是否有不需要在首屏展示的非关键信息
    占用了页面加载的时间。
  • 资源优化,比如图片、视频等不同的格式类型会有不同的使用场景,在使用的过程中是否恰当。
  • 构建优化,比如压缩合并、基于webpack构建优化方案等。

Web 性能指标

RAIL 性能模型:Response Animation Idle Load
以用户为中心,最终目标不是让您的网站在任何特定设备上都能运行很快,而是使用户满意

  • 响应(Response):应尽可能快速的响应用户,应该在100ms以内响应用户的输入
  • 动画(Animation):在展示动画的时候,每一帧应该以16ms进行渲染,这样可以保证动画效果的一致性,并且避免卡顿
  • 空闲(Idle):当使用 JavaScript 主线程的时候,应该把任务划分到执行时间小于50ms的片段中去,这样可以释放线程以进行用户交互
  • 加载(Load):应该在小于1s的时间内加载完成你的网站,并可以进行用户交互

根据网络条件和硬件的不同,用户对性能延迟的理解也有所不同。例如,通过快速的Wi-Fi连接在功能强大的台式机上加载站点通常在1s内完成,用户对此已经习以为常。在3G连接速度较慢的移动设备上加载网站需要花费更多的时间,因此移动用户通常更耐心,在移动设备上加载5s是一个更现实的目标

基于用户体验的性能指标
  • First Contentful Paint (FCP)
    首次内容绘制,浏览器首次绘制来自 DOM 内容的时间,内容必须是文本、图片、非白色的 canvas 或 SVG,也包括带有正在加载中的 Web 字体的文本。
  • Largest Contentful Paint (LCP)
    最大内容绘制,可视区域中最大的内容元素呈现到屏幕上的时间,用以估算页面的主要内容对用户可见时间。LCP 考虑的元素有 <img>、<svg>、<video>、url()函数加载的背景图片
  • First Input Delay (FID)
    首次输入延迟,从用户第一次与页面交互(例如点击连接、点击按钮、输入框输入等)到浏览器实际能够响应的交互时间
  • Time To Interactive (TTI):可持续(流畅)交互时间
    表示网页第一次完全达到可交互状态的时间点,浏览器已经可以持续性的响应用户输入。完全达到可交互状态的时间点是在最后一个长任务完成的时间,并且在随后的 5s 内网络和主线程是空闲的。
  • Total Block Time (TBT)
    总阻塞时间,度量了 FCP 和 TTI 之间的总时间,在该时间范围内,主线程被阻塞足够长的时间以防止输入响应。

只要存在长任务,该主线程就会被视为“阻塞”,该任务在主线程上运行超过50ms。我们说主线程“被阻止”是因为浏览器无法中断正在进行的任务。因此,如果用户确实在较长的任务中间与页面进行交互,则浏览器必须等待任务完成才能响应。

如果任务足够长(例如,超过50ms的任何时间),则用户很可能会注意到延迟并感觉页面缓慢或过时。

  • Cumulative Layout Shift (CLS)
    累计布局偏移,CLS 会测量在页面整个生命周期中发生的每个意外的布局移位的所有单独布局移位分数总和。它是一种保证页面的视觉稳定性从而提升用户体验的指标
  • Speed Index
    Speed Index (速度指数) 是一个表示页面可视区域中内容的填充速度的指标,可以通过计算页面可见区域内容显示的平均时间来衡量
Web Vitals

Web Vitals 是简化版的基于用户体验的性能指标, 把下边三个指标做好,网站性能不会太差

  • 加载性能(LCP):显示最大内容元素所需时间
  • 交互性(FID):首次输入延迟时间
  • 视觉稳定性(CLS):累计布局配置偏移

前端页面的生命周期

性能问题呈现给用户的感受往往是简单而直接的:加载资源缓慢、运行过程卡顿或响应交互迟缓等,当把这些问题呈现到前端工程师面前时,却是另一种系统级别复杂的图景。
从域名解析、TCP建立连接到HTTP的请求与响应,以及从资源请求、文件解析到关键渲染路径等,每一个环节都有可能因为设计不当、考虑不周、运行出错而产生性能不佳的体验。作为前端工程师,为了能在遇到性能问题时快速而准确地定位问题所在,并设计可行的优化方案,熟悉前端页面的生命周期是一堂必修课。
分析前端页面生命周期的各个环节,并着重分析其中关键渲染路径的具体过程和优化实践,希望以此为基础帮读者建构一套完整知识框架的图谱。
请添加图片描述

  • 大家在进行前端面试时,经常问这样一个问题:从浏览器地址栏输入URL后,到页面渲染出来,整个过程都发生了什么?这个问题不仅能很好地分辨出面试候选人对前端知识的掌握程度,能够考查其知识体系的完整性,更重要的是,能够考查面试者在前端性能优化方面理解和掌握此过程的深入程度,与快速定位性能瓶颈及高效权衡出恰当的性能优化解决方案是正相关的。

  • 根据笔者面试和工作的经验,笔者将工程师的能力由低到高划分了若干等级:不堪一击、初窥门径、略有小成、驾轻就熟
    融会贯通…

  • 如果面试者的回答是:首先浏览器发起请求,然后服务器返回数据,最后脚本执行和页面渲染,那么这种程度大概在不堪一击与初窥门径之间,属于刚入门前端,对性能优化还没什么概念。

  • 如果知道在浏览器输入URL后会建立TCP连接,并在此之上有HTTP的请求与响应,在浏览器接收到数据后,了解HTML与CSS文件如何构成渲染树,以及JavaScript 引擎解析和执行的基本流程,这种程度基本算是初窥门径,在面对网站较差的性能表现时,能够尝试从网络连接、关键渲染路径及)JS执行过程等角度去分析和找寻可能存在的问题。本课程的目标便是带领各位同学从初窥门径的程度向更高的级别提升。

  • 其实这个问题的回答可以非常细致,能从信号与系统、计算机原理、操作系统聊到网络通信、浏览器内核,再到DNS解析、负载均衡.页面渲染等,但这门课程主要关注前端方面的相关内容,为了后文表述更清楚,这里首先将整个过程划分为以下几个阶段。

  • (1)浏览器接收到URL,到网络请求线程的开启。

  • (2)一个完整的HTTP请求并的发出。

  • (3)服务器接收到请求并转到具体的处理后台。

  • (4)前后台之间的HTTP交互和涉及的缓存机制。

  • (5)浏览器接收到数据包后的关键渲染路径。

  • (6) JS引擎的解析过程。

网络请求线程开启

浏览器接收到我们输入的URL到开启网络请求线程,这个阶段是在浏览器内部完成的,需要先来了解这里面涉及的一些概念。
请添加图片描述
解析URL后,如果是HTTP协议,则浏览器会新建一个网络请求线程去下载所需的资源,要明白这个程需要先了解进程和线程之间的区别,以及目前主流的多进程浏览器结构。

线程与进程

简单来说,进程就是一个程序运行的实例,操作系统会为进程创建独立的内存,用来存放运行所需的代码和数据;而线程是进程的组成部分,每个进程至少有一个主线程及可能的若干子线程,这些线程由所属的进程进行启动和管理。由于多个线程可以共享操作系统为其所属的同一个进程所分配的资源,所以多线程的并行处理能有效提高程序的运行效率。

进程和线程之间的区别:
  • (1)只要某个线程执行出错,将会导致整个进程崩溃。
  • (2)进程与进程之间相互隔离。这保证了当一个进程挂起或崩溃的情况发生时,并不会影响其他进程的正常运行,虽然每个进程只能访问系统分配给自己的资源,但可以通过IPC机制进行进程间通信。
  • (3)进程所占用的资源会在其关闭后由操作系统回收。即使进程中存在某个线程产生的内存泄漏,当进程退出时,相关的内存资源也会被回收。
  • (4))线程之间可以共享所属进程的数据。
单线程浏览器 多线程浏览器

懒得写---------

建立HTTP请求

这个阶段的主要工作分为两部分:DNS解析和通信链路的建立。
简单说就是:

  • 首先发起请求的客户端浏览器要明确知道所要访问的服务器地址
  • 然后建立通往该服务器地址的路径
DNS解析

在前面章节讲到的URL解析,其实仅将URL拆分为代表具体含义的字段,然后以参数的形式传入网络请求线程进行进一步处理,首先第一步便是这里讲到的DNS解析。其主要目的便是通过查询将URL中的Host字段转化为网络中具体的IP地址,因为域名只是为了方便帮助记忆的,IP地址才是所访问服务器网络中的“门牌号”。请添加图片描述
首先查询浏览器自身的DNS缓存,如果查到IP地址就结束解析,由于缓存时间限制比较大,一般只有1分钟,同时缓存容量也有限制,所以在浏览器缓存中没找到IР地址时,就会搜索系统自身的DNS缓存;如果还未找到,接着就会尝试从系统的hosts文件中查找。
在本地主机进行的查询若都没获取到,接下来便会在本地域名服务器上查询。如果本地域名服务器没有接的目标IP地址可供返回,则本地域名服务器便会采取迭代的方式去依次查询根域名服务器、COM顶级域名服务器和权限域名服务器等,最终将所要访问的目标服务器IP地址返回本地主机,若查询不到,则返回报错信息。
由此可以看出DNS解析是个很耗时的过程,若解析的域名过多,势必会延缓首屏的加载时间。本节仅对DNS解析过程进行简要的概述,而关于原理及优化方式等更为详细的介绍会在后续课程中单独展开介绍。

网络模型

在通过DNS解析获取到目标服务器IP地址后,就可以建立网络连接进行资源的请求与响应了。但在此之前,我们需要对网络架构模型有一些基本的认识,在互联网发展初期,为了使网络通信能够更加灵活、稳定及可互操作,国际标准化组织提出了一些网络架构模型:OSI模型、TCP/IP模型,二者的网络模型图示如下图所示。
请添加图片描述

请添加图片描述

TCP连接

根据对网络模型的介绍,当使用本地主机连上网线接入互联网后,数据链路层和网络层就已经打通了,而要向目标主机发起HTTP请求,就需要通过传输层建立端到端的连接。
传输层常见的协议有TCP协议和UDP协议,由于本章关注的重点是前端页面的资源请求,这需要面向连接、丢包重发及对数据传输的各种控制,所以接下来仅详细介绍TCP协议的“三次握手”和“四
次挥手”。
由于TCP是面向有连接的通信协议,所以在数据传输之前需要建立好客户端与服务器端之间的连接,即通常所说的“三次握手”,具体过程分为如下步骤。
请添加图片描述
(1)由客户端先向服务器端发送 FIN=M 的指令,随后进入完成等待状态FIN_WAIT_1,表明客户端已经没有再向服务器端发送的数据,但若服务器端此时还有未完成的数据传递,可继续传递数据。
(2)当服务器端收到客户端的FIN报文后,会先发送 ack=M+1的确认,告知客户端关闭请求已收到,但可能由于服务器端还有未完成的数据传递,所以请客户端继续等待。
(3)当服务器端确认已完成所有数据传递后,便发送带有FIN=N的报文给客户端,准备关闭连接。
(4)客户端收到FIN=N的报文后可进行关闭操作,但为保证数据正确性,会回传给服务器端一个确认报文 ack=N+1,同时服务器端也在等待客户端的最终确认,如果服务器端没有收到报文则会进行重传,只有收到报文后才会真正断开连接。而客户端在发送了确认报文一段时间后,没有收到服务器端任何信息则认为服务器端连接已关闭,也可关闭客户端信息。

前后端的交互

当TCP连接建立好之后,便可通过HTTP等协议进行前后端的通信,但在实际的网络访问中,并非浏览器与确定IP地址的服务器之间直接通信,往往会在中间加入反向代理服务器。

反向代理服务器

对需要提供复杂功能的网站来说,通常单一的服务器资源是很难满足期望的。一般采用的方式是将多个应用服务器组成的集群由反向代理服务器提供给客户端用户使用,这些功能服务器可能具有不同类型,比如文件服务器、邮件服务器及Web应用服务器,同时也可能是相同的Web服务部署到多个服务器上,以实现负载均衡的效果,反向代理服务器的作用如图所示。

请添加图片描述
反向代理服务器根据客户的请求,从后端服务器上获取资源后提供给客户端。反向代理服务器通常的作用如下:

  • 负载均衡。
  • 安全防火墙。
  • 加密及SSL加速。
  • 数据压缩。
  • 解决跨域。
  • 对静态资源缓存。
    常用作反向代理服务器的有Nginx、llS、Apache,我们会在后面针对Nginx深入介绍一些可用于性能优化的配置。
后端处理流程

经反向代理收到请求后,具体的服务器后台处理流程大致如下。
(1)首先会有一层统一的验证环节,如跨域验证、安全校验拦截等。如果发现是不符合规则的请求,则直接返回相应的拒绝报文。
(2)通过验证后才会进入具体的后台程序代码执行阶段,如具体的计算、数据库查询等。
(3)完成计算后,后台会以一个HTTP响应数据包的形式发送回请求的前端,结束本次请求。

http相关协议特性

HTTP是建立在传输层TCP协议之上的应用层协议,在TCP层面上存在长连接和短连接的区别。所谓连接,就是在客户端与服务器端建立的TCP连接上,可以连续发送多个数据包,但需要双方发送心跳检查包来维持这个连接。
短连接就是当客户端需要向服务器端发送请求时,会在网络层IP协议之上建立一个TCP连接,当请求发送并收到响应后,则断开此连接。根据前面关于TCP连接建立过程的描述,我们知道如果这个过程频发生,就是个很大的性能耗费,所以从HTTP的1.0 版本开始对于连接的优化一直在进行。
在HTTP 1.0时,默认使用短连接,浏览器的每一次HTTP操作就会建立一个连接,任务结束则断开连接。
在HTTP 1.1时,默认使用长连接,在此情况下,当一个网页的打开操作完成时,其中所建立用于传输HTTP的TCP连接并不会断开关闭,客户端后续的请求操作便会继续使用这个已经建立的连接。如果我!对浏览器的开发者工具留心,在查看请求头时会发现一行Connection: keep-alive。长连接并非永保持,它有一个持续时间,可在服务器中进行配置。
而在HTTP 2.0 到来之前,每一个资源的请求都需要开启一个TCP连接,由于TCP本身有并发数的限制这样的结果就是,当请求的资源变多时,速度性能就会明显下降。为此,经常会采用的优化策略包括,静态资源的请求进行多域名拆分,对于小图标或图片使用雪碧图等。
在HTTP 2.0之后,便可以在一个TCP连接上请求多个资源,分割成更小的帧请求,其速度性能便会明显上升,所以之前针对 HTTP 1.1限制的优化方案也就不再需要了。
HTTP2.0除了一个连接可请求多个资源这种多路复用的特性,还有如下一些新特性。
(1)二进制分帧:在应用层和传输层之间,新加入了一个二进制分帧层,以实现低延迟和高吞吐量。
(2)服务器端推送:以往是一个请求带来一个响应,现在服务器可以向客户端的一个请求发出多个响应,这样便可以实现服务器端主动向客户端推送的功能。
(3)设置请求优先级:服务器会根据请求所设置的优先级,来决定需要多少资源处理该请求。
(4) HTTP头部压缩:减少报文传输体积。

浏览器缓存

在基于HTTP的前后端交互过程中,使用缓存可以使性能得到显著提升。具体的缓存策略分为两种:强缓存和协商缓存。

强缓存就是当浏览器判断出本地缓存未过期时,直接读取本地缓存,无须发起HTTP请求,此时状态为: 200 from cache。在HTTP 1.1版本后通过头部的cache-control 字段的max-age属性值规定的过期时长来判断缓存是否过期失效,这比之前使用expires标识的服务器过期时间更准确而且安全。

协商缓存则需要浏览器向服务器发起HTTP请求,来判断浏览器本地缓存的文件是否仍未修改,若未修改则从缓存中读取,此时的状态码为:304。具体过程是判断浏览器头部if-none-match与服务器短的e-tag 是否匹配,来判断所访问的数据是否发生更改。这相比HTTP 1.0版本通过1ast-modified判断上次文件修改时间来说也更加准确。具体的浏览器缓存触发逻辑如图所示。
在这里插入图片描述
在浏览器缓存中,强缓存优于协商缓存,若强缓存生效则直接使用强缓存,若不生效则再进行协商缓存的请求,由服务器来判断是否使用缓存,如果都失效则重新向服务器发起请求获取资源。

关键渲染路径

当我们经历了网络请求过程,从服务器获取到了所访问的页面文件后,浏览器如何将这些HTML、CSS 及JS文件组织在一起渲染出来呢?

构建对象模型

首先浏览器会通过解析HTML和CSS文件,来构建 DOM(文档对象模型)和CSSOM(层叠样式表对模型),为便于理解,我们以如下HTML内容文件为例,来观察文档对象模型的构建过程。
请添加图片描述
浏览器的渲染过程主要包括以下几步

  • 解析HTML生成DOM树
  • 解析CSS生成CSSOM规则树
  • 将DOM树与CSSOM规则树合并在一起生成渲染树
  • 遍历渲染树开始布局,计算每个节点的位置大小信息
  • 将渲染树每个节点绘制到屏幕
构建css对象模型请添加图片描述
渲染绘制

请添加图片描述
(1)从所生成DOM树的根节点开始向下遍历每个子节点,忽略所有不可见的节点(脚本标记不可见、cSS隐藏不可见),因为不可见的节点不会出现在渲染树中。
(2)在cSSoM中为每个可见的子节点找到对应的规则并应用。
(3)布局阶段,根据所得到的渲染树,计算它们在设备视图中的具体位置和大小,这一步输出的是一个“盒模型”。
(4)绘制阶段,将每个节点的具体绘制方式转化为屏幕上的实际像素。

性能优化方案

请求和响应优化
  • DNS解析优化: 减少 DNS 查找次数,进行 DNS 预获取:
  • 多开持久连接:多搞几个域名,因为浏览器对域名的并发有限制,最大并发请求6-8个。域名一多就得使用DNS预获取
  • 减少 HTTP 请求:因为在http1.1中请求是并发的,但是响应是串行的,如果处理的这个响应特别耗时,就会阻塞其他请求响应结果
  • 压缩传输的数据资源:gzip 压缩
  • CDN 缓存:引用的外部资源包通过 CDN 方式引入,以来能减少项目打包文件体积,二来能提高资源请求速度
  • HTTP 缓存:强缓存 和 协商缓存
  • Service Worker 缓存
  • 服务端渲染
  • 预渲染
渲染优化
  • 减少重排重绘
  • 动画每一帧控制在16ms以内渲染
  • 使用骨架屏配合 service worker缓存
  • 基于用户体验性能指标
资源加载优化
  • 合并文件:将多个较小的文件合并成一个文件,减少http请求。不过在http2.0不需要做这步操作了,http2.0可以同一个连接并发处理多个请求和响应
  • 对HTML使用协商缓存,对静态资源使用强缓存
  • 静态资源压缩
  • 路由懒加载
  • CSS样式异步加载:
  • JS异步加载:
图片优化
  • 合理使用图片格式:WebP
  • 懒加载:暂时不设置图片的 src 属性,而是将图片的 url 隐藏起来,比如先写在 data-src 里面,等当前图片是否到了可视区域再将图片真实的 url 放进 src 属性里面,从而实现图片的延迟加载
  • 预加载:一种是隐藏在 css 的 background 的 url 属性里面。一种是通过 javascript 的 Image 对象设置实例对象的 src 属性实现图片的预加载
  • 渐进式加载:在高画质图像加载完之前会先显示低画质版本。低画质版本由于画质低、压缩率高,尺寸很小,加载很快。
构建优化
  • 代码压缩:JS压缩(UglifyJsPlugin)、HTML压缩(HtmlWebpackPlugin)、CSS压缩(ExtractTextPlugin)、gizp压缩(compression-webpack-plugin)
  • 第三方包按需引入
  • Nginx 开启gizp传输压缩

缓存策略

Cache Only

  • 所有资源请求直接从缓存获取返回,如果在缓存中找不到,请求将失败。该模式假定资源之前已被缓存,可能 install 期间就做了缓存。对于静态资源比较合适

Network Only

  • 只从网络返回,不需要缓存。适用于前端用户行为日志打点之类的请求

Cache,falling back to Network

  • 优先从 Cache 返回内容,如果失败了则发送网络请求

Network,falling back to Cache

  • 优先从 Network 返回内容,如果失败了则从缓存获取。适用于频繁更新的内容,希望用户总是看到最新的内容

Cache && Network race

  • 同时从 Cache 和网络获取内容,取最快响应的内容返回。应用场景少,对比较老的设备从硬盘读取数据比较慢的情况使用,几乎可以忽略

Cache,then Network

  • 优先从 Cache 返回内容,同时从网络获取最新内容,如果网络内容比较新,则更新缓存,并更新页面内容。UX实现难度大

Generic fallback

  • 先从 Cache 获取数据,Cache 没有则从网络获取,如果网络也不可用,返回缓存中默认内容。适用于默认图片之类的场景

Http 强缓存 和 协商缓存

同时存在强缓存和协商缓存,优先使用协商缓存

强缓存
如果浏览器判断所请求的目标资源有效命中,则可以从强制缓存中返回请求响应,无需与服务器进行任何通信。

  • expires:需要写死一个固定时间,客户端时间和服务器时间可能不同步,导致缓存可能不会生效

  • cache-control,max-age:max-age=10,单位秒,在10秒之内使用强制缓存。对比于expires,设置时间更灵活

  • 缺点:资源更新了但还属于强制缓存时间内,导致无法及时更新
    协商缓存
    在使用本地缓存之前,需要向服务器发起一次 GET 请求,与之协商当前浏览器保存的本地缓存是否已过期,没过期客户端直接使用缓存,过期服务器返回新的资源

  • cache-control、last-Modified、if-Modified-Since
    cache-control: no-cache(协商缓存)
    last-Modified: 资源修改时间
    if-Modified-Since: 客户端把第一次接收的 last-Modified 发送给服务端让它做比对,时间上是否修改,没修改走协商缓存 304
    last-Modified 缺点:有可能资源就改了个名字,但资源内容没有改变,会导致缓存失效,推荐使用Etag

  • cache-control、Etag、if-none-match
    cache-control: no-cache(协商缓存)
    etag: 基于文件内容生成一个唯一的密码戳
    if-none-match: 客户端把第一次接收的 etag 发送给服务端让它做比对,检验etag是否修改,没修改走协商缓存 304

HTTP1.0 和 HTTP1.1 的区别

  • 长连接
    在HTTP1.1中默认开启长连接keep-alive,一定程度上弥补了Http1.0每次请求都要创建连接的缺点
  • 节约带宽
    HTTP1.0中存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能
  • HOST域
    在HTTP1.1中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname),HTTP1.0没有host域
  • 缓存处理
    在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制- 缓存策略
  • 错误通知的管理
    在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除
  • 管道机制
    在HTTP1.1请求是可以并发的,但响应是串行接收的,如果处理的这个响应非常慢,就会阻塞后边响应的结果。Http2.0中解决了响应并发的问题

HTTP1.1 和 HTTP2.0 的区别

多路复用

  • HTTP2.0使用了多路复用的技术,复用TCP连接,做到同一个连接并发处理多个请求和响应
    二进制协议
  • HTTP1.1头部信息肯定是文本(ASCII编码),数据体可以是文本或二进制。HTTP2.0则是彻底的二进制协议,头信息和数据体都是二进制。
    头部数据压缩
  • HTTP1.1不支持头部信息数据压缩,HTTP2.0使用HPACK算法对头部信息数据进行压缩,数据体积小了,网络传输就会更快
    服务器推送
  • 在客户端请求之前服务端主动发送资源的机制,减少客户端的请求

HTTP 长连接和 WebSocket 长连接的区别

HTTP1.1

  • Keep-alive的确可以实现长连接,但是这个长连接是有问题的,本质上依然是客户端主动发起-服务端应答的模式,是没法做到服务端主动发送通知给客户端的。也就是说,在一个HTTP连接中,可以发送多个Request,接收多个Response。但是一个request只能有一个response。而且这个response也是被动的,不能主动发起。开启了Keep-alive,可以看出依然是一问一答的模式,只是省略了每次的关闭和打开操作

WebSocket

  • WebSocket是可以互相主动发起的。相对于传统 HTTP 每次请求-应答都需要客户端与服务端建立连接的模式,WebSocket 是类似 TCP 长连接的通讯模式,一旦 WebSocket 连接建立后,后续数据都以帧序列的形式传输。在客户端断开 WebSocket 连接或 Server 端断掉连接前,不需要客户端和服务端重新发起连接请求。在海量并发及客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实时性优势明显

TCP 和 UDP 的区别

TCP 是面向连接的、可靠的字节流服务

  • TCP 是面向连接的,UDP 是面向无连接的
  • TCP 仅支持单向传播,UDP 支持单播、多播、广播
  • TCP 三次握手保证了连接的可靠性,UDP 是无连接的不可靠的传输协议,不可靠是指通信上不需要建立连接,对接收到的数据不需要确认,发送端不知道数据是否会正确接收
  • UDP 比 TCP 头部开销小,数据传输速率更高、实时性更好
    应用场景
  • UDP 对数据安全性无特殊要求: 即时通信、消息语音、在线视频会议、语音通话
  • TCP 对数据准确性要求高,速度可以相对较慢的: 文件传输、邮件的发送与接收

TCP 三次握手

  • 首先建立连接,客户端给服务端传输 SYN 包,这时客户端知道自己能发出消息但是不知道服务端接收到了消息没有
  • 服务端向客户端返回 SYN + ACK 包,客户端确定自己能发出消息并接收消息,服务端确定自己能发出消息,不知道自己发出的消息是否被接收
  • 客户端收到服务端确认应答后,给服务端传输 ACK标识。此时服务端接收并确认自己能发出消息、接收消息

TCP 四次挥手

  • 由客户端向服务端发出 FIN 指令,随后进入完成等待状态,如果服务端还有数据需要传输则继续传输
  • 服务器收到 FIN 指令后,会发送 ACK 告知客户端关闭请求已收到,但是还有数据需要传输,所以请客户端继续等待
  • 服务器完成数据的传输后,发送 FIN 指令告知客户端准备关闭连接
  • 客户端收到 FIN 指令后可随时关闭连接,但为了数据传递的完整性,会回传给服务器 ACK,服务器收到 ACK 断开连接,没有则重新传输。客户端在发送 ACK 之后没有接收服务器任何消息,则关闭连接

进程与线程

进程:CPU 资源分配的最小单位。 进程就是一个程序的实例,操作系统会为进程创建独立的内存,用来存放运行所需的代码和数据,例如:微信 和 qq 就是两个进程
线程:CPU 调度的最小单位。 线程是进程的组成部分,每个进程至少有一个主线程及可能的若干子线程,这些线程由所属的进程进行启动和管理

进程和线程的区别

  • 只要某个线程执行错误,将会导致整个进程崩溃
  • 进程与进程之间相互隔离,这保证了当一个进程挂起或崩溃的情况发生时,并不会影响其他进程的正常运行,虽然每个进程只能访问系统分配给自己的资源,但可以通过 IPC 机制进行进程间的通信
  • 进程所占用的资源会在其关闭后由操作系统回收。即使进程中某个线程产生的内存泄露,当进程退出时,相关的内存资源也会被回收
  • 线程之间可以共享所属进程的数据

多进程浏览器

  • 浏览器主进程
    一个浏览器只有一个主进程,负责菜单栏、标题栏等界面显示,文件访问,前进后退,以及子进程的管理
  • GPU 进程
    GPU(图形处理单元) 最初是为了实现 3D 的 CSS 效果而引入的,后来随着网页及浏览器在界面中的使用需求越来越普遍,Chrome 便在架构中加入了 GPU 进程
  • 插件进程
    主进程会为每个加入浏览器的插件开辟独立的子进程,由于进程间所分配的运行资源相对独立,所以即便某个插件进程意外崩溃,也不至于对浏览器和页面造成影响。另外,出于对安全因素的考虑,采用了沙箱模式,在沙箱中运行的程序受到一些限制:不能读取敏感位置的数据,也不能在硬盘上写入数据。这样即使插件运行了恶意脚本,也无法获取系统权限。
  • 网络进程
    负责页面的网络资源加载,之前属于浏览器主进程的一个模块,最近才独立出来
  • 渲染进程
    也被称为浏览器内核。其默认会为每个标签窗口页开辟一个独立的渲染进程,负责将HTML、CSS、JS等资源转为可交互的界面,其中包含多个子线程,即 JS引擎线程、GUI渲染线程、事件触发线程、定时触发器线程、异步 HTTP 请求线程等。当打开一个标签页输入 URL 后,所发起的网络请求就是从这个进程开始的。另外出于对安全性的考虑,渲染进程也被放入沙箱中。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值