常见性能优化

  • 前言
  • 一、图片优化
    • 1.雪碧图(图片精灵)
    • 2.图片压缩
    • 3.字体图标代替图片
    • 4.webp图片
  • 二、DOM优化
    • 1.缓存DOM节点查找的结果
    • 2.防抖和节流
    • 3.事件代理
    • 4.减少合并DOM操作
    • 5.DOM读写分离
    • 6.DOM元素离线更新
  • 三、性能更好的API(脚本优化)
    • 1.用requestAnimationFrame代替setTimeout
    • 2.使用IntersectionObserver来实现图片可视区域的懒加载
  • 四、加载优化
    • 1.使用CDN
    • 2.按需加载
    • 3.DNS预先解析
    • 4.浏览器缓存
    • 5.文件压缩、混淆、合并
  • 五、前端缓存
    • 1.cookie
    • 2.localStorage
  • 总结

前言

  想要成为一名合格的前端开发工程师,必须要掌握前端性能优化,本文将为大家介绍一些常见的前端性能优化问题,如有遗漏,欢迎补充~

一、图片优化

1.雪碧图(图片精灵)

  图像精灵是放入一张单独的图片中的一系列图像。包含大量图像的网页需要更长时间来下载,同时会生成多个服务器请求。使用图像精灵将减少服务器请求数量并节约带宽。
  具体操作可以去W3C里面查看教程:https://www.w3school.com.cn/css/css_image_sprites.asp

2.图片压缩

  要无损压缩!!!

  • 优先使用png而不是GIF
  • 压缩png / gif动画 / 动态生成的图像
  • 使用 CSS sprites / png8
  • 避免使用AlphaImageLoader(用来解决IE6不支持png图片透明度的问题)
  • 去除JPEG的metadata

3.字体图标代替图片

  • SVG
      SVGScalable Vector Graphics)是一种图像文件格式,意思为可缩放的矢量图形,是一种用XML定义的语言,用来描述二维矢量及矢量/栅格图形。优势在于:可以任意放大图形显示,但绝不会以牺牲图像质量为代价,平均来讲,SVG文件比JPEGPNG格式的文件要小很多,因此渲染速度也很快。
  • iconfont
      iconfont是阿里妈妈MUX倾力打造的矢量图标管理、交流平台,设计师将图标上传到Iconfont平台,用户可以自定义下载多种格式(支持AI/ SVG/ PNG / 代码格式)的icon,平台也可将图标转换为字体,便于前端工程师自由调整与调用。

4.webp图片

  WebP(发音:weppy)是一种同时提供了有损压缩与无损压缩(可逆压缩)的图片文件格式,派生自影像编码格式VP8。根据Google较早的测试,WebP的无损压缩比网络上找到的PNG档少了45%的文件大小,即使这些PNG档在使用pngcrushPNGOUT处理过,WebP还是可以 减少28% 的文件大小。

二、DOM优化

1.缓存DOM节点查找的结果

  在同一个节点无需多次查询的情况下,可以缓存DOM。

var div = document.getElementById('div');

2.防抖和节流

  • 防抖
      所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
//以鼠标滚轮事件为例
function debounce(fn,delay){  //fn为真正执行的函数,delay为间隔时间var timerId = null;return function(){var arg = arguments[0];  //访问调用方法的第1个参数if(timerId){clearTimeout(timerId); //清除定时器}timerId = setTimeout(function(){  //设置定时器fn(arg);},delay)}
}function move(ev){  //测试上述代码if(ev.wheelDeltaY > 0){console.log('向上');}else{console.log('向下');}
}
document.onwheel = debounce(move,2000);  //每隔两秒执行一次
  • 节流
      所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率,单位时间内, 只会触发一次事件,如果事件触发后,又重复触发了同一事件,则忽略后面触发的事件,直到第一次事件的计时结束。
//以鼠标滚轮事件为例
function throttle(fn,delay){var timerId = null;return function(){var that = this;var arg = arguments[0];  //访问调用方法的第1个参数if(timerId) return;timerId = setTimeout(function(){  //设置定时器fn(arg,that);timerId = null;},delay)}
}function move(ev,obj){  //测试上述代码console.log(obj);if(ev.wheelDeltaY > 0){console.log('向上');}else{console.log('向下');}
}
document.onwheel = throttle(move,1000);

3.事件代理

  指将事件监听器注册在父级元素上,把原本需要绑定在子元素的响应事件(clickkeydown等)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。

  简单来说,比如你们宿舍的人都要取快递,一种方法是你们一个个去取各自的快递;还有一种方法是把所有要取的快递委托给某一个人,当他把所有快递取回来后,再根据收件人信息分发给每一个人。这个被委托的人就相当于父元素。

  • addEventListener( )
    1) 语法:element.addEventListener(event, function, useCapture)
    2)参数值
参数 描述
event 必须。字符串,指定事件名。注意:不要使用"on”前缀(例如使用“click”,而不是“onclick”)
function 必须。指定事件触发时要执行的函数。当事件对象会作为第一个参数传入函数。
useCapture 可选。布尔值,指定事件是否在捕获或冒泡阶段执行。

3)移出事件监听:element.removeEventListener(event, function,useCapture)

4.减少合并DOM操作

  • 在内存中操作DOM
      使用createDocumentFragment()方法创建虚拟的节点对象,让DOM操作发生在内存中,而不是页面上。
    语法:document.createDocumentFragment()
  • 批量操作DOM
      由于DOM操作可能会造成浏览器回流,所以要避免频繁操作DOM。可以使用innerHTML属性批量生成DOM节点,具体操作为字符串拼接,再用innerHTML更新DOM。
      不过如果代码比较多的情况下,手动拼接就比较麻烦。(因为编辑器里不会有提示~~)
<!-- 模拟聊天框发送信息 -->
<div id="p"></div>  <!-- 节点 -->
<input type="text" id='msg'>  <!-- 节点信息 -->
<button onclick="sendMsg()">发送</button>
var pNode = document.getElementById('p');  //获取p标签节点
var msg = document.getElementById('msg');  //获取节点的文字内容
function sendMsg(){var val = msg.value;  //存放文字内容p.innerHTML += `<p>${val}</p>`  //字符串拼接
}
  • 批量操作CSS样式
    1)切换class
<!-- 选项卡切换 -->
<style>#tab{width: 600px;height: 300px;margin: 50px auto;border: 1px solid #000;}#tab ul{display: flex;justify-content: space-between;}#tab li{height: 30px;line-height: 30px;padding: 0 10px;flex-grow: 1;background: #f1f1f1;transition: 0.3s;}#tab li.current{background: deeppink;}.tabItem{display: none;}.tabItem.current{display: block;}
</style>
<div id="tab"><ul><li class="current">电影</li><li>电视</li><li>动漫</li><li>新闻</li></ul><div class="tabCont"><div class="tabItem current">THIS IS TAB 1</div><div class="tabItem">THIS IS TAB 2</div><div class="tabItem">THIS IS TAB 3</div><div class="tabItem">THIS IS TAB 4</div></div>
</div>
//jQuery代码
$('#tab li').on('click',function(){var index=$(this).index()//返回元素的索引$(this).add($('.tabItem').eq(index)).addClass('current').siblings().removeClass('current')
})

运行效果

 2)新的类

<style>
.box{width: 300px;height: 300px;border: 1px solid #000;/*...*/
}
</style>
element.className += " box";

5.DOM读写分离

  浏览器具有惰性渲染机制,连接多次修改DOM可能只触发浏览器的一次渲染。而如果修改DOM后,立即读取DOM,为了保证读取到正确的DOM值,会触发浏览器的一次渲染。因此,修改DOM的操作要与访问DOM分开进行。

6.DOM元素离线更新

  当对DOM节点进行较大的改变时,需要先将元素脱离文档流,然后进行改变操作,最后再放回到文档流中。例如appendChild等都可以使用Document Fragment对象进行离线操作,带元素“组装”完成后再一次插入页面,或者使用 display:none 对元素隐藏,在元素“消失”后进行相关操作。

<ul id='list'></ul>
var ul = document.getElementById('list')
ul.style.display = 'none';  //脱离文档流
// 对ul进行相关操作
ul.style.display = 'block';  //放回文档流

三、性能更好的API(脚本优化)

1.用requestAnimationFrame代替setTimeout

  requestAnimationFrame是浏览器用于定时循环操作的一个接口,主要用途是按帧对网页进行重绘。而使用 setTimeout或者 setInterval 来触发更新页面的函数,该函数可能在一帧的中间或者结束的时间点上调用,进而导致该帧后面需要进行的事情没有完成,引发丢帧。
  设置这个API的目的是为了让各种网页动画效果(如DOM动画、Canvas动画、SVG动画等)能够有一个统一的刷新机制,从而节省系统资源。
  目前,主要浏览器Firefox 23 / IE 10 / Chrome / Safari都支持这个方法。可以用下面的方法,检查浏览器是否支持这个API。如果不支持,则自行模拟部署该方法。

//检查浏览器是否支持这个API
window.requestAnimFrame = (function(){return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function( callback ){window.setTimeout(callback, 1000 / 60);};
})();

2.使用IntersectionObserver来实现图片可视区域的懒加载

  传统的做法中,需要使用scroll事件,并调用getBoundingClientRect方法,来实现可视区域的判断,即使使用了函数节流,也会造成页面回流。使用IntersectionObserver,则没有上述问题。

四、加载优化

1.使用CDN

  CDNContent Delivery Network),即内容分发网络。CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术。

2.按需加载

  按需加载是前端性能优化的一大措施,顾名思义就是根据需要去加载资源。换句话说就是当用户触发某个动作的时候,才主动去请求资源,这样可以减少HTTP请求,节省宽带,让页面首屏的内容更快展现在用户的视线范围内,提高用户体检。触发的动作有很多,如鼠标点击,拉动页面滚动条,输入文字等等;加载的文件,可以是JS图片CSSHTML等。

  • 图片的按需加载
<img src="伪装的图片" data-src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png">

  把图片的真实资源地址存放在标签自定义的属性里面,如 ‘data-src’,当触发动作时,交换属性,就可以达到按需加载。

3.DNS预先解析

  域名(DNS)解析是把域名指向网站空间IP,让人们通过注册的域名可以方便地访问到网站的一种服务。域名解析就是域名到IP地址的转换过程。


图片来源:百度百科

  • 预解析的方法
    在 head 标签里面写上几个 link 标签。
<link rel="dns-prefecth" href="https://www.csdn.net">
<link rel="dns-prefecth" href="https://www.baidu.com">

4.浏览器缓存

  浏览器缓存Browser Caching)是为了节约网络的资源加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样就可以加速页面的阅览。它是网站访问统计最难解决的问题之一。

  • 彻底缓存:cache-control、exprices
      彻底缓存的意思是在缓存失效之前不再需要跟服务器交互。浏览器总是优先使用cache-control,如果没有cache-control才考虑Expires
  • 缓存协商:Last-modified 、Etag
      缓存协商的意思是需要去服务器端询问页面有没有修改过,没有修改过则返回304直接使用缓存内容,否则返回新内容。
    协商步骤
    1)服务器发送带Last-modified:GMTtime 头的http response
    2)浏览器下次请求时带上if-modified-since:GMTtime http 请求头
    3)服务端用本地Last-modified时间与if-modified-since比较,计算浏览器数据是否过期并发送响应

5.文件压缩、混淆、合并

  • 合并
    如果不进行文件合并,有如下3个隐患
    1)文件与文件之间有插入的上行请求,增加了N-1个网络延迟;
    2)受丢包问题影响更严重;
    3)经过代理服务器时可能会被断开;
    当然,文件合并不一定完美,它也有一些自己的问题
    1)首屏渲染问题
    2)缓存失效问题
    改进建议
    1)公共库合并
      将公共库单独打包成一个文件。
    2)不同页面单独合并
      按需加载(异步组件)。
  • 压缩与混淆
    1)HTML压缩
      HTML压缩就是压缩在文本文件中有意义,但是在HTML中不显示的字符(包括空格、制表符Tab、换行符等)
      使用在线网站压缩;
      html-minifier工具;
      后端模板引擎渲染时压缩;
    2)CSS压缩
      CSS压缩包括无效代码删除与CSS语义合并。
      使用在线网站压缩
      对于html中的css可以使用html-minifier压缩
      clean-css工具
    3)JS压缩与混淆
      JS压缩与混淆包括无效字符及注释的删除、代码语义的缩减和优化、降低代码可读性,实现代码保护。
      使用在线网站进行压缩
      对于html中的js可以使用html-minifier压缩
      UglifyJS2工具

五、前端缓存

1.cookie

  类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息。Cookie是一段不超过4KB的小型文本数据,由一个名称(Name)、一个值(Value)和其它几个用于控制Cookie有效期、安全性、使用范围的可选属性组成。

属性 作用
Name/Value

设置Cookie的名称及相对应的值,对于认证Cookie,Value值包括Web服务器所提供的访问令牌 。

Expires

设置Cookie的生存期。有两种存储类型的Cookie:会话性与持久性。Expires属性缺省时,为会话性Cookie,仅保存在客户端内存中,并在用户关闭浏览器时失效;持久性Cookie会保存在用户的硬盘中,直至生存期到或用户直接在网页中单击“注销”等按钮结束会话时才会失效。

Path

定义了Web站点上可以访问该Cookie的目录。

Domain

指定了可以访问该 Cookie 的 Web 站点或域。Cookie 机制并未遵循严格的同源策略,允许一个子域可以设置或获取其父域的 Cookie。因而,浏览器禁止在 Domain 属性中设置.org、.com 等通用顶级域名、以及在国家及地区顶级域下注册的二级域名,以减小攻击发生的范围。

Secure

指定是否使用HTTPS安全协议发送Cookie。使用HTTPS安全协议,可以保护Cookie在浏览器和Web服务器间的传输过程中不被窃取和篡改。

HTTPOnly

用于防止客户端脚本通过document.cookie属性访问Cookie,有助于保护Cookie不被跨站脚本攻击窃取或篡改。但是有一定局限性。

2.localStorage

  用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去除。
  在使用 web 存储前,应检查浏览器是否支持 localStorage

<div id="result"></div>
if(typeof(Storage) !== "undefined"){localStorage.sitename="CSDN";document.getElementById("result").innerHTML="网站名:" + localStorage.sitename;
}else{document.getElementById("result").innerHTML="对不起,您的浏览器不支持 web 存储。";
}

网站名:CSDN

  • 常用API
    1)保存数据
      localStorage.setItem(key,value);
    2)读取数据
      localStorage.getItem(key);
    3)删除单个数据
      localStorage.removeItem(key);
    4)删除所有数据
      localStorage.clear();
    5)得到某个索引的key
      localStorage.key(index);

总结

  前端性能优化的手段有很多,本文并没有罗列完整。
  另:部分内容参考——https://www.cnblogs.com/xiaohuochai/p/9178390.html

【前端性能】常见前端性能优化相关推荐

  1. 【前端性能】网站性能优化

    网站性能优化 1.尽量减少HTTP请求次数 终端用户响应的时间中,有80%用于下载各项内容,这部分时间包括下载页面中的图像.样式表.脚本.Flash等.通过减少页面中的元素可以减少HTTP请求的次数, ...

  2. 前端框架/架构,性能优化,负载均衡,首屏渲染

    前端数据结构与算法- https://zhuanlan.zhihu.com/p/27659059 > 前端重构方案 前端重构方案了解一下- https://blog.csdn.net/vM199 ...

  3. 前端不哭!最新优化性能经验分享来啦 | 技术头条

    作者 | Dimitris Kiriakakis 译者 | 风车云马 编辑 | Jane 出品 | Python大本营(id:pythonnews) [导语]Angular.React.VueJS 是 ...

  4. 都说百度前端牛,来看看百度前端工程化之H5性能优化

    导读:从粗糙到精致,从简单到复杂,全球互联网Web App(网页应用)平均体积已增压到1.6Mb,随着音视频等富媒体内容的流量池膨胀,终端设备上的用户对网页装载速度尤其敏感.页面不能做到秒开,就会有大 ...

  5. 前端感官性能的衡量和优化实践

    本文已发表在2017年8月<程序员>杂志. 我们为什么需要关注站点的性能,性能为什么如此重要呢?如今任何互联网产品首先重要的都是流量,流量最终会转换为商业价值.所以在互联网产品中,流量.转 ...

  6. 前端如何进行网站性能优化

    大家好,我是IT修真院学员,一枚正直纯洁善良的WEB程序员,今天给大家分享一下,修真院官网JS任务4,深度思考中的知识点-前端如何进行网站性能优化. 一.背景介绍 性能优化的目的 1.从用户角度而言, ...

  7. 前端如何进行网站性能分析及优化性能

    目录 1.分析网站性能常用的方式 1.1 chrome dev Tools 1.2  Lighthouse 1.3 第三方收费方案 2.介绍一个常用的性能分析工具 LightHouse 2.1 特点: ...

  8. 小程序前端性能测试_如何提高前端应用程序的性能

    小程序前端性能测试 If your website takes longer than 3 seconds to load, you could already be losing nearly ha ...

  9. 【面试】前端面试之开发性能篇

    文章目录 如何优化前端的性能? 什么叫优雅降级和渐进增强? 如何规避JavaScript多人开发函数重名的问题? 请说出三种减低页面加载时间的方法? 你所了解到的Web攻击技术? 前端开发中,如何优化 ...

  10. 前端逐帧动画性能探究和比较

    什么是逐帧动画? 首先看一下维基百科中的定义: 定格动画,又名逐帧动画,是一种动画技术,其原理即将每帧不同的图像连续播放,从而产生动画效果. 简单的来说就是: 以一定的速度切换几张连续图像,让它动起来 ...

最新文章

  1. SPFA-DFS P3385 模板 判断负环===vector为啥过不了?
  2. js实现审批流_JavaScript实现审核流程状态的动态显示进度条
  3. 怎样在VirtualBox 虚拟机中挂载共享目录
  4. 深入探讨!Batch 大小对训练的影响
  5. zookeeper集群搭建配置zoo.cnf
  6. 正则表达式(grep命令,egrep命令,sed命令,awk命令,sort工具,uniq工具)
  7. mysql 存储过程 查询结果 循环_在存储过程中从查询结果集中怎么循环
  8. LeetCode:Combinations
  9. linux提升nvme性能,基于SPDK的NVMe SSD性能评估指南
  10. 深度学习1-深度学习框架介绍
  11. java中实现下载音乐_如何用JAVA的IO流下载落网音乐?
  12. 视频教程-IT必备技能Cisco认证CCNA全集-思科认证
  13. phpcms整站代码分析
  14. 混响延迟插件9个合集 – ValhallaDSP Bundle 2020 WiN 免安装版
  15. ios模拟器安装app
  16. CardView 整理
  17. C#事件中sender的小用法(转载)
  18. 启动jupyter notebook 报错:ImportError:DLL load failed,找不到指定模块的解决办法
  19. AUTOCAD——文件管理
  20. java中 continue outer, break inner 简解

热门文章

  1. javascript教程完整版,JavaScript视频教程
  2. Hexo+Buttterly+Github Pages构建个人博客
  3. 【记录】嵌入式经典通信UART理解
  4. 一次完整的PWM电磁摆设计实验---含手工制板全攻略
  5. jQuery与JS实现AJAX实例!(附AJAX教程、路线图)
  6. 基于HTML的环境网站设计 HTML+CSS环保网站项目实现 带设计说明psd
  7. Centos7系或中标麒麟ifconfig/ip addr无法显示ip地址的详细解决方法
  8. Python DistributedDataParallel(DDP)训练模型
  9. Android控件 SeekBar
  10. 【Windows】U 盘装系统,无法格式化所选磁盘分区[错误: 0x8004242d]