> 文章列表 > web性能优化基础了解

web性能优化基础了解

web性能优化基础了解

一、概述

什么是web性能优化

Web性能网站或应用程序的客观度量和可感知的用户体验。性能优化是指通过各种手段和技术,使前端页面加载、渲染和交互等方面具有更高的性能,以提升用户体验和网站的整体性能。

为什么要做性能优化

性能优化是为了提高网站或应用的响应速度、页面加载速度、用户交互体验等方面,从而提高用户的满意度和用户留存率。同时,也可以减少服务器负载、提高系统的稳定性和安全性。在当前互联网快速发展的背景下,用户对网站和应用的响应速度和体验要求越来越高,因此性能优化显得尤为重要。通过对性能优化的不断优化,可以提高网站和应用的竞争力和用户体验,同时降低运营成本。

二、关注web性能的点

用户的留存

用户留存率指的是在一定时间范围内,用户继续使用某个应用或者产品的概率。例如,某个应用的用户在第一天下载之后继续使用的概率为60%,则第二天的用户留存率为60%。用户留存率通常被视为评估应用或产品质量的重要指标之一,因为它可以反映用户体验的好坏,对于产品的长期发展也至关重要。通常来说,用户留存率越高,说明用户对产品的满意度越高,产品的市场竞争力也就越强。

网站的转化率

网站的转化率是指访问者在网站上执行某种预期操作(如购买商品、填写表单、注册账户等)的比率。通常用一个百分比表示,即转化率=(预期操作的完成次数/网站访问量)* 100%。例如,如果一个网站在一天内共有1000次访问,其中10次是成功购买商品的,那么这个网站的转化率就是1%。转化率是衡量网站营销和用户体验的关键指标之一。提高网站的转化率可以帮助企业增加销售额、提高用户满意度和增加品牌忠诚度。

体验是传播

体验是传播是指用户对网站或产品的好的体验,会被他们传播给他们的朋友、同事、家人等人群,进而产生口碑效应,增加用户粘性,吸引更多的用户使用。如果用户的体验不好,他们也会将这种负面的情绪传播给他们周围的人,从而降低网站或产品的声誉和使用量。因此,提供良好的用户体验是吸引和留住用户的重要因素。

客户投诉

当网站加载速度过慢或者响应时间过长时,用户往往会感到不耐烦,容易导致用户流失、投诉或者差评,这对于企业来说都是不利的。而当网站性能得到提升,可以更快地响应用户请求,减少等待时间,提高用户满意度,从而降低用户投诉的风险。

提升工作绩效

当网站或应用程序的性能得到改善时,用户的等待时间将减少,他们可以更快地完成任务,这将增加用户的满意度并提高生产力。同时,优化代码和减少资源请求也可以减少开发人员在维护和调试方面所花费的时间,从而提高工作效率。

三、性能优化思路

用户输入URL地址后浏览器到页面加载完成的过程,优化主要是针对这个过程的每一步做优化

减少整体加载时间

减少文件体积

在vue项目中的使用方案:

  • 使用生产模式:在生产环境下,Vue默认使用压缩版本的代码,可以有效减少文件体积。可以通过设置process.env.NODE_ENV为production来启用生产模式。
  • 避免引入无用的组件和库:仅仅引入需要的组件和库可以大大减小项目的文件体积。
  • 懒加载路由和组件:在需要的时候才加载路由和组件,可以减少初始加载时的文件体积。可以使用Vue提供的异步组件、Vue异步组件加载器、vue-router等来实现。
  • 使用动态导入:动态导入能够让你在运行时才加载需要的代码,而不是一次性把所有代码加载进来。可以使用import()或require.ensure()来实现。
  • 移除未使用的CSS:在Vue中,可以使用CSS的scoped属性来限制CSS的作用域,这样就可以避免将未使用的CSS样式打包到项目中。
  • 优化图片资源:可以通过压缩图片、使用SVG图标、使用Base64编码等方式来减小图片的大小,从而减小项目的文件体积。
  • 压缩代码:可以使用webpack插件或其他工具来压缩代码,从而减小文件体积。

减少HTTP请求

  • 合并文件:将多个CSS、JavaScript文件合并成一个文件,减少HTTP请求次数。可以使用工具(如Webpack)来实现。
  • 使用CSS雪碧图:将多张小图片合并成一张大图,然后使用CSS的background-position属性来显示对应的图片,以减少HTTP请求次数。
  • 使用字体图标:使用字体图标代替小图片,减少HTTP请求次数。
  • 延迟加载:将页面中不必要的内容(如图片、视频、广告等)延迟加载,只在用户需要时再进行加载,以减少页面的HTTP请求次数。可以使用Vue提供的v-lazy指令或使用第三方库(如vue-lazyload)来实现。
  • 缓存静态资源:可以设置HTTP缓存来缓存静态资源,当再次访问时可以直接从缓存中获取,避免再次发送HTTP请求。
  • 使用CDN:使用CDN(内容分发网络)可以将静态资源分布到多个地理位置的服务器上,从而加快资源的加载速度,并减少HTTP请求次数。
  • 轻量化页面:精简页面中的图片、样式和脚本等,减少HTTP请求次数和文件大小。

使用预加载

  • 使用Vue Router的router.beforeEach方法:在路由跳转之前,使用Vue.prototype.$http来发起一个HTTP请求,将需要预加载的资源(如CSS、JavaScript文件、图片等)加载到缓存中,从而达到预加载的目的。
  • 使用标签预加载资源:在HTML头部中使用标签,将需要预加载的资源(如CSS文件、JavaScript文件、图片等)引入到页面中,设置rel属性为preload,as属性为对应的资源类型,从而实现预加载。需要注意的是,标签只能在HTML头部中使用,不能在Vue单文件组件中使用。
  • 使用标签预加载图片:在Vue单文件组件或HTML文件中使用标签,将需要预加载的图片引入到页面中,设置src属性为对应的图片地址,从而实现预加载。
  • 使用JavaScript动态加载资源:使用JavaScript动态加载需要预加载的资源,将资源加载到缓存中,从而实现预加载。

使网站尽快可用

仅加载首屏内容,其他内容根据需要进行懒加载

平滑和交互性

使用css替代js动画

transition(过渡):通过设置元素的属性变化过渡动画效果,如改变元素的颜色、大小、位置等,可以设置过渡时间、过渡函数等参数。

animation(动画):通过自定义关键帧动画实现元素的动画效果,可以设置动画时间、动画函数、重复次数等参数。

transform(变形):通过对元素进行旋转、缩放、移动等变形操作,实现元素的动画效果,如平移、旋转、缩放等。

scroll-behavior(滚动行为):通过设置滚动行为实现页面的平滑滚动效果,可以设置滚动的持续时间、滚动函数等参数。

减少重绘

使用懒加载:懒加载可以让页面中的组件在需要的时候再加载,避免了一次性加载大量组件的情况,从而减少了重绘的次数。

使用keep-alive缓存组件:使用keep-alive组件可以将需要缓存的组件进行缓存,避免重复渲染和重绘。

使用异步组件:使用异步组件可以让页面中的组件在需要的时候再进行加载,避免了一次性加载大量组件的情况,从而减少了重绘的次数。

感知表现

你的页面可能不能做得更快,要让用户感觉更快,耗时操作有反馈,加载动画、进度条、骨架屏等

骨架屏

骨架屏是一种展示页面加载状态的技术,它可以在页面加载过程中显示一个简单的页面骨架,告诉用户正在加载内容,并给用户留下一个良好的第一印象。骨架屏通常使用 HTML 和 CSS 绘制简单的占位符来模拟页面元素的布局,然后在加载页面内容的同时渲染出骨架屏。

使用骨架屏可以使用户感觉页面加载更快,因为他们可以立即看到页面正在加载,并且可以得到一个大致的页面布局。骨架屏还可以帮助用户集中注意力,减少对页面加载时间的不耐烦和焦虑感。

性能测定

性能指标

页面加载时间:指从用户发起请求到页面完全加载完成的时间。通常可以通过测量页面的DOMContentLoaded事件或load事件来计算。

首次渲染时间:指页面第一次呈现可见内容的时间,即白屏时间。通常可以通过测量performance.timing中的domInteractive时间来计算。

数据加载时间:指数据从服务器到达浏览器的时间,通常可以通过测量网络请求的时间来计算。

页面交互性能:指页面响应用户操作的速度和流畅度,通常可以通过测量页面的事件响应时间和动画帧率来计算。

内存使用情况:指页面所占用的内存大小,通常可以通过Chrome DevTools的Memory面板来查看。

性能测试

使用Chrome DevTools:Chrome DevTools提供了各种性能分析工具,包括网络分析器、时间线分析器、CPU分析器、内存分析器等,可以用来分析和优化页面的性能。

使用WebPageTest:WebPageTest是一个免费的在线工具,可以测试网页的加载速度和性能,并生成详细的报告。

使用Lighthouse:Lighthouse是一个由Google开发的开源工具,可以评估网页的性能、可访问性、最佳实践和SEO等方面,生成详细的报告,并给出改进建议。

使用自动化工具:可以使用自动化测试工具,如Selenium、Puppeteer等,来模拟用户行为,测试网页的性能和交互性能。

性能监控持续优化

网络请求监控:监控页面中各个资源的请求时间、大小、数量等数据指标,可以使用浏览器的开发者工具、网络分析工具(如Har、Charles等)或者第三方工具(如Fiddler、Wireshark等)来进行监控和分析。

页面性能监控:监控页面的加载速度、渲染时间、交互性能等指标,可以使用Performance API、Lighthouse、WebPageTest等工具进行监控和分析。

JS运行性能监控:监控页面中JS脚本的运行时间、占用内存等指标,可以使用Chrome DevTools的Profiler、Firefox的Profiler、v8-profiler等工具进行监控和分析。

错误监控:监控页面中的JavaScript错误、网络请求错误、资源加载错误等错误类型和发生时间,可以使用Sentry、Bugsnag、Rollbar等工具进行监控和分析。

用户体验监控:监控用户行为、页面加载、交互反应等方面的指标,可以使用Google Analytics、Hotjar、Mouseflow等工具进行监控和分析。

四、进行web性能优化

  1. 了解性能指标,多快才算快;
  2. 使用专业工具评估出网站或应用的性能表现;
  3. 根据网站页面响应生命周期,分析出造成较差性能表现的原因;
  4. 进行技术改造、可行性分析等具体的优化实施;
  5. 迭代优化;

性能指标

性能指标是用于衡量系统、软件或应用程序性能的标准或指标。在Web开发中,性能指标是用于衡量网站或应用程序性能的标准或指标。一些常见的Web性能指标包括页面加载时间、响应时间、请求响应时间、带宽、内存使用量、CPU利用率、并发用户数等等。这些指标可以帮助开发者了解应用程序的运行情况,并确定哪些部分需要改进以提高性能和用户体验。

  • 页面加载时间:页面加载时间是指从用户请求页面开始到页面完全加载完成的时间。一般来说,页面加载时间越短越好。建议页面加载时间控制在2-3秒以内。
  • 首次内容渲染时间(FCP):FCP指的是页面开始渲染第一个DOM元素的时间。它是用户体验的重要因素之一,建议FCP时间在1秒以内。
  • 可交互时间(TTI):TTI指的是页面加载完成后用户可以与页面进行交互的时间。一般来说,TTI时间应该在3-5秒以内。
  • 总下载大小:网站的总下载大小会影响页面加载时间。一般来说,建议总下载大小控制在1MB以内。
  • 平均服务器响应时间:服务器响应时间指的是用户发送请求到服务器返回响应的时间。建议服务器响应时间控制在200ms以内。

RAIL性能模型

RAIL 是 Google 提出的一个性能模型,用于指导 Web 应用程序的性能优化。RAIL 的英文全称是 Response, Animation, Idle, Load,它将用户在使用 Web 应用时的行为划分为四种类型,每一种类型对应了一个性能指标。

具体来说,RAIL 将用户行为分为以下四种类型:

  • Response:指应用对用户的输入作出响应的时间,包括输入框响应、按钮点击等,通常需要在 100 毫秒内完成。
  • Animation:指应用中动画的流畅度,通常需要在 10 毫秒内完成一次更新。
  • Idle:指应用在用户没有进行交互时保持活动的程度,包括预加载和缓存数据等操作。
  • Load:指应用在加载页面和数据时的性能,通常需要在 1000 毫秒内完成。

基于用户体验的核心指标

FCP是First Contentful Paint的缩写,指的是页面中首次渲染内容的时间点,也就是用户能够看到页面上第一个有意义的内容的时间点。FCP是Web性能指标中的一项,能够反映用户对页面响应速度的感受。FCP时间越短,用户的感受就越好。

LCP (Largest Contentful Paint) 是 Web Vitals 中的一个指标,它用于度量网页加载时最大的可见内容渲染完成所需要的时间。LCP指的是页面上最大的元素,例如一张大图片、视频、一个文字块等等。LCP 的值应该小于2.5秒,否则用户体验就会受到影响。LCP是衡量页面加载速度和性能的重要指标之一,与其他指标如 FCP、TTFB 和 TTI 等一起,可以帮助开发人员评估网站性能并进行性能优化。

FID代表第一输入延迟(First Input Delay),是Web性能指标之一,衡量用户与网站交互时的响应速度。具体而言,FID衡量的是从用户首次与页面交互(例如点击链接、按钮或填写表单)到浏览器实际响应该交互的时间差。FID的单位为毫秒(ms)。

TTI(Time to Interactive)指的是页面加载后用户可以进行交互操作的时间。它是一个相对新的指标,旨在更准确地衡量页面的实际可用性。与以前的指标不同,例如页面完全加载时间或DOM完成时间,TTI更关注用户交互体验,因为它在所有必要的元素都可用之前,等待所有资源加载完成的页面不会被视为可用。

Total Block Time(TBT),总阻塞时间,度量了FCP和TTI之间的总时间,在该时间范围内,主线程被阻塞足够长的时间以防止输入响应

新一代性能指标:web vitals

Web Vitals是一个由Google提出的Web性能指标集合,旨在帮助网站所有者量化网站的用户体验。Web Vitals由三个核心指标组成:

Largest Contentful Paint(LCP):衡量页面加载的速度。LCP衡量的是视口中最大的可见元素在加载时需要多长时间才能呈现在屏幕上。

First Input Delay(FID):衡量网页的交互性能。FID衡量的是用户首次与页面交互(例如,单击链接、按钮或填写表单)时,浏览器需要多长时间才能响应该操作。

Cumulative Layout Shift(CLS):衡量页面的视觉稳定性。CLS衡量的是页面上所有元素在页面加载期间的移动距离和移动速度的加权和。

网站的Web Vitals指标需要优于一定的阈值,才能为用户提供更好的体验,同时也会得到Google搜索引擎的优化。

性能测量

性能测量指的是对网站或应用程序进行定量和定性评估的过程,以了解其性能如何影响用户体验和业务结果。这通常涉及到对不同性能指标进行监测和测量,例如页面加载时间、交互响应时间、资源大小、缓存策略等等。性能测量可以帮助开发者了解其应用程序的性能瓶颈并确定性能改进的机会,以提高用户体验并最大化业务价值。

浏览器Devtools调试工具

网络监控分析

在Chrome浏览器的开发者工具中,可以使用网络面板(Network Panel)进行网络监控分析。下面是一些具体步骤:

打开开发者工具:在Chrome浏览器中,按下F12或者Ctrl+Shift+I打开开发者工具。

打开网络面板:点击开发者工具的顶部菜单栏中的Network选项卡打开网络面板。

开始记录网络请求:在网络面板上方有一个记录按钮,点击该按钮,即可开始记录浏览器中的所有网络请求。

进行网络分析:记录网络请求后,可以进行各种网络分析,如查看请求时间、大小、类型、状态码等等,还可以查看请求详情和响应内容,分析网络性能瓶颈和优化方案。

保存和导出:在网络面板中,还可以将记录的网络请求数据保存为HAR文件格式,方便进行离线分析和分享。

性能监控分析

在DevTools中进行性能监控分析,可以使用Chrome自带的Performance面板。在Performance面板中,可以记录Web页面的所有活动,包括JavaScript执行、CSS计算、布局、绘制等等,从而可以进行全面的性能分析。

具体操作步骤如下:

  • 打开Chrome浏览器,进入需要监控的网站页面。
  • 在浏览器中按下F12键或者点击右上角的三个点,选择“更多工具”->“开发者工具”,打开DevTools。
  • 在DevTools中选择Performance面板。
  • 点击左上角的“开始记录”按钮,开始记录性能数据。
  • 在页面上进行操作,例如点击按钮、滚动页面等等。
  • 点击左上角的“停止记录”按钮,停止记录性能数据。

分析性能数据。在Performance面板中可以看到所有的性能数据,包括时间轴、JavaScript执行、布局、绘制等等,可以对每一个数据进行详细的分析和调优。

灯塔(Lighthouse)

Lighthouse是一个开源的自动化工具,用于改进网络应用的质量。它可以运行在Chrome浏览器或者命令行中。下面是使用Lighthouse进行网站性能分析的步骤:

  • 打开Chrome浏览器,打开你要分析的网站。
  • 打开Chrome开发者工具,点击Lighthouse标签页。
  • 点击“Generate report”按钮,等待分析结果。
  • 分析结果将会展示在不同的类别中,如性能、可访问性、最佳实践等。每个类别都会有一个得分和具体的建议。

你可以根据得分和建议来优化你的网站,然后再次运行Lighthouse以验证优化效果。

WebPageTest

WebPageTest 是一款常用的在线性能测试工具,提供了丰富的测试项和详细的报告,可以帮助开发人员深入了解网站的性能表现和问题。

以下是使用 WebPageTest 进行测试的步骤:

  • 打开 WebPageTest 网站(https://www.webpagetest.org/)。
  • 在网站首页,选择要测试的浏览器和测试地点。
  • 在 “Advanced Settings” 中设置测试选项,例如要测试的 URL、测试次数、浏览器缓存、带宽限制、CPU 效能等。
  • 点击 “Start Test” 开始测试。
  • 测试完成后,可以在测试结果页面中查看详细的测试结果,包括页面加载时间、HTTP 请求和响应、DOM 加载时间、首次渲染时间等等。
  • 如果需要更详细的测试报告,可以下载测试结果的 HAR 文件或者进行截图。

需要注意的是,WebPageTest 进行测试时会模拟真实用户的网络环境,因此测试结果会受到多种因素的影响,如网络带宽、服务器响应速度等。建议在测试前先了解测试环境,以便更准确地解读测试结果。

生命周期

在浏览器的地址栏是输入了一个地址后的一整个过程。

  1. 浏览器接受到URL,到网络请求线程的开启
  2. 一个完整的HTTP请求链接,建立请求通信
  3. 服务器接收到请求并转到具体的处理后台
  4. 前后台之间的HTTP交互和涉及的缓存机制
  5. 浏览器接收到数据包后的关键渲染路径
  6. JS引擎的解析过程

网络请求线程开启

浏览器接收到我们输入的URL到开启网络请求现成,这个阶段是在浏览器内部完成。

名称 释义 备注
Protocal 协议头 常见的有HTTP、FTP、Telnet
Host 主机域名、IP地址 所访问资源字互联网中的地址,主机域名会经DNS解析为IP地址
Port 端口号
Path 目录路径
Query 查询参数
Fragment 片段 路由或锚点

进程和线程之间的区别

  1. 某个线程执行出错,将会导致整个进程崩溃
  2. 进程与进程之间相互隔离
  3. 进程所占用的资源会在其关闭后由操作系统回收
  4. 线程之间可以共享所属进程的数据

多进程浏览器

  1. 浏览器主进程:一个浏览器只有一个主进程,负责如菜单栏、标题栏等界面显示,文件访问、前进回退、子进程管理等
  2. GPU进程:图形处理单元为了实现3D的CSS效果引进的
  3. 插件进程:主进程会为每个加入浏览器的加减开辟独立的子进程
  4. 网络进程:负责页面的网络资源加载,之前属于浏览器主进程中的一个模块
  5. 渲染进程:也称为浏览器内核,默认会为每个标签窗口页开辟一个独立的渲染进程,负责讲HTML、CSS和JavaScript等资源转为可交互的页面,包含多个子线程,JS引擎线程、GUI渲染线程、事件触发线程、定时触发器线程、异步HTTP请求线程

建立HTTP请求

HTTP请求的建立可以分为以下几个步骤:

  • DNS解析:客户端向DNS服务器发送请求,将主机名解析为IP地址。
  • TCP连接:客户端使用IP地址和端口号(默认80)与服务器建立TCP连接。
  • 发送请求:客户端向服务器发送HTTP请求,包括请求行、请求头和请求体。
  • 服务器处理请求:服务器接收到请求后,进行处理并生成响应。
  • 接收响应:客户端接收到响应,包括响应行、响应头和响应体。
  • 关闭连接:客户端和服务器都可以在任何时候关闭连接,HTTP/1.0默认在每个请求/响应后关闭连接,HTTP/1.1默认使用持久连接,在多个请求/响应中重用连接。

以上是HTTP请求建立的基本过程,具体实现细节和HTTP版本有所不同。例如,HTTP/2使用二进制协议和多路复用来提高性能,HTTPS在TCP连接建立后还需要进行TLS握手等操作。

DNS解析

DNS查询

递归查询

  1. 浏览器缓存
  2. 系统自身DNS缓存
  3. hosts文件

迭代查询

  1. 本地域名服务器
  2. 根域名服务器(告知顶级域名服务器)
  3. COM顶级域名服务器(告知权限域名服务器)
  4. 权限域名服务器(返回IP或报错)
网络模型

传统七层OSI

应用层、表示层、会话层、传输层、网络层、数据链路层、物理层

TCP/IP模型

应用层、传输层、网络层、数据链路层

TCP连接
建立链接的三次握手

三次握手是TCP协议中用于建立一个可靠的数据传输连接的过程。该过程需要客户端和服务端之间交换三个不同的数据包,以确保连接能够成功建立。

具体的过程如下:

  • 客户端向服务端发送SYN(同步)数据包,表示它想要建立一个连接。这个数据包包含客户端选择的一个随机序列号,用于在连接期间标识客户端的数据包。
  • 服务端收到SYN数据包后,发送一个SYN-ACK(同步-确认)数据包作为响应。该数据包包含一个服务端选择的随机序列号,以及确认客户端的SYN数据包。服务端还将在该数据包中设置标志位,告诉客户端连接正在建立中。
  • 客户端收到SYN-ACK数据包后,发送一个ACK(确认)数据包。该数据包包含服务端随机序列号加一的值,以及客户端标识的序列号。这表明客户端已成功接收到服务端的确认,并且连接已经建立。
断开链接的四次挥手

四次挥手(Four-way handshake)是指在TCP连接的拆除过程中,客户端和服务器端共需要发送四个包以确认连接的拆除,详细过程如下:

  • 第一次挥手:客户端发送一个FIN报文,报文中会指定一个序列号(seq=x)。
  • 第二次挥手:服务器端收到FIN报文后,会发送一个ACK报文,且把客户端发来的序列号+1作为ACK报文的序列号(ack=x+1),- 表示已经收到客户端的报文了,但还没有准备好关闭连接。此时,TCP连接进入半关闭状态,客户端不能再向服务器端发送数据,但是可以接收数据。
  • 第三次挥手:当服务器端准备好关闭连接时,会发送一个FIN报文,报文中会指定一个序列号(seq=y),表示数据已经发送完毕。
  • 第四次挥手:客户端收到FIN报文后,会发送一个ACK报文,且把服务器发来的序列号+1作为ACK报文的序列号(ack=y+1),表示已经收到服务器端的报文了。此时,TCP连接会关闭,进入TIME_WAIT状态,等待2MSL(最大报文存活时间)后释放连接。

前后端的交互

当TCP连接建立好之后,便可以进行前后端的通信

反向代理服务器

  • 负载均衡
  • 安全防火墙
  • 加密和SSL加速
  • 数据压缩
  • 解决跨域
  • 对静态资源缓存

优化方案

  • 从发出请求到收到响应的优化,DNS查询、HTTP长连接、HTTP2、HTTP压缩、HTTP缓存
  • 关键渲染路径优化,是否有不必要的重绘和回流
  • 加载过程的优化,比如延迟加载,首屏加载
  • 资源优化,图片,视频不用的使用场景
  • 构建优化,压缩合并、基于webpack的构建优化方案

请求响应优化

DNS解析
  1. 减少DNS的查找请求次数

进行DNS预获取:DNS Prefetch

更多DNS解析优化

  1. 延长DNS缓存时间
  2. 尽可能使用A或AAAA记录代替CNAME
  3. 使用CDN加速域名
  4. 自己搭建DNS服务

HTTP长连接

HTTP长连接指在一个TCP连接上可以传输多个HTTP请求和响应消息。与短连接相比,长连接可以减少每次连接的建立和关闭的开销,提高数据传输的效率。

在HTTP/1.0中,默认是短连接,也就是每个HTTP请求都需要新建一个TCP连接。但是,这样会造成性能上的损失,因为建立TCP连接的过程是很费时的。因此,HTTP/1.1增加了对持久连接(即长连接)的支持,也就是在同一个TCP连接上可以发送多个HTTP请求,这样就可以减少建立TCP连接的次数,降低了网络延迟,提高了性能。

需要注意的是,虽然长连接可以减少TCP连接的建立和关闭开销,但是如果连接持续时间过长,会导致连接池中的连接被占满,从而影响性能。因此,需要适当地设置长连接的超时时间或关闭长连接,以避免过多的连接占用资源。

HTTP2协议

HTTP/2是一种网络协议,是HTTP/1.x的后继者,目的是提高web性能,特别是页面加载速度。HTTP/2是在SPDY(由Google开发的协议)的基础上发展而来,与HTTP/1.x的主要不同点如下:

  • 多路复用:HTTP/2使用了多路复用技术,通过单一的HTTP/2连接,可以实现同时发送多个请求和响应,避免了HTTP/1.x中由于每个请求都需要建立连接和断开连接导致的性能瓶颈。
  • 二进制分帧:HTTP/2采用了二进制分帧技术,将请求和响应数据分割成更小的帧(Frame)并对它们进行编码和压缩,从而降低延迟和带宽的占用。
  • 头部压缩:HTTP/2使用了HPACK压缩算法对请求和响应头部进行压缩,降低了数据传输的大小,提高了网络性能。
  • 服务器推送:HTTP/2支持服务器推送,服务器可以在客户端请求资源之前预测客户端需要的资源并主动推送给客户端,从而进一步提高页面加载速度。

压缩传输的数据资源

为了提高网络传输的效率,我们可以对传输的数据进行压缩。常见的压缩方式有以下几种:

  • Gzip:Gzip 是一种常用的压缩算法,可以对文本、样式表、JavaScript 文件等进行压缩,可以显著地减小传输数据的大小,从而提高传输效率。大多数现代的 Web 服务器都支持 Gzip 压缩,可以通过设置响应头中的 Accept-Encoding 字段来告诉服务器客户端支持的压缩算法。
  • Brotli:Brotli 是一种相对于 Gzip 更加高效的压缩算法,它可以在更小的传输数据量下提供更好的压缩率,但相应的计算成本也更高。Brotli 也是一种服务器端压缩算法,可以通过设置响应头中的 Accept-Encoding 字段来告诉服务器客户端支持的压缩算法。
  • 图片压缩:对于图像等二进制数据,可以使用图片压缩算法进行压缩,常见的图片压缩算法包括 JPEG、PNG、WebP 等。在传输图片时,可以选择使用适合场景的图片压缩算法,可以减小传输的数据量,从而提高传输效率。
  • 数据分片:对于较大的数据,可以将其分成多个小块进行传输,这样可以在网络故障或者其他问题导致数据传输失败时,只需要重新传输失败的小块数据,而不需要重新传输整个数据。

缓存

浏览器缓存指的是浏览器在访问网站时,将一些静态资源如图片、CSS、JavaScript等文件缓存在本地磁盘中,以便下次访问相同的网站时可以直接从本地缓存读取这些资源,从而加快页面加载速度,减少网络请求和服务器负载。

强制缓存

强制缓存是浏览器缓存机制的一种,它允许将静态资源(如图片、CSS、JavaScript 等)在第一次请求后缓存在浏览器中,以便在下一次请求该资源时能够从本地缓存中获取,而不必重新请求服务器。强制缓存是通过设置 HTTP 响应头来实现的。当设置了强制缓存之后,即使资源有更新,浏览器也不会请求最新版本的资源,而是直接从本地缓存中获取。

常用的设置强制缓存的响应头字段包括:Cache-Control 和 Expires。Cache-Control 用于设置缓存的控制策略,常见的值包括 max-age(最大缓存时间)和 public(表示响应可以被任何对象缓存),Expires 是一个日期,表示缓存的过期时间。当浏览器从缓存中获取资源时,会比较本地资源的缓存时间和服务器上资源的更新时间,如果本地资源没有过期,则直接使用本地缓存;否则才会向服务器请求最新版本的资源。

需要注意的是,强制缓存只对首次请求有效,也就是说,当第一次请求某个资源时,如果设置了强制缓存,浏览器会缓存该资源,并在接下来的请求中直接使用本地缓存。但是当资源的缓存过期后,浏览器会重新向服务器请求资源,并更新本地缓存。

协商缓存

协商缓存指的是客户端和服务器之间的一种交互方式,用于判断缓存是否有效,从而决定是否从缓存中获取资源。它通过在请求头中添加一些字段信息(如 If-Modified-Since 和 If-None-Match)来告诉服务器需要的资源以及自己缓存的版本,服务器通过比较客户端和服务器缓存版本的新旧来判断是否需要重新传输资源。如果资源未被修改,则服务器返回 304 Not Modified 状态码,客户端直接从缓存中获取资源。这种方式相对于强制缓存,具有更灵活的控制能力,能够在资源更新时及时获取最新的版本,减少了缓存失效的风险。

缓存决策

缓存决策是指浏览器在加载资源时,通过判断缓存是否命中来决定是从服务器获取资源还是从缓存中获取资源的过程。当浏览器需要获取资源时,首先会根据资源的 URL判断该资源是否被缓存。如果缓存命中,浏览器会检查缓存中的资源是否过期或者是否需要验证缓存是否可用,如果满足条件则直接从缓存中读取该资源;如果缓存未命中,则从服务器获取资源,并将该资源缓存起来,以备下次使用。缓存决策的目的是提高资源的加载速度,减少网络带宽的消耗,提升用户的访问体验。

CDN缓存

CDN全称Content Delivery Network,即内容分发网络,它是构建在现有网络基础上的虚拟智能网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、调度及内容分发等功能模块,使用户在请求所需访问的内容时能够就近获取,以此来降低网络拥塞,提高资源对用户的响应速度。

五、渲染优化

浏览器从获取HTML到最终在屏幕上显示需要完成步骤:

  1. 处理HTML标记并构建DOM树
  2. 处理CSS标记并构建CSSOM树
  3. 将DOM与CSSOM合并成一个render 树
  4. 根据渲染树来布局,计算每个节点的几何信息
  5. 将各个节点绘制到屏幕上

优化CSSOM

优化 CSSOM 可以提高页面的渲染性能,以下是一些常见的优化方式:

  • 减少样式规则数量:样式规则越多,浏览器计算样式的时间就会越长。可以通过合并样式规则、删除冗余样式等方式来减少样式规则数量。
  • 避免使用通配符选择器:通配符选择器会匹配页面中所有的元素,对于大型页面来说,匹配的元素数量可能非常多,导致计算样式的时间过长。
  • 避免使用类属性选择器:类属性选择器会遍历 DOM 树,寻找匹配的元素。当样式规则中使用了多个类属性选择器时,计算样式的时间会非常长。
  • 避免使用复杂选择器:复杂选择器包括后代选择器、子选择器、相邻选择器和通用兄弟选择器等。这些选择器在计算样式时需要进行多次匹配,因此会拖慢页面的渲染速度。
  • 避免使用!important:使用!important会强制浏览器应用样式规则,导致浏览器重新计算样式,影响页面的渲染速度。
  • 减少样式表的数量:当页面中包含多个样式表时,浏览器需要下载、解析和计算多个样式表,导致页面的渲染速度变慢。可以通过将多个样式表合并成一个样式表来减少样式表的数量。
  • 避免在 JavaScript 中直接修改样式:直接修改样式会导致浏览器重新计算样式和布局,影响页面的渲染速度。可以通过修改类名来改变元素的样式,从而避免直接修改样式。

使用requestAnimationFrame

requestAnimationFrame 是浏览器提供的一个 API,用于优化动画、渲染等场景中的性能表现。它通过在浏览器下次重绘之前调用一个回调函数来实现动画效果,而且可以自动协调回调函数的执行时间,保证了动画的流畅性和性能。

与传统的定时器(例如 setInterval 和 setTimeout)相比,requestAnimationFrame 的优势在于:它能够避免在屏幕显示之前不必要的计算和渲染,从而减少了闪烁、卡顿等问题,同时还能最大限度地减少电池的能耗,保护用户设备的使用时间。

使用 requestAnimationFrame 通常的步骤如下:

  • 定义一个回调函数,用于在下一次重绘之前进行某些操作,例如修改元素的位置、大小、颜色等等。
  • 调用 requestAnimationFrame 函数,并将上述回调函数作为参数传入。
  • 在回调函数中更新元素的状态,然后再次调用 requestAnimationFrame 函数,实现动画的连续播放。

使用WebWorker线程

  • DOM限制:webworker不能操作dom
  • 文件读取限制:不能加载网络中的脚本:无法访问本地文件系统
  • 通信限制:(主线程和Worker子线程不在同一个上下文中,无法直接进行通信,只能通过消息来完成)
  • 脚本执行限制:可以通过XMLHTTPRequrest对象发起ajax请求,不能使用alert()和confirm()方法在页面弹出提示
  • 同源限制:子线程执行的代码文件需要与主线程的代码文件同源

事件节流和防抖

使用lodash

debounce防抖

直到时间停止时间间隔后才执行对应的事件

throttle节流

是事件会在一定的时间间隔中执行对应的方法

function throttle(fn, delay) {let lastTimelet timerdelay || (delay = 300) // 默认间隔300msreturn function(arguments) {let context = thislet args = argumentslet nowTime = +new Date() // 获取系统当前时间if(lastTime && nowTime < lastTime + delay) {clearTimeout(timer) // 清除定时器timer = setTimeout(function(){// delay时间后,执行函数lastTime = nowTimefn.apply(context, args)}, delay)}else{lastTime = nowTimefn.apply(context, args)}}
}

计算样式优化

计算样式优化是一种优化网页性能的方法,它的目的是减少浏览器计算样式所需的时间。当浏览器在渲染页面时,它必须计算出每个元素应该具有的样式,以便正确地呈现它们。这个过程可能会消耗大量的时间,尤其是当页面中有大量元素时。

计算样式优化的目的是通过减少计算样式所需的时间来提高页面的加载速度。其中一些方法包括:

  • 使用具体的CSS选择器:使用具体的CSS选择器可以帮助浏览器更快地匹配元素并计算它们的样式。
  • 避免使用通配符:通配符选择器(例如*)会匹配页面上的每个元素,这可能会导致性能问题。
  • 避免使用昂贵的选择器:某些选择器(例如nth-child)可能需要更长的时间来计算样式。
  • 最小化重排和重绘:当元素的样式更改时,浏览器必须重新计算元素的布局和重新绘制元素。减少这些操作的次数可以提高页面的性能。
  • 使用CSS预处理器:CSS预处理器(例如Sass或Less)可以帮助您编写更简洁、更有组织的CSS,并自动优化它们的输出,以减少浏览器计算样式所需的时间。

BEM

BEM是一种用于前端开发的命名约定,全称为“块(Block)、元素(Element)、修饰符(Modifier)”。

BEM的基本思想是将页面看做是一个由多个组件组成的集合,每个组件都是相对独立的,拥有自己的特定样式和行为。BEM规定,每个组件由一个块(Block)和其内部的一个或多个元素(Element)组成,块和元素使用双下划线(__)连接,如block__element。同时,可以通过添加修饰符(Modifier)来改变组件的外观和行为,修饰符使用双破折号(–)连接,如block–modifier。

使用BEM的好处在于它提供了一种清晰、简洁的命名方式,能够有效地避免样式污染和样式重复定义的问题,同时也能够方便地组织和维护大型项目的样式代码。

页面布局与重绘

Ctrl + shift + P 输入 rendering

在浏览器控制台输入rendering命令通常会启动一个工具,它可以用来检查当前页面的渲染性能并进行分析。这个工具通常会提供一些有用的指标,例如页面加载时间、DOM渲染时间、CSS渲染时间等。此外,它还可以提供一些有用的提示和建议,例如如何优化页面性能、如何减少DOM重绘等。这个工具通常被用来分析和优化Web应用程序的性能,以提高用户体验和页面加载速度。