Web前端性能优化——防抖处理/节流处理/图片懒加载

本文探讨前端优化策略,包括资源压缩、合并、缓存利用、CDN加速、DOM操作优化、懒加载和节流防抖技巧,提升页面加载与渲染速度,降低CPU负担和网络请求,减轻服务器压力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前端性能优化

没有标准答案,越全面越好,如果做不到,就尽量从前端角度考虑

原则

  • 多使用内存,缓存(以空间换时间,这种思想也适用于后台)访问频繁,变化不大
  • 减少 CPU 计算量,减少网络加载耗时

入手

1、 提升加载速度

  • 减少资源体积:压缩代码(如QQ的图片压缩等)
  • 减少访问次数:合并代码,SSR服务端渲染、缓存等
  • 使用更快的网络:CDN
  • CSS 放在 head,JS 放在 body 最下面
  • 尽早开始执行 JS,用 DOMContentLoaded 触发
  • 懒加载(图片懒加载,上滑懒加载)

2、 提升渲染速度

  • 对 DOM 查询进行缓存
  • 拼单 DOM 操作,合并到一起插入 DOM 结构
  • 节流 throttle 防抖 debounce

防抖

示例:输入框的 keyup 事件

防抖处理

下面代码使用定时器对 keyup 事件进行了防抖处理,核心原则就是

  • 当用户 1000ms 之内没有再次输入,就对文本框的内容进行处理(这里只是简单的输出)
  • 如果用户在 1000ms 之内继续输入,则清除上次的定时器,自然就不会对文本框内容进行处理了
  • 也就是说,最终只会对最后一次输入进行处理
  • 试想,如果是实时验证用户名是否可用的需求,做了防抖处理后,能够大大减轻服务器的压力,减少请求次数

代码演示:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>防抖</title>
</head>

<body>
  <input type="text" name="" id="userName">

  <script>
    const txt_userName = document.querySelector('#userName')
    txt_userName.addEventListener('keyup', debounce(() => {
      console.log(this);
      console.log(txt_userName.value);
    }))

    // 封装防抖函数
    function debounce(callback, delay = 1000) {
      let timer = null
      return function () {
        if (timer) {
          // 可取消由 setTimeout() 方法设置的 timeout
          clearTimeout(timer)
        }
        timer = setTimeout(() => {
          // 事件处理代码
          callback && callback()
          timer = null
        }, delay)
      }
    }
  </script>

</body>

</html>

节流

示例:拖拽元素

  • 拖拽元素时,要随时拿到被拖拽元素的位置
  • 直接用 drag 事件,会频繁触发,很容易导致卡顿
  • 节流:无论拖拽速度多快,都会每隔 100ms 触发一次
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>节流</title>
  <style>
    .box {
      width: 200px;
      height: 150px;
      background-color: rgb(175, 95, 250);
    }
  </style>
</head>

<body>
  <div class="box" draggable="true"></div>

  <script>
    const box = document.querySelector('.box')
    box.addEventListener('drag', throttling((e) => {
      console.log(e);
    }))
    function throttling(callback, delay=1000) {
      let timer = null
      return function() {
        if(timer) return
        timer = setTimeout(() => {
          callback && callback.apply(this,arguments)
          timer = null
        },delay)
      }
    }
  </script>
</body>

</html>

图片懒加载

css样式

  <style>
    body {
      width: 100%;
      height: 100%;
    }

    img {
      width: 200px;
      height: 280px;
    }
  </style>

html代码

<body>
  <div>
    <div>
      <h2>白敬亭也太帅了吧</h2>
      <p>今天又是被小白帅炸的一天哦!!!啦啦啦啦啦~~~~~</p>
      <img src="" alt="" data-src="https://www.77wenyu.com/uploads/img1/20200712/8cf365eed29433fdf0a28882491da083.jpg">
    </div>
    <div>
      <h2>白敬亭也太帅了吧</h2>
      <p>今天又是被小白帅炸的一天哦!!!啦啦啦啦啦~~~~~</p>
      <img src=""
        data-src="https://star-img.idol001.com/atlas/7177/images/2018/2/6/C58r63d4j41517896392282.jpg/default-w720"
        alt="">
    </div>
    <div>
      <h2>白敬亭也太帅了吧</h2>
      <p>今天又是被小白帅炸的一天哦!!!啦啦啦啦啦~~~~~</p>
      <img src="" alt=""
        data-src="https://uploadfile.bizhizu.cn/up/92/d4/87/92d487a2c3f10ad62061bfccbbeacff7.jpg.source.jpg">
    </div>
    <div>
      <h2>白敬亭也太帅了吧</h2>
      <p>今天又是被小白帅炸的一天哦!!!啦啦啦啦啦~~~~~</p>
      <img src="" data-src="https://c-ssl.duitang.com/uploads/item/201803/14/20180314090645_gprdv.jpg" alt="">
    </div>
  </div>
</body>

js代码

<script>
  var imgArr = document.querySelectorAll('img');
  var n = 0; //存储图片加载到的位置,避免每次都从第一张图片开始遍历

  // 图片懒加载
  function lazyLoad() {
    // 可视区域高度
    const seeHeight = window.innerHeight
    for (var i = n; i < imgArr.length; i++) {
      if (imgArr[i].offsetTop < seeHeight + window.pageYOffset) {
        if (imgArr[i].getAttribute('src') == '') {
          imgArr[i].src = imgArr[i].getAttribute('data-src')
        }
        n = i + 1
      }
    }
  }
  lazyLoad()

  // 滚屏函数
  window.onscroll = throttling(lazyLoad)

  // 节流函数
  function throttling(callback, delay = 1000) {
    let timer = null
    return function () {
      if (timer) return
      timer = setTimeout(() => {
        callback()
        timer = null
      }, delay)
    }
  }
</script>

效果如下:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值