首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Flutter 性能优化之Isolates

原文(英文):https://medium.com/flutterdevs/flutter-performance-optimization-17c99bb31553

曾经想知道flutter如何在单个线程上处理所有UI构建和事件,例如Future,taps等。(是的,它在单个线程上完成所有操作???直到明确完成)。

什么是Thread/Isolates?

线程是一个独立的处理过程,具有自己的内存块并在该内存上执行给定的指令。它可以与其他线程并行工作,因此可以减少单个CPU上多个进程的执行时间。

让我们通过一个例子来理解这一点:

在Fps游戏中,例如反恐精英,使命召唤等,您可以看到,一旦发射武器,便同时执行了几项任务,例如播放子弹声,改变子弹数和减少对手的生命值,这些并行执行并在单独的隔离上(Thread/Isolates可以互换使用),它具有自己的内存。

诸如JAVA和C ++线程共享它们的内存。flutter每个Isolates都有自己的内存,是相互独立的。由于该内存具有自己的私有空间,因此不需要锁定,用完了就可以垃圾回收。

为了保持这些好处,flutter每个Isolates(Flutter的多线程)都有一个单独的内存,这就是为什么它们被称为isolate?。

在下面了解有关Isolates的更多信息。

它对我有什么帮助?在哪里应该使用Isolates/threads?

1 网络请求,要处理大约一百万条记录,仅此一项就会挂起您的UI。

2 图像处理任务,需要大量的计算,数字运算操作,这可能会导致UI卡死。

因此,Isolates可以从主线程中卸载出来大量计算。

如何使用Isolates/threads

Flutter团队设计了一种在flutter中使用Isolates/threads方法。使用compute,我们可以执行与isolates相同的任务

句法:

var getData = await compute(function,parameter);

compute两个参数:

1 future或function,但必须是静态的(如dart线程不共享内存,因此它们是类成员,而不是对象成员)。

2 要传递给function的参数,要发送多个参数,可以将其作为Map传递(因为它仅支持单个参数)。

计算函数返回一个Future,如果需要,可以将其存储到变量中并将其提供给future构建器。

让我们开始分析一个案例:

代码语言:javascript
复制

import 'dart:io';
?
import 'package:flutter/material.dart';
?
class With10SecondDelay extends StatelessWidget {
  runningFunction() {
    int sum = 0;
    for (int i = 1; i <= 10; i++) {
      sleep(Duration(seconds: 1));
      print(i);
      sum += i;
    }
    return "total sum is $sum";
  }
?
  pauseFunction() {
    //pause function is not async
    print(runningFunction());
  }
?
  @override
  Widget build(BuildContext context) {
    pauseFunction();
    return Material(
      child: Center(
        child: Center(
          child: Text(
            "Tnx for waiting 10 seconds : check console for response",
            style: TextStyle(
              fontSize: 50,
            ),
          ),
        ),
      ),
    );
  }
}

在上面的代码中,在build方法正下方调用了pausefunction(),该方法将代码的执行暂停10秒钟。因此,当您尝试从上一个页面导航到该页面时,将有十秒钟的延迟,然后我们的页面被推到小部件树上。

我们可以尝试使用异步解决此问题。

代码语言:javascript
复制
  pauseFunction() async {    //pause function is async    print(runningFunction());  }

如您现在所见,我们已经将暂停功能声明为异步,即使这样做也无济于事

由于dart中的async基本上使我们的代码处于理想状态,直到可以进行计算为止,因此在我们看来dart在不同的线程上执行这些操作,但实际上它只是在等待该async函数中发生的事件。

以下是有关异步的更多信息: https://youtu.be/SmTCmDMi4BY :)

让我们使用compute解决上述问题。

代码语言:javascript
复制

?
import 'dart:io';
?
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
?
class ComputeWith10SecondDelay extends StatelessWidget {
  static Future<String> runningFunction(String str) async {
    int sum = 0;
    for (int i = 1; i <= 10; i++) {
      await Future.delayed(Duration(seconds: 1));
      print(i);
      sum += i;
    }
    return "Sum is : " + sum.toString() + str;
  }
?
  pauseFunction() async {
    print(await compute(runningFunction,
        " This is an argument")); //storing data of copute result
  }
?
  @override
  Widget build(BuildContext context) {
    pauseFunction();
?
    return Material(
      child: Center(
        child: Center(
          child: Text(
            "Wow , it saved my 10 seconds : check console for response",
            style: TextStyle(
              fontSize: 50,
            ),
          ),
        ),
      ),
    );
  }
}

在上面的代码中,我们基本上将函数传递给了compute()函数,并创建了一个单独的隔离来处理任务,我们的主UI仍将无任何延迟地运行(请检查调试控制台以获取响应)。

摘要:

1 默认情况下,Dart是在单线程上执行其所有代码。

2 每个函数和每个async-await调用仅在主线程上起作用(除非指定)。

3 我们可以使用compute(Future function / normal function,arguments)创建多个线程。

4 您可以使用计算来执行网络呼叫,执行数字运算,图像处理等。

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/661f0c463b2cff4128bbb41bb
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券
http://www.vxiaotou.com