web前端性能优化 —— 前端人必需的知识储备

简介: 本文较长,也比较全,从多个维度、各个阶段来谈前端性能优化的各种实用技巧。(重点与难点放了图片解析,希望能够对大家有所帮助)

本文较长,也比较全,从多个维度、各个阶段来谈前端性能优化的各种实用技巧。(重点与难点放了图片解析,希望能够对大家有所帮助)


请求阶段


开启HTTP2

多路复用,突破TCP连接数限制。

头部压缩,节省请求带宽。

二进制分帧方式,提高通信效率。

1.png

  • 开启http缓存
  • 利用Expires和Cathe-Control开启强缓存
  • 利用Last-Modified/If-Modified-Since开启协商缓存


2.png

  • 开启gzip压缩
  • 降低关键资源的带宽体量(实测可压缩60%以上)

3.png

缩小请求头

减少一些不必要的Cookie信息携带。

利用CND(把大文件的加载变成一个请求,直接拿过来用,适用于大图、大文件)

减少单次RTT时长,加速资源获取。

4.png


域名分片


将一个网站的资源放在多个域名下面,拓展TCP连接数。

降低HTTP请求数


CSS和JS,根据实际情况,进行内联与合并。


图片合成雪碧图,小图片base64化。


避免css @import。


可以用CSS实现的不要用图片,再小的图片也是一个请求!


避免重定向


避免延迟整个HTML文档的传输。

DNS预解析

// 打开DNS预读取
<meta http-equiv="x-dns-prefetch-control" content="on">
// 强制查询特定主机名
<link rel="dns-prefetch" href="http://example.com">

5.png6.png

域名预连接

<link rel="preconnect" href="http://example.com">


加载阶段



资源压缩


对前端资源进行压缩

加载时机


js设置为异步加载(defer/async)

加载策略


SPA业务中,模块按需加载(路由懒加载)


css媒体查询,定义场景加载


图片懒加载


预获取


<link rel="prefetch" href="image.png">

预加载

<link rel="preload" href="image.png">


渲染阶段



预渲染

<link rel="prerender" href="image.png">

避免使用iframe


iframe连接页面后,会开启独立的页面进程,消耗资源

HTML优化


控制html标签层级,减轻解析负担,降低解析时间


首屏html可以少量,主体结构动态插入


CSS优化


CSS文件放head,让CSSOM先行,避免阻塞渲染树


控制css选择器层级,不要太深,降低匹配开销


尽量用id和class选择器,不要过渡层叠


避免使用通配符,提高匹配效率


JS优化


JS文件放在body底部,避免阻塞DOM树构建


避免在body内容中间插入script脚本


JS异步加载,设置defer/async


运行阶段




CSS层面


给图片设置尺寸,避免载入显示后,造成重排


巧用绝对定位,脱离文档流,避免后续操作,造成重排


因为绝对定位的元素一般处于默认复合层,所以它的改变还是会造成整个图层的重绘

巧用合成属性(will-change/3D transform)


新建合成层,独立于默认复合层,后续改变不会造成重拍/重绘


因为是合成层,运作基于合成线程,未占用主线程,效率较高


能用CSS实现的效果,尽量不用JS实现,充分发挥合成线程的能力


利用合成属性时,一定要设置z-index,防止后面的重叠元素同样被游览器新建图层,浪费资源


JS层面


巧用异步处理,减少js对主线程的长时占用(定时器/Web Worker)


不影响this的情况下,对反复访问的对象进行变量保存


避免过长的对象层次访问,提高读取效率


合理使用局部变量,减少作用域跨越


减少使用for...in循环,避免遍历原型链


巧用事件委托,降低事件绑定的内存占用


慎用闭包,避免使用with和eval


条件判断上,避免类型转换


条件较多时,使用switch代替if..else


最小化语句数,避免多个声明


简化终止条件,简化循环体,减值迭代


减少字符串拼接,避免"临时字符串"的出现


当叠加字符串的时候,字符串变量应该靠左


数组join方法,比其他字符串连接方式慢


字符串concat方法,比使用简单的+和+=慢


DOM层面


尽量用新选择器API代替老API


尽量通过Id和Class选择器进行DOM获取


避免直接操作style进行布局信息修改,造成重排


避免强制同步布局(在JS更改DOM信息后,立即访问)


DOM集合操作非常昂贵,应转换为数组再进行操作


对dom访问信息进行缓存,对dom改变进行批量操作


对操作频繁的dom,尽可能采用position:absolute(避免重排)


对操作密集的dom,先display:none——>操作——>再display:block(避免重排)


对操作量很大的dom,采用文档碎片createDocumentFragment


webApi层面


用requestAnimationFrame代替setTimeOut/setInterval进行动画实现(这一点是大多数人不知道的,画重点)


根据业务情况,适时使用Storage和IndexDB缓存数据,减少不必要的ajax请求


利用Web Worker处理无关dom的任务,减少对主线程的时间占用


对那些不会改变服务器状态,只获取数据的Ajax请求,应该使用get类型(让游览器缓存起来)






目录
相关文章
|
3天前
|
前端开发
【Web前端】CSS基本语法规范和引入方式&&常见选择器用法&&常见元素属性
【Web前端】CSS基本语法规范和引入方式&&常见选择器用法&&常见元素属性
|
6天前
|
前端开发 JavaScript 开发者
新一代前端框架:革命性的Web开发利器
传统的前端框架在满足日益复杂的Web开发需求上逐渐显露出局限性,而新一代前端框架的出现,以其革命性的设计和功能,重新定义了Web开发的标准。本文将介绍这些新一代前端框架的特点和优势,并探讨它们在实际项目中的应用。
|
10天前
|
JavaScript 前端开发 UED
【Web 前端】如何将一个 HTML 元素添加到 DOM 树中的?
【5月更文挑战第2天】【Web 前端】如何将一个 HTML 元素添加到 DOM 树中的?
|
10天前
|
JavaScript 前端开发 索引
【Web 前端】jQuery 里的 each() 是什么函数?你是如何使用它的?
【5月更文挑战第2天】【Web 前端】jQuery 里的 each() 是什么函数?你是如何使用它的?
|
10天前
|
存储 前端开发 JavaScript
【Web 前端】如何找到所有 HTML select 标签的选中项?
【5月更文挑战第2天】【Web 前端】如何找到所有 HTML select 标签的选中项?
|
10天前
|
JavaScript 前端开发 C++
【Web 前端】JavaScript window.onload 事件和 jQuery ready 函数有何不同?
【5月更文挑战第2天】【Web 前端】JavaScript window.onload 事件和 jQuery ready 函数有何不同?
|
10天前
|
前端开发 JavaScript
【Web 前端】$(document).ready() 是个什么函数?为什么要用它?
【5月更文挑战第2天】【Web 前端】$(document).ready() 是个什么函数?为什么要用它?
|
10天前
|
JavaScript 前端开发
【Web 前端】如何在点击一个按钮时使用 jQuery 隐藏一个图片?
【5月更文挑战第2天】【Web 前端】如何在点击一个按钮时使用 jQuery 隐藏一个图片?
|
11天前
|
JavaScript 前端开发
【Web 前端】 jQuery 里的 ID 选择器和 class 选择器有何不同?
【5月更文挑战第1天】【Web 前端】 jQuery 里的 ID 选择器和 class 选择器有何不同?
|
11天前
|
JavaScript 前端开发
【Web 前端】网页上有 5 个div元素,如何使用JQ来选择它们?
【5月更文挑战第1天】【Web 前端】网页上有 5 个div元素,如何使用JQ来选择它们?