🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## 前端性能优化 ### `css` 样式优化 * 当一个属性只有一个值需要修改时,尽量只设置这一个属性值 例如: ~~~ // 不推荐使用 background: '#fff' // 推荐使用 background-color: '#fff' ~~~ * 在设置多个样式时,尽量避免设置行内样式;使用更改 `className` 的方式替换 `style.xxx = xxx` > why: 每次修改元素的style属性都会触发回流操作,使用className更改可多次创建,一次更改 ~~~ // 例如: 在服务的状态发生改变时,我们需要更改相应标签的样式 watch: {  status(newVal) {    switch(newVal) {      case '运行':        this.serviceClass = 'run';        break;      ......   } } } ~~~ ### `DOM` 优化 * 尽量减少 `DOM` 元素数量 ~~~ // 查看当前页面dom元素数量 console.log('number of elements', document.getElementsByTagName( '*' ).length) // 正常页面的 `dom` 元素数量一般不应该超过1000个 ~~~ * 优化 `DOM` 交互 对于只会渲染一次的数值,在 `vue` 中应尽量使用 `v-once` 指令 ~~~ <p v-once>这个将不会改变: {{ msg }}</p> ~~~ * 区分 `v-show` 与 `v-if` 的使用 > 在隐藏元素时,前者只会设置样式 `display: none` ,后者会移除元素 ### `HTML` 优化 * 避免空的 `src` 和 `href` > 为空时,浏览器渲染时会把当前页面的url作为它们的属性值,从而把页面的内容加载进来作为它们的值 * 合理架构,使DOM结构尽量简单 * 利用 `LocalStorage` 合理缓存资源 ### 内存优化 JavaScript存在内存回收机制,可将一些不再使用的变量,方法销毁,释放其占用的内存。在某些情况下,无法被回收(函数执行完毕后,在函数内部所声明的对象不一定会被销毁) * 变量优化 * 尽量选用局部变量而不是全局变量(回收机制很难判断何时回收全局变量;局部变量访问速度更快) * 善用回调 除了使用闭包访问内部变量,我们还可使用回调函数处理 优点:回调函数本身通常为临时的匿名函数,被请求执行后,回调函数自身的引用会被解除,同时得到回收。 ~~~ const getData = callback => {  const data = "some big data";  callback(data); } getData(data => {  console.log("data:", data); }) ~~~ * 对象优化 * 减少不必要的对象创建 复杂的 `javaScript` 对象,其创建时时间和空间的开销都很大,应该尽量考虑创建后进行存储。 ### 类型转换 * 将数字转为为字符串 从性能上讲,`"" + 1` 效率最高,`"" + 1` > `String()` > `.toString()` > `new String()` ~~~ // String() 属于内部函数,所以速度很快 // .toString() 需要查询原型中的函数,所以速度略慢 ~~~ * 浮点数转换为整数 错误使用 `parseInt()` ~~~ ` parseInt 是将字符串转换为数字,而不是浮点数转为整型的方法 ` ~~~ 应该使用 `Math.floor()` 或者 `Math.round()` ~~~ // Math.floor() 返回小于等于参数的最大整数 Math.floor(5.5) // 5 Math.floor(-1.5) // -2 // Math.round() 四舍五入返回整数 Math.round(5.5) // 6 Math.round(-1.5) // -1 Math.round(-1.6) // -2 ~~~ ### 逻辑判断优化 * `switch` 语句 在 `if-else` 语句中,当 `else-if` 有至少两个时,转换为 `switch` 语句 > tips: 在case中未写break时会继续向下执行代码, 这在需要判断的选项的值一致时起作用。 ~~~ let result = '' const now = new Date() const day = now.getDay() switch(day) {  case 0:  case 6:    result = '休息日'   break  case 1: result = '周一'    break  // ...  default: break } ~~~ ### 数组优化 * 初始化数组直接使用 `const arr = [];` ,不要使用 `const arr = new Array();` * 在遍历数组时,可先保存数组长度到局部变量,避免多次查询数组长度 ~~~ const length = arr.length; for (let i = 0; i < length; i++) {} ~~~ ### 动画优化 * 设置动画元素 `display` 为 `absolute` 或 `fixed` 这样做只会触发 `repaint` , 通常情况下会造成频繁的 `reflow` ### 缓存过期设置 * 在使用localStorage、session等缓存技术时,可设置他们的过期时间,以定期清理一些数据。 例如: ~~~ // 以localstorage为例 class LocalStorage {  constructor() {    this.source = window.localStorage;    this.init(); }  init() {    const reg = /__time/;    const data = this.source;    const list = Object.keys(data);    const time = new Date().getTime();    if(list.length > 0){      list.forEach(item => {        if (reg.test(item)) {          if (data[item] < time) {            const k = item.replace(reg, "")            this.remove(k);            this.remove(item);         }       }     })   }; }  save(k, v, needTime = false, endTime = 3 * 1000) {    localStorage.setItem(k, v);    if (needTime) {      const time = new Date().getTime() + endTime;      localStorage.setItem(`${k}__time`, time);   } }  remove(k) {    localStorage.removeItem(k); } } ~~~ ## 小结 前端涉及到的性能优化问题,大多是由编码习惯导致的,多注意一些细节上的代码编写,可大幅度的优化性能上的问题。多看一些 “大佬” 的代码,会提高自己代码的编写质量。同时,代码走查也是个不错的方式,自检或协助检查亦可以提高代码编写质量,去除一些不好的书写习惯。