Flutter中防抖动和节省策略

打印 上一主题 下一主题

主题 647|帖子 647|积分 1941

什么是防抖和节省?

   函数节省(throttle)与 函数防抖(debounce)都是为了限制函数的执行频次,以优化函数触发频率过高导致的相应速率跟不上触发频率,出现耽误,假死或卡顿的征象
是应对频繁触发事件的优化方案。
  防抖(debounce)

   防抖就是防止抖动,避免事件的重复触发。
防抖可以概括为触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。
n 秒后执行该事件,若在n秒后被重复触发,则重新计时
简朴的说,如果某一事件被连续快速地触发多次,只会执行末了那一次。
  

  • 利用场景
   · input 搜刮录入,用户不绝录入值
· window触发resize事件
· mousemove 鼠标滑动事件
· scroll滚动条滑动请求、上拉触底加载更多
· 表单验证,按钮的提交事件
  节省(throttle)

   节省就是淘汰流量,将频繁触发的事件淘汰,并每隔一段时间执行。会控制事件触发的频率。所以节省会稀释函数的执行频率。
n 秒内只运行一次,若在n秒内重复触发,只有一次收效。
如果连续快速地触发多次,在规定的时间内,只触发一次。如限制1s,则1s内只执行一次,无论怎样,都在会1s内执行相应的操纵。
  

  • 利用场景
   · 获取验证码
·鼠标不绝点击触发,mousedown(规定时间内只触发一次)
·mousemove 鼠标滑动事件
·滚动条滑动请求、上拉触底加载更多
·搜刮、提交等按钮功能
  防抖和节省之间的差别:

   相同点: 目标都是,降低回调函数的执行频率,节省计算资源
    不同点:
· 防抖,是在一段连续操纵结束之后,处理回调
· 节省,是在一段连续操纵中,每一段时间只执行一次,在频率较高的事件中利用来提高性能。
·防抖用于无法预知的用户主动举动,如用户输入内容去服务端动态搜刮结果。用户打字的速率等是无法预知的,具有非规律性。
·节省可用于一些非用户主动举动大概可预知的用户主动举动,如用户滑动商品橱窗时发送埋点请求、滑动固定的高度是已知的逻辑,具有规律性。
·防抖是关注于末了一次的事件触发,而节省则是在规定的时间里只执行一次。
·防抖是将多次执行变为末了一次执行,节省是将多次执行变成每隔一段时间执行
  

  • 防抖以一个实时搜刮框为例 当用户在输入框中举行实时搜刮时,频繁调用接口大概会导致性能问题和不必要的网络请求。为了优化这种情况,通常可以利用防抖动策略来淘汰接口调用的频率。
利用 flutter_hooks 包可以更轻易地实现防抖动功能。
   flutter_hooks: ^0.18.0
dio: ^5.0.2
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_hooks/flutter_hooks.dart';
  4. import 'package:dio/dio.dart';
  5. void main() {
  6.   runApp(MyApp());
  7. }
  8. class MyApp extends StatelessWidget {
  9.   @override
  10.   Widget build(BuildContext context) {
  11.     return MaterialApp(
  12.       home: Scaffold(
  13.         appBar: AppBar(
  14.           title: Text('Debounced Search'),
  15.         ),
  16.         body: SearchScreen(),
  17.       ),
  18.     );
  19.   }
  20. }
  21. class SearchScreen extends HookWidget {
  22.   @override
  23.   Widget build(BuildContext context) {
  24.     final searchController = useTextEditingController();
  25.     final debouncedSearch = useMemoized(() {
  26.       return _DebouncedSearch(duration: Duration(milliseconds: 500));
  27.     });
  28.     useEffect(() {
  29.       void listener() {
  30.         debouncedSearch.run(() {
  31.           // 这里调用接口
  32.           _performSearch(searchController.text);
  33.         });
  34.       }
  35.       searchController.addListener(listener);
  36.       return () => searchController.removeListener(listener);
  37.     }, [searchController]);
  38.     return Padding(
  39.       padding: const EdgeInsets.all(8.0),
  40.       child: Column(
  41.         children: [
  42.           TextField(
  43.             controller: searchController,
  44.             decoration: InputDecoration(
  45.               hintText: 'Search...',
  46.             ),
  47.           ),
  48.           Expanded(
  49.             child: ListView(
  50.               children: [
  51.                 // 搜索结果展示
  52.               ],
  53.             ),
  54.           ),
  55.         ],
  56.       ),
  57.     );
  58.   }
  59.   void _performSearch(String query) async {
  60.     if (query.isEmpty) return;
  61.     try {
  62.       // 模拟调用接口
  63.       print('Searching for $query');
  64.       // 在这里用 Dio 或其他包实际调用接口
  65.       var response = await Dio().get('https://api.example.com/search', queryParameters: {'q': query});
  66.       print(response.data);
  67.     } catch (e) {
  68.       print('Search error: $e');
  69.     }
  70.   }
  71. }
  72. class _DebouncedSearch {
  73.   final Duration duration;
  74.   Timer? _timer;
  75.   _DebouncedSearch({required this.duration});
  76.   void run(void Function() action) {
  77.     _timer?.cancel();
  78.     _timer = Timer(duration, action);
  79.   }
  80. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

火影

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表