性能优化

2022/9/11

# 图片优化

使用svg、webP、base64编码、雪碧图

# 加载优化

  • 图片懒加载

HTML 代码

<body>
  <img src="empty.jpg" data-src="city.png" alt="city" class="lazy">
  <img src="empty.jpg" data-src="moon.png" alt="moon" class="lazy">
  <img src="empty.jpg" data-src="room.png" alt="room" class="lazy">
  <img src="empty.jpg" data-src="two.png" alt="two" class="lazy">

</body>

JS 代码

document.addEventListener("DOMContentLoaded", function(){
    // 获取需要懒加载的图片列表
    let lazyImges = [].concat(...document.querySelectorAll('.lazy'))
    console.log(lazyImges)

    let sign = false

    const lazyload = function(){
      if(sign == false){
        sign = true
        setTimeout(() => {
          lazyImges.forEach(img => {
            // 获取图片的相对位置和视图大小进行对比,判断图片是否出现在视图中
            if(img.getBoundingClientRect().top <= window.innerHeight && img.getBoundingClientRect().bottom >=0 && img.style.display !== 'none'){
              img.src = img.dataset.src
              img.classList.remove('lazy')
              lazyImges.filter(v => v !== img)

              // 如果没有需要懒加载的图片了,移除监听
              if(lazyImges.length === 0){
                document.removeEventListener('scroll', lazyload)
                window.removeEventListener('resize', lazyload)
                window.removeEventListener('orientationchange', lazyload)

              }
            }
          })
          sign = false
        }, 200);
      }
    }
    lazyload()

    document.addEventListener('scroll', lazyload)  // 监听滚动
    window.addEventListener('resize', lazyload)  // 监听缩放
    window.addEventListener('orientationchange', lazyload)  // 监听方向翻转

  })

# 书写高性能代码

# 构建优化

使用 webpack 等打包工具,对文件进行混淆压缩

# 渲染优化

  1. js 执行优化
  • 恰当使用 web worker
  • 节流
    固定时间端内只会执行一次,常用场景:搜索框联想、滚动加载等
  function throttle(fn, delay){
    let flag = true
    return (...args) => {
      if(flag){
        flag = false
        setTimeout(() => {
          flag = true
          // console.log(new Date())
          fn.apply(this, args)
        }, delay);
      }
    }
  }
  • 防抖
    连续触发只会执行一次,常用场景:窗口缩放(resize)、登录等按钮避免用户重复触发、输入验证(输入完成后再进行检查,避免keyup等事件重复触发)等

延时防抖,第一次执行也会延迟

 function debounce(fn, delay){
    let setId = undefined
    let that = this
    return function(...args){
      if(setId !== undefined) clearTimeout(setId)
      setId = setTimeout(() => {
        fn.apply(that, args)
        setId = undefined
      }, delay);
    }
  }

立即防抖

function QuickDebounce(fn, delay){
    setId = undefined
    return (...agrs) => {
      if(setId !== undefined) clearTimeout(setId)
      let now = !setId
      setId = setTimeout(() => {
        setId = undefined
      }, delay);
      if(now) fn.apply(this, agrs)
    }
  }
  1. 计算样式优化
  • 减少要计算的元素数量
    css 引擎查找样式表时,对每条规则的匹配顺序时从右向左
  • 降低选择器的复杂性
  1. 减少页面重排和重绘
  • 避免对样式的频繁改动
    一条条修改 dom 元素的样式会多次对渲染树的修改,应改为 element.classList.add() 添加类名的方式更改样式
    offsetTopscrollLeft等属性值赋值、取值时会触发页面的重新计算,使用时应先将值缓存起来,再将最后的结果统一赋值

# 服务器端优化

# 数据存储

# 缓存技术

选择合适的缓存方式