首页/新闻资讯/正文详情

Flet 大列表渲染性能优化:ListView、GridView 与批量更新实战

发布时间:2026/9/23 18:48:14 来源:云帆数科 栏目:资讯中心
Flet 大列表渲染性能优化:ListView、GridView 与批量更新实战
Flet 大列表渲染性能优化ListView、GridView 与批量更新实战【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址: https://gitcode.com/gh_mirrors/fl/flet导读在 Flet 中展示包含数百甚至数千个条目的列表时直接使用Column或Row会导致界面卡顿、滚动迟滞。本指南讲解 Flet 针对此类场景的核心方案使用按需渲染的ListView与GridView控件配合item_extent、runs_count、max_extent等性能参数以及通过分批调用page.update()控制 WebSocket 消息体积的批量更新策略。读完本文你将掌握在大数据量列表场景下写出流畅、响应迅速的 Flet 应用的完整实战方法。问题为什么 5000 条记录会让 Column/Row 卡顿在大多数情况下用Column和Row控件展示列表就足够了。但当列表包含数百甚至数千个条目时Column和Row会变得低效、界面明显迟滞——因为它们会一次性渲染全部子控件即使这些控件并不在当前滚动位置可见。下面这个示例向页面添加了 5,000 个文本控件而页面默认使用Column作为布局容器import flet as ft def main(page: ft.Page): for i in range(5000): page.controls.append(ft.Text(fLine {i})) page.scroll always page.update() ft.run(main, viewft.AppView.WEB_BROWSER)运行这段程序后你会发现不仅首次加载并渲染所有文本行需要花上几秒钟滚动时同样又慢又卡。原因在于5,000 个Text控件全部被实例化并参与布局即使其中绝大多数不可见每次滚动都会触发大量控件的重建与绘制超出 GPU 与 UI 线程的处理能力。解决办法展示大量条目的列表时改用ListView和GridView控件——它们只在当前滚动位置可见的范围内按需渲染条目。ListView按需渲染的线性列表ListView既可以是纵向默认也可以是横向horizontalTrue的条目沿滚动方向一个接一个排列。ListView本身已经实现了高效的按需渲染但滚动性能还可以进一步提升如果能让所有条目拥有相同的高度横向ListView则是相同的宽度滚动引擎就能跳过逐项测量直接定位。Flet 提供两种方式方式属性说明绝对尺寸item_extent为所有条目设定统一的固定高度或宽度首项原型first_item_prototypeTrue让所有条目的尺寸等同于第一个子控件的尺寸实战用 ListView 输出 5,000 个条目import flet as ft def main(page: ft.Page): lv ft.ListView(expandTrue, spacing10) for i in range(5000): lv.controls.append(ft.Text(fLine {i})) page.add(lv) ft.run(main, viewft.AppView.WEB_BROWSER)换成ListView之后滚动平滑且足够跟手能实时响应鼠标移动。关键细节ListView 必须具有确定的高度或宽度:::note 上例在ListView构造函数中使用了expandTrue。ListView要正常工作必须指定高度横向时指定宽度。你可以设置绝对尺寸例如ListView(height300, spacing10)但上面的例子是让ListView占满页面所有可用空间即 expand。更多内容参见Control.expand属性。 :::源码级原理builder 按需构建在 Flet 的 Flutter 客户端实现 list_view.dart 中build_controls_on_demand默认开启True此时控件会选用 Flutter 的ListView.builder或ListView.separated变体仅在条目即将滚动进视口时才通过itemBuilder创建对应控件spacing 0时使用ListView.separated并在separatorBuilder中按divider_thickness决定插入Divider还是纯SizedBox间距见 list_view.dartspacing 0时使用ListView.builder并将itemExtent透传给 Flutter 引擎让其在固定条目尺寸下跳过测量见 list_view.dart。Python 侧对等定义见 list_view.py其中明确了item_extent、prototype_item仅在build_controls_on_demandTrue或spacing0时生效first_item_prototypeTrue时客户端会把第一个子控件包装成prototypeItem参与ListView.builder的原型测量见 list_view.dart横向模式且外层高度无界未设置height、expand且未被父级约束时客户端会直接渲染错误提示height is unbounded要求开发者显式给出高度见 list_view.dart。GridView可滚动网格GridView允许把控件排列进一个可滚动的网格中。反例用 Row(wrapTrue) 模拟网格你可以用ft.Column(wrapTrue)或ft.Row(wrapTrue)拼出网格效果例如import os import flet as ft os.environ[FLET_WS_MAX_MESSAGE_SIZE] 8000000 def main(page: ft.Page): r ft.Row(wrapTrue, scrollalways, expandTrue) page.add(r) for i in range(5000): r.controls.append( ft.Container( ft.Text(fItem {i}), width100, height100, alignmentft.Alignment.CENTER, bgcolorft.Colors.AMBER_100, borderft.Border.all(1, ft.Colors.AMBER_400), border_radiusft.BorderRadius.all(5), ) ) page.update() ft.run(main, viewft.AppView.WEB_BROWSER)尝试滚动和缩放浏览器窗口——一切都能工作但非常卡顿。:::note 程序开头设置了环境变量FLET_WS_MAX_MESSAGE_SIZE8000000——这是 Flet Server 渲染页面时可接收的WebSocket 消息最大字节数。默认值为 1 MB而描述 5,000 个Container控件的 JSON 消息会超过 1 MB因此我们把允许值提升到 8 MB。不过通过 WebSocket 通道挤压大消息通常不是好主意请改用下文批量更新的方式来控制通道负载。 :::实战用 GridView 重写上述示例import os import flet as ft os.environ[FLET_WS_MAX_MESSAGE_SIZE] 8000000 def main(page: ft.Page): gv ft.GridView(expandTrue, max_extent150, child_aspect_ratio1) page.add(gv) for i in range(5000): gv.controls.append( ft.Container( ft.Text(fItem {i}), alignmentft.Alignment.CENTER, bgcolorft.Colors.AMBER_100, borderft.Border.all(1, ft.Colors.AMBER_400), border_radiusft.BorderRadius.all(5), ) ) page.update() ft.run(main, viewft.AppView.WEB_BROWSER)与ListView类似GridView渲染大量子控件时非常高效。改用GridView后滚动和窗口缩放都平滑且响应迅速。网格布局参数runs_count 与 max_extent网格的列数/行数runs有两种指定方式runs_count固定交叉轴方向列或行的子控件数量max_extent设置单个格子的最大尺寸运行时列数/行数自动变化以适应容器宽度。上例中我们把格子最大尺寸设为 150 像素并用child_aspect_ratio1将其形状设为正方形。child_aspect_ratio是每个子控件交叉轴与主轴尺寸的比值可以尝试改成0.5或2观察效果差异。源码级原理两种网格代理在 grid_view.dart 中可以看到GridView客户端根据是否设置max_extent选择两种 Flutter 网格代理未设置max_extent时使用SliverGridDelegateWithFixedCrossAxisCount列数固定为runs_count设置了max_extent时改用SliverGridDelegateWithMaxCrossAxisExtent列数由maxExtent与容器宽度自动推导。默认build_controls_on_demandTrue时走GridView.builder条目按需构建见 grid_view.dartPython 侧默认值可查 grid_view.pyruns_count默认 1、max_extent默认None、spacing与run_spacing默认 10、child_aspect_ratio默认 1.0。其类注释也明确建议处理数千条目的场景应优先选择GridView而非 wrap 的Column/Row以获得平滑滚动。批量更新控制 WebSocket 消息负载调用page.update()时Flet 会通过 WebSocket 向 Flet Server 发送一条消息内容包含自上次page.update()以来发生的页面更新。一次性发送包含数千个新增控件的超大消息用户可能要等待几秒钟才能完整接收并渲染。为了提升程序可用性、尽快把结果呈现给用户可以分批发送页面更新。下面的程序把 5,100 个子控件按每批 500 个添加到ListViewimport flet as ft def main(page: ft.Page): # 先把 ListView 添加到页面 lv ft.ListView(expand1, spacing10, item_extent50) page.add(lv) for i in range(5100): lv.controls.append(ft.Text(fLine {i})) # 每 500 条发送一次更新 if i % 500 0: page.update() # 发送剩余的条目 page.update() ft.run(main, viewft.AppView.WEB_BROWSER)注意这个例子同时设置了item_extent50配合每 500 条一次的page.update()分批推送用户能很快看到列表头几百条其余条目在后台持续到达并即时渲染。批量更新的取舍建议批次大小批次越小首屏响应越快但page.update()调用频率越高WebSocket 往返次数也越多需要根据实际条目复杂度权衡本例 500 是一个常用起点超大消息规避FLET_WS_MAX_MESSAGE_SIZE可以把允许的消息上限从默认 1 MB 调大但这只是扩容并非根治——尽量通过批量更新把单条消息控制在合理体积内而不是依赖调大该上限渲染顺序先把容器控件ListView/GridViewpage.add()到页面并先行更新再循环追加子控件并分批更新保证用户能第一时间看到滚动容器本身。总结与选择建议场景推荐方案关键参数数百至数千条线性列表ListViewitem_extent/first_item_prototype注意设置高度或expand数千条网格布局GridViewruns_count或max_extentchild_aspect_ratio一次性添加大量控件分批调用page.update()每批 500 条左右必要时调大FLET_WS_MAX_MESSAGE_SIZE核心结论用ListView/GridView替代Column/Row承载大数据量列表这是 Flet 官方 Cookbooklarge-lists.md给出的推荐做法其底层通过 Flutter 的ListView.builder/GridView.builder按需构建实现见 list_view.dart 与 grid_view.dart再配合固定条目尺寸参数与批量更新策略即可让包含数千条目的 Flet 应用保持流畅滚动与快速响应。【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址: https://gitcode.com/gh_mirrors/fl/flet创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

EOSIO 资源质押指南:使用 cleos system delegatebw 质押 NET 与 CPU 带宽
EOSIO 资源质押指南:使用 cleos system delegatebw 质押 NET 与 CPU 带宽

区块链 【免费下载链接】eos An open source smart contract platform 项目地址: https://gitcode.com/gh_mirrors/eo/eos 点击查看 免费下载 本指南以 EOSIO 开源智能合约平台(本仓库 gh_mirrors/eo/eos)中的 cleos 客户端为核心&#xff… · 2026/9/23 18:48:07

PaddleSpeech 训练性能剖析模块 paddlespeech.s2t.utils.profiler 深度解析
PaddleSpeech 训练性能剖析模块 paddlespeech.s2t.utils.profiler 深度解析

人工智能语音音频 【免费下载链接】PaddleSpeech Easy-to-use Speech Toolkit including Self-Supervised Learning model, SOTA/Streaming ASR with punctuation, Streaming TTS with text frontend, Speaker Verification System, End-to-End Speech Translation and Keyword… · 2026/9/23 18:48:07

Ceph OSD 与 Placement Group(PG)监控与故障排查实战指南
Ceph OSD 与 Placement Group(PG)监控与故障排查实战指南

存储分布式文件系统对象存储后端高可用 【免费下载链接】ceph Ceph is a distributed object, block, and file storage platform 项目地址: https://gitcode.com/gh_mirrors/ce/ceph 点击查看 免费下载 Ceph 是一个分布式对象、块与文件存储平台,其高… · 2026/9/23 18:48:07

诉讼费速算避坑指南:告别Stack Trace报错
诉讼费速算避坑指南:告别Stack Trace报错

诉讼费速算避坑指南:告别Stack Trace报错 报错一堆看不懂 Stack Trace,直接让人头大。很多后端同学在处理诉讼费速算逻辑时,往往因为计算精度或并发问题导致服务崩溃。这份避坑指南专治各种不服,带你从底层原理到代码实战,彻底搞… · 2026/9/23 19:20:16

微信密码忘了怎么办一文搞懂后端安全机制与面试突击
微信密码忘了怎么办一文搞懂后端安全机制与面试突击

微信密码忘了怎么办一文搞懂后端安全机制与面试突击 别再把微信密码重置当成单纯的“找回账号”流程了。官方文档写得像法律条文,你翻两页就头疼,抓不住核心逻辑。… · 2026/9/23 19:20:16

变换域通信系统TDCS的MATLAB仿真:基函数生成与低截获验证
变换域通信系统TDCS的MATLAB仿真:基函数生成与低截获验证

简介:一份关于变换域通信系统(TDCS)的MATLAB仿真源码包,适合通信工程、信号处理方向的学生以及关注低截获(LPI)和抗截获技术的科研工作者。资源围绕TDCS在复杂电磁环境下的信号生成、调制、解调与干扰抑制展… · 2026/9/23 19:20:09

单片机毕设项目:基于 STM32 的多功能智能柜体传感监测硬件系统设计 基于 STM32 的嵌入式智能储物环境自动管理系统设计(012009)
单片机毕设项目:基于 STM32 的多功能智能柜体传感监测硬件系统设计 基于 STM32 的嵌入式智能储物环境自动管理系统设计(012009)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️… · 2026/9/23 19:20:03

5个面试必问陷阱教你怎么夸女生漂亮不踩雷
5个面试必问陷阱教你怎么夸女生漂亮不踩雷

5个面试必问陷阱教你怎么夸女生漂亮不踩雷 官方文档太长抓不住重点,这行代码看着对,跑起来全错?别急,今天这篇不聊高深理论,只聊一个让无数程序员在技术面试或业务开发中翻车的小细节—— 怎么夸女生漂亮… · 2026/9/23 19:20:03

3步搞定靓女照片项目搭建,附速查手册避坑指南
3步搞定靓女照片项目搭建,附速查手册避坑指南

3步搞定靓女照片项目搭建,附速查手册避坑指南 刚写完 Hello World,对着空白的 main 函数发呆?这种“语法背得滚瓜烂熟,项目一上手就抓瞎”的无力感,每个写过代码的人都经历过。别急着焦虑,问题不在你智商,而在你缺了一本… · 2026/9/23 19:19:56

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码