Flutter缓存优化插件memoize的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter缓存优化插件memoize的使用

memoize 是一个用于缓存函数调用结果的Flutter插件。当输入参数没有改变时,它会返回之前缓存的结果,从而避免重复计算。这对于性能优化非常有用,尤其是在需要频繁调用相同函数且参数不变的情况下。

注意事项

  • memoize_dart 从版本 3.0.0 开始支持 Dart 2.12.0 和 null safety。
  • 版本 2.0.0 及以上不再依赖 func,因为 func 已被归档且不支持 Dart 2。
  • 如果你需要使用 dart-1.24.3,请使用 1.4.0 版本。

示例代码

使用 memo1, memo2, … memo10

这些函数通过 == 操作符比较参数:

import 'dart:math';
import 'package:memoize/memoize.dart';

void main() {
  var rect1 = Rectangle<int>(0, 0, 10, 10);
  var rect2 = Rectangle<int>(0, 0, 10, 10);

  var func = memo1((Rectangle<int> a) => a.width * a.height);

  print(func(rect1)); // 计算并缓存结果
  print(func(rect2)); // 返回缓存的结果
}

使用 imemo1, imemo2, … imemo10

这些函数通过 identical 函数比较参数:

import 'dart:math';
import 'package:memoize/memoize.dart';

void main() {
  var rect1 = Rectangle<int>(0, 0, 10, 10);
  var rect2 = Rectangle<int>(0, 0, 10, 10);

  var func = imemo1((Rectangle<int> a) => a.width * a.height);

  print(func(rect1)); // 计算并缓存结果
  print(func(rect1)); // 返回缓存的结果(同一对象实例)
  print(func(rect2)); // 不使用缓存(不同对象实例)
}

使用 memo0

memo0 在首次调用时缓存结果,并可以作为懒加载缓存使用:

import 'dart:math';
import 'package:memoize/memoize.dart';

void main() {
  var func = memo0(() => Rectangle<int>(0, 0, 10, 10));

  print(func()); // 计算并缓存结果
  print(func()); // 返回缓存的结果(同一对象实例)
}

完整示例Demo

下面是一个完整的Flutter应用示例,展示了如何在Flutter项目中使用 memoize 插件。

pubspec.yaml

首先,在 pubspec.yaml 文件中添加 memoize 依赖:

dependencies:
  flutter:
    sdk: flutter
  memoize: ^3.0.0

main.dart

接下来是完整的 main.dart 文件:

import 'package:flutter/material.dart';
import 'package:memoize/memoize.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Memoize Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Memoize Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  final func = memo1((int value) => value * value);

  void _incrementCounter() {
    setState(() {
      _counter++;
      print('Square of $_counter: ${func(_counter)}');
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的计数器应用。每次点击按钮时,计数器递增,并使用 memoize 插件缓存计算结果。这样可以确保相同的输入不会导致重复计算,从而提高性能。

总结

memoize 插件通过缓存函数调用结果来优化性能,特别适用于那些输入参数不变或变化较少的情况。通过合理使用 memoize,你可以显著提升应用程序的响应速度和用户体验。


更多关于Flutter缓存优化插件memoize的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter缓存优化插件memoize的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用memoize插件来进行缓存优化的代码示例。memoize插件通常用于缓存函数调用的结果,以提高性能,尤其是在处理耗时操作或频繁调用相同函数时。

首先,确保你已经在你的pubspec.yaml文件中添加了memoize依赖:

dependencies:
  flutter:
    sdk: flutter
  memoize: ^x.y.z  # 请替换为最新版本号

然后,运行flutter pub get来安装依赖。

以下是一个完整的示例,展示如何使用memoize插件来缓存一个耗时的网络请求结果:

import 'package:flutter/material.dart';
import 'package:memoize/memoize.dart';
import 'dart:async';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Memoize Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MemoizeExample(),
    );
  }
}

class MemoizeExample extends StatefulWidget {
  @override
  _MemoizeExampleState createState() => _MemoizeExampleState();
}

class _MemoizeExampleState extends State<MemoizeExample> {
  // 创建一个Memoizer实例,用于缓存函数结果
  final memoizer = Memoizer<String>();

  // 模拟一个耗时的网络请求函数
  Future<String> fetchData(String url) async {
    await Future.delayed(Duration(seconds: 2)); // 模拟网络延迟
    return "Data from $url";
  }

  // 使用Memoizer包装的函数
  Future<String> cachedFetchData(String url) async {
    return await memoizer.memoize(url, () async => await fetchData(url));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Memoize Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () async {
                String result = await cachedFetchData('https://example.com');
                // 显示结果
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text(result)),
                );
              },
              child: Text('Fetch Data'),
            ),
            ElevatedButton(
              onPressed: () {
                // 清除缓存
                memoizer.clearCache();
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Cache Cleared')),
                );
              },
              child: Text('Clear Cache'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中:

  1. 我们创建了一个Memoizer实例来管理缓存。
  2. fetchData函数模拟了一个耗时的网络请求,通过Future.delayed模拟网络延迟。
  3. cachedFetchData函数使用memoizer.memoize来缓存fetchData的结果。memoizer.memoize接受一个键(在这个例子中是URL)和一个返回Future的函数(即fetchData)。如果缓存中已经有了该键的结果,它将直接返回缓存的结果,而不是再次调用fetchData
  4. 在UI中,我们有两个按钮:一个用于获取数据,另一个用于清除缓存。

这样,当你多次点击“Fetch Data”按钮时,你会看到第一次请求有2秒的延迟,但随后的请求会立即返回结果,因为结果已经被缓存了。点击“Clear Cache”按钮将清除缓存,再次点击“Fetch Data”将重新触发网络请求。

回到顶部