尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
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),仅供参考
RELATED

相关推荐

3道高频面试题拆解 chengrenwangzhan 手写实现避坑

3道高频面试题拆解 chengrenwangzhan 手写实现避坑

3道高频面试题拆解 chengrenwangzhan 手写实现避坑 刚复制的代码跑不通,对着报错信息发呆?别慌,这在【chengrenwangzhan】这类底层组件开发中太常见了。很多同学在准备【高频面试题】时,喜欢直接背代码,但面试官稍加…

📅 2026/9/23 18:48:17
程序员述职答辩 PPT 画图指南:结构图、架构图、流程图与逻辑图的绘制思路与实战方法

程序员述职答辩 PPT 画图指南:结构图、架构图、流程图与逻辑图的绘制思路与实战方法

文档教程后端 【免费下载链接】CodeGuide :books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总,旨在为大家提供一个清晰详细的学习教程,侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助,请给予支持(关注、…

📅 2026/9/23 18:43:17
PX4 VTOL 风标(Weather Vane)功能:原理、参数配置与源码实现解析

PX4 VTOL 风标(Weather Vane)功能:原理、参数配置与源码实现解析

嵌入式物联网机器人自动驾驶智能硬件 【免费下载链接】PX4-Autopilot PX4 Autopilot Software 项目地址: https://gitcode.com/gh_mirrors/px/PX4-Autopilot 点击查看 免费下载 导读:本文围绕 PX4 Autopilot 的 VTOL 风标(Weather Vane&…

📅 2026/9/23 18:43:17
MORE NEWS

更多资讯

📰

基于IPFS、Ethereum与ABE的区块链安全数据共享系统解析

简介:一套结合IPFS、Ethereum与ABE(基于属性加密)的区块链安全数据共享系统设计源码,面向区块链开发者和数据安全研究人员,适用于金融、医疗、法律等对数据保护要求较高的场景。包内含2000个文件,压缩包约6…

📰

论文降AIGC,其实是在跟“太完美”作对

官网:www.shujiangce.com | 微信 公众号 :书匠策AI 你有没有想过一个问题:为什么检测器能认出AI写的东西? 不是因为它读懂了你的论文。不是因为它理解了你的论证。是因为AI写的东西,太“干净”了。 你写论文的时…

📰

AI辅助论文写作的应用价值与规范发展路径探析

刚接触一个新领域,最怕的就是迷失在海量的外国文献里,读了很多篇还是理不清脉络。我曾经也以为“研究现状”只能靠逐篇阅读、手动总结,直到发现了一些能生成“知识图谱”的神器。它们能让你像开了上帝视角一样,瞬间看清一个领域的…

📰

ShowDoc 中的 Guzzle PHP HTTP 客户端:从 Composer 安装到 OAuth2 集成实战

ShowDoc 中的 Guzzle PHP HTTP 客户端:从 Composer 安装到 OAuth2 集成实战 【免费下载链接】showdoc ShowDoc is a tool greatly applicable for an IT team to share documents online一个非常适合IT团队的在线API文档、技术文档工具 项目地址: https://gitcode…

📰

Eclipse Mosquitto 1.4.1 版本发布解析:安全修复、Broker 稳定性与客户端库关键改动全解读

后端消息队列消息路由 【免费下载链接】mosquitto Eclipse Mosquitto - An open source MQTT broker 项目地址: https://gitcode.com/gh_mirrors/mos/mosquitto 点击查看 免费下载 本文以 Eclipse Mosquitto 官方发布的 Version 1.4.1 released 公告为核心&#xf…

📰

GetX 依赖注入完全指南:无 Context 的依赖管理、Bindings 与 SmartManagement 深度解析

前端 【免费下载链接】getx Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get. 项目地址: https://gitcode.com/gh_mirrors/ge/getx 点击查看 免费下载 本文基于仓库文档 documentation/ru_R…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬