HTTP
减少http请求
-
合并文件是一种减少HTTP请求的方式,通过合并多个Js文件到一个Js文件,合并多个CSS文件到一个CSS文件的方式。
-
CSS Sprites是减少图片请求首选的方法。把你的背景图片合并到一张图片中,使用CSS的background-image和background-position属性来展示期望的图片部分。
-
Inline images 使用data:URL scheme把图片数据内嵌到当前页面中。这种方式会增加HTML文档的大小。把Inline images写到(缓存的)样式文件中是减少HTTP请求的同时避免增加页面大小的一种方法。
-
<img src="data:image/<filetype>;base64,<data>" alt="embedded image" />
-
<filetype>
表示图像文件类型(如 png、jpeg 等),<data>
表示文件数据,使用 base64 编码。 -
<img src="data:image/png;base64,iVBORw0KGgoAAAAN..." alt="embedded image" />
-
-
使用缓存
- 强缓存
- 协商缓存
-
使用
LocalSrorage
-
延迟加载
- 可以将页面中不需要立即加载的资源进行延迟加载,例如使用 LazyLoad 技术实现图片懒加载,减少初始页面的资源请求量和加载时间。
- 组件按需加载
减小请求资源大小
- 可以使用压缩文件、减小图片文件大小等方式。
Accept-Encoding: gzip, deflate
- 压缩js和css
- 压缩的做法就是移除代码中不必要的字符减少文件大小进而提升加载速度。
请求空闲期间
- 组件预加载
- 利用网络空闲事件,进行资源加载
DNS解析优化
- 减少 DNS 查询次数:将静态资源和动态资源部署在不同的域名下,减少同一域名下的 DNS 查询次数。
- 减少 DNS 解析时间:可以通过缓存DNS解析结果来减少DNS解析时间,具体可以通过浏览器缓存和DNS缓存两种方式来实现。
- 使用DNS预解析:在HTML头部加入
<link rel="dns-prefetch" href="//example.com">
,可以告诉浏览器提前解析DNS,提高网页打开速度。 - 选择最优的 DNS 解析服务商:可以通过选用更快速、稳定的DNS服务商来提高DNS解析速度,如Google Public DNS、OpenDNS等。
CDN加速
- 可以使用 CDN(Content Delivery Network,内容分发网络)技术,将资源分发到离用户最近的节点,减少请求时间和带宽成本。
HTTP协议的选择
- 选用http2
- http2 可以进行多路复用,即跟同一个域名通信,仅需要一个 TCP 建立请求通道,请求与响应可以同时基于此通道进行双向通信,而 http1.x 每次请求需要建立 TCP,多次请求需要多次连接,还有并发限制,十分耗时
- http2 可以头部压缩,能够节省消息头占用的网络的流量,而HTTP/1.x每次请求,都会携带大量冗余头信息,浪费了很多带宽资源
- http2可以进行服务端推送,我们平时解析 HTML 后碰到相关标签才会进而请求 css 和 js 资源,而 http2 可以直接将相关资源直接推送,无需请求,这大大减少了多次请求的耗时
减小COOKIE大小
- 可以在页面中设置
cookie
白名单,意思就是定期检查我们的cookie
,如果是需要的就保留,不需要的就删除,定期整理。cookie
控制可以减小页面间传输的大小,也可以对cookie
进行有效的管理。
避免重定向
- 避免使用重定向链。尽可能减少重定向链,特别是多个301重定向
- 使用缓存。在重定向后,可以使用缓存来缓存结果,从而减少下一次请求的时间。
CSS
- 将css文件放在顶部
- CSS 执行会阻塞渲染,阻止 JS 执行
- 避免css表达式(例如:calc())
- CSS表达式的问题是计算太频繁了
- 避免使用通配符选择器和后代选择器
- 这些选择器的匹配效率较低,会增加浏览器的渲染时间。如果必须使用,可以将其用在更具体的选择器中。
- 选择
<link>
而不是@import
link
:浏览器会派发一个新的线程(HTTP线程)去加载资源文件,与此同时GUI渲染线程会继续向下渲染代码@import
:GUI渲染线程会暂时停止渲染,去服务器加载资源文件,资源文件没有返回之前不会继续渲染(阻碍浏览器渲染)style
:GUI直接渲染
- 减少回流与重绘
- 不要频繁操作元素的样式,对于静态页面,可以修改类名,而不是样式。
- 将元素先设置
display: none
,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。 - 避免频繁操作DOM,可以创建一个文档片段
documentFragment
,在它上面应用所有DOM操作,最后再把它添加到文档中 - 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。
- css应该包含在外部文件中,还是内联在页面里面?
- 内联在页面,增加html的大小
- 外部文件可以被缓存,不会增加请求次数
js
-
将js文件放在底部
- JS 加载和执行会阻塞 HTML 解析,阻止 CSSOM 构建
-
避免重复引入相同的js文件
- 减少请求
- 减少脚本执行时间
-
<script>
标签的引入资源方式有三种,有一种就是我们常用的直接引入,还有两种就是使用 async 属性和 defer 属性来异步引入,两者都是去异步加载外部的JS文件,不会阻塞DOM的解析(尽量使用异步加载)。三者的区别如下:- script 立即停止页面渲染去加载资源文件,当资源加载完毕后立即执行js代码,js代码执行完毕后继续渲染页面;
- async 是在下载完成之后,立即异步加载,加载好后立即执行,多个带async属性的标签,不能保证加载的顺序;
- defer 是在下载完成之后,立即异步加载。加载好后,如果 DOM 树还没构建好,则先等 DOM 树解析好再执行;如果DOM树已经准备好,则立即执行。多个带defer属性的标签,按照顺序执行。
-
js应该包含在外部文件中,还是内联在页面里面?
- 内联在页面,增加html的大小
- 外部文件可以被缓存,不会增加请求次数
HTML
-
精简 HTML 结构和代码
- 删除无用的标签、属性和注释。减小 HTML 文件大小可以加速页面加载和解析。
-
减少 DOM 元素数量
- 使用 CSS 实现样式效果,减少 DOM 元素数量可以减少页面渲染时间。
-
避免使用嵌套过深的标签,过多的标签嵌套会导致解析效率降低。
-
优化事件处理
- 减少事件处理程序的数量:避免使用太多的事件处理程序,因为每个处理程序都会增加页面的负担。可以尝试将多个事件处理程序合并为一个。
- 使用事件委托:使用事件委托可以减少事件处理程序的数量,尤其是当页面中有大量的元素需要绑定事件时。可以将事件处理程序绑定到一个祖先元素上,然后利用事件冒泡机制,让祖先元素代为处理所有子元素的事件。
- 避免在循环中绑定事件处理程序:在循环中绑定事件处理程序可能会导致性能问题,因为每次循环都会重新绑定事件处理程序。可以考虑使用事件委托来避免这种情况。
- 使用事件节流和防抖:事件节流和防抖可以减少事件处理程序的触发次数,从而提高页面的性能。事件节流是指在一定时间内只执行一次事件处理程序,而事件防抖是指在一定时间内只有最后一次触发事件才会执行事件处理程序。
- 删除不必要的事件处理程序:如果页面中存在不必要的事件处理程序,可以将其删除以提高页面的性能。
总结
网页性能优化通常可以从以下几个方向进行优化:
-
减少 HTTP 请求:尽量减少页面中的 HTTP 请求次数,合并 CSS 和 JS 文件,利用浏览器缓存来减少请求次数。
-
压缩文件大小:利用 gzip 压缩算法对文本文件进行压缩,减少文件大小。
-
使用 CDN:利用内容分发网络(CDN)来缓存文件,提高文件加载速度。
-
使用异步加载:使用异步加载方式,例如将 JavaScript 脚本放在页面底部,利用 async 和 defer 属性等方式异步加载 JS 脚本和 CSS 样式表。
-
图片优化:优化图片文件大小,尽量使用 CSS3 图片效果代替图片,使用懒加载或预加载等技术来优化图片加载。
-
避免重定向:避免重定向,减少请求次数。
-
优化事件处理:避免不必要的事件监听和事件冒泡。
-
CSS 优化:使用合适的选择器,避免使用 CSS 表达式、重复的样式等。
-
HTML 优化:使用合适的标签、语义化的 HTML 代码等。
-
JS 优化:避免全局变量、减少 DOM 操作、避免重复计算等。
如何回答面试官
从访问页面的开始说起:
-
在地址栏输入网址,解析url
-
缓存判断
优化:
- 开启缓存
- 强缓存
- 协商缓存
- 开启缓存
-
DNS解析
优化:
- DNS预解析
- 减少 DNS 解析时间
- 减少 DNS 查询次数
- 选择最优的 DNS 解析服务商
-
获取MAC地址
-
TCP/IP握手
对协议的选择,减少tcp/ip握手次数
优化:
- http1.0 开启长连接(
Connection: keep-alive
) - http1.1 默认开启长连接
- http1.x 请求-应答 模型,有http队头堵塞问题
- http2.0
- 解决了http队头堵塞,但有tcp层的堵塞未解决
- http1.0 开启长连接(
-
https握手
硬件方面
- 加密算法需要硬件的支持
对协议和算法的选择,减少https握手
-
TLS1.2
- RSA 密钥交换算法 四次握手
- ECDHE 密钥交换 第 3 次握手后,第 4 次握手前,发送加密的应用数据
-
TLS1.2(四次握手)&TLS1.3(两次握手)
-
返回数据
优化:
- 可以使用压缩文件、减小图片文件大小等方式
-
页面渲染
页面渲染流程:
-
html的解析,构建一棵 DOM 树
优化:
- 精简 HTML 结构和代码
- 减少 DOM 元素数量
- 避免使用嵌套过深的标签,过多的标签嵌套会导致解析效率降低。
- 优化事件处理
-
对 CSS 进行解析,生成 CSSOM 规则树
优化:
- 将css文件放在顶部
- 避免css表达式(例如:calc())
- 避免使用通配符选择器和后代选择器
- 选择
<link>
而不是@import
- 减少回流与重绘
- css精灵图
-
根据 DOM 树和 CSSOM 规则树构建渲染树
-
根据渲染树来进行布局
-
布局阶段结束后是绘制阶段
-
合并图层
-
-
TCP四次挥手
-
页面展示后,就是与页面的交互
- 防抖节流
- 图片懒加载
- 组件预加载
- 避免频繁操作DOM,可以创建一个文档片段
documentFragment
,在它上面应用所有DOM操作,最后再把它添加到文档中
还可以穿插着说说减少http请求、异步加载js&css、
优化的方向有很多,但尽量往自己了解熟悉的方向说,面试官很有可能从你说的优化方向深入问下去
例如:
- css精灵图如何实现
- 什么是缓存机制
- 手撕防抖节流
- 懒加载思路
- http1.0&http1.1&http2.0区别、优缺点
- 这里很有可能就问到计网方向去的问题
- 请求头字段、状态码
- 等等