Flutter 性能优化之渲染耗时问题修复

127 阅读1分钟

Flutter 性能优化之渲染耗时问题修复

记录下页面渲染耗时的排错,首先我们使用Flutter Devtools中的Performance 查看一下时间轴(首先要勾选Enhance Tracing 中的这些选项),

image.png

我们看到MyOrderDomainItem的Container下有一大段空白耗时,实际上的耗时应该是比里面的Container稍微大一些,我们看到MyOrderDomainItem的耗时是15ms,Container的耗时是7ms,差了差不多8ms的空白,这是怎么回事呢?

image.png

image.png

我先看了看代码, 好像没有问题,我把Container 中的内容都删除,换成无内容的Container 也还存在这个问题。这是什么情况呢,百思不得其解。

final class MyOrderDomainItem extends StatelessWidget {
  final MyYdData item;
  final bool isExpand;
  final void Function(MyYdData data)? onSelectChange;

  const MyOrderDomainItem({
    super.key,
    required this.item,
    this.onSelectChange,
    required this.isExpand,
  });

  @override
  Widget build(BuildContext context) {
    LOG("item isExpand = $isExpand");
    return Container(
      width: double.infinity,
      color: Colors.white,
      child: Column(
        children: [
          Row(
            children: [
              SizedBox(
                height: 50,
                width: 50,
                child: Padding(
                  padding: const EdgeInsets.only(left: 15, top: 5, bottom: 5, right: 5),
                  child: JMImage(
                    item.isSelect ? R.image.iconSelectOnCircleFill : R.image.iconSelectOffCircle,
                    size: 16,
                    margin: const EdgeInsets.only(right: 10),
                  ),
                ),
              ).onTap(() {
                onSelectChange?.call(item);
              }),
              Expanded(
                child: Row(
                  children: [
                    Expanded(child: Text(
                      item.ym ?? '',
                      style: R.style.titleM(14),
                    ),),
                    Expanded(child: Text(
                      item.zttxt ?? "",
                      style: R.style.content(14),
                    ),),
                    Expanded(child: Text(
                      item.scsj ?? "",
                      style: R.style.content(14),
                    ),),
                  ],
                ),
              ),
            ],
          ),
          Container(
            color: R.color.under,
            height: 1,
          ),
          Visibility(visible: isExpand,child: Column(children: [
            Padding(
              padding: const EdgeInsets.only(top: 10, bottom: 10),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const SizedBox(
                    height: 50,
                    width: 50,
                  ),
                  Expanded(
                      child: Row(
                        children: [
                          Expanded(child: Column(
                            mainAxisAlignment: MainAxisAlignment.start,
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text(
                                "抢注价格:¥${item.qian}",
                                style: R.style.content(12),
                              ),
                              Text("已冻结:¥${item.qian1}", style: R.style.content(12))
                            ],
                          ),),
                          Expanded(child: Column(
                            mainAxisAlignment: MainAxisAlignment.start,
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text("删除类型:${item.sclx}", style: R.style.content(12)),
                              RichText(
                                text: TextSpan(
                                  text: '预定时间:',
                                  style: R.style.content(12),
                                  children: [
                                    TextSpan(text: "${item.sj}", style: R.style.content(10))
                                  ],
                                ),
                              ),
                              // Text("预定时间:${item.sj}", style: R.style.content(12))
                            ],
                          ),),
                        ],
                      )),
                ],
              ),
            ),
            Container(
              color: R.color.under,
              height: 10,
            ),
          ],),),
        ],
      ),
    ).onTap((){
      if (item.zt == "3") {
        toNamed("${RouteNames.domainBidding.detail}?data=${item.ym}");
      }
    });
  }
}

于是乎,我顺着时间轴往下翻,我看到了platform channel的通信,我似乎理解了为什么出现这个耗时问题了。

image.png

image.png

因为我的这个LOG 工具是和原生通信的,这是个耗时的动作。

image.png

因此注释掉这段打印的代码,运行看看结果

image.png

image.png

此时将MyOrderDomainItem优化到和Container耗时相接近的地方,至此修复了一个耗时问题。

实际上这个问题可能在release环境中不会触发,因为LOG日志工具在线上环境是不会打开的。

image.png

虽然这个问题线上不会触发,但是这也是一份经验,告诉我们不要在build 中进行耗时动作,会导致页面卡顿。