学习目标
完成本单元后,你将能够:
- 解释优化数据检索的好处。
- 描述缓存数据的好处。
应对独特性能挑战
Lightning Web Components 运行在客户端、在单个页面中,与操作同一数据的其他组件一起按需创建和销毁——这给开发者带来独特的性能挑战。下面讨论这些特性如何影响性能,并回顾优化 Lightning 组件性能的最佳实践。首先是优化数据检索和缓存。
优化数据检索
没有数据的组件不是有用的组件。用 Lightning Web Components 从服务器检索数据时有多种选择,以下是优化服务器往返的方法:
- 尽可能使用 Lightning Data Service 或缓存数据。
- 调用服务器前,先确认没有其他获取数据的方式——适当用属性、事件或方法在组件间传递数据,而非在不同组件重复检索;同一页多个组件检索相同数据时,考虑创建一个无 UI 的服务组件一次查询、再把数据传给其他组件。
- 调用服务器时限制结果集的字段和行数——只 SELECT 需要的字段、给查询设置 LIMIT、大结果集实现分页。
- 偶尔访问的数据惰性加载,不要预加载用户可能不需要的数据。
- 不要为过滤或排序客户端已有数据而调用服务器(除非分页数据)——JavaScript 数组内置了 sort、filter、find 等函数。
- 用 Lightning Data Service 和 UI API 检索记录(而非 Apex),也能检索列表视图、元数据和 picklist 值。
- 用 getRecord wire 适配器时只请求组件需要的字段(要显式);不要按布局请求记录(布局字段多、开销大);除非绝对必要不要用 getRecordUi(响应包含的元数据往往比数据负载大 100–1000 倍)。
改进数据缓存
应用组合是组装自包含组件来构建应用的强大方式,但若规划不当,组件的自治性会对性能产生负面影响——如果每个组件都各自向服务器发起独立调用,就会有大量调用。一次较大的调用比多次小调用更高效。客户端数据缓存通过在组件间共享数据来提升性能,显著减少服务器往返次数。LWC 有两种内置客户端缓存机制:Lightning Data Service 和可缓存 Apex 方法;若两者都不适用,也可实现自定义缓存方案。
Lightning Data Service
Lightning Data Service 提供托管记录方式:你无需编写 Apex 数据访问逻辑,它还会通过检查记录和字段的可访问性来为你处理安全。框架负责管理记录——首次请求时从服务器获取、存储到高效的客户端缓存、在请求相同数据的所有组件间共享、把变更发送到服务器并在依赖的 Salesforce 数据变化时使缓存项失效。如果另一组件随后需要额外字段,这些字段会被透明加载并加入缓存中的记录。
Lightning Data Service 缓存多种 UI API 数据(记录、schema、元数据、布局元数据、记录列表等),还提升 UI 一致性:某组件更新记录后,所有使用该记录的组件会收到通知并多数自动刷新。
可缓存 Apex 方法
无法使用 Lightning Data Service 时,用 Apex。可缓存 Apex 方法(cacheable Apex method)是一种服务器动作,其响应存储在客户端缓存中,之后相同方法、相同参数的请求可直接从缓存获取而非服务器。可缓存方法让你用传统远程过程调用(RPC)方式访问数据。一般准则是:缓存(标记为 storable)任何幂等且非变更的动作。创建很简单,只需给 Apex 方法加 @AuraEnabled(cacheable=true) 注解;API 版本 55.0 及以上可用 @AuraEnabled(scope='global') 启用全局缓存。
使用渐进式披露与条件渲染
本单元介绍渐进式披露、惰性实例化和条件渲染,只在需要时显示数据。
学习目标
完成本单元后,你将能够:
- 解释渐进式披露的好处。
- 描述条件渲染。
用渐进式披露优化性能
在屏幕上显示所有可用数据和工具通常不是好的 UX 实践,也会显著影响性能。加入页面布局的 Lightning 组件在页面加载时实例化,增加页面加载时间。因此交互设计指南倾向于渐进式披露(progressive disclosure)——只呈现手头任务所需的最少数据,把高级或很少用的功能推迟到次要界面,让应用更易学习、更少出错。实现渐进式披露、推迟非必要数据或功能有几种方法,重点看两种:惰性实例化(lazy instantiation/lazy loading)和条件渲染。
惰性实例化
惰性实例化(或惰性加载)指对象或组件在首次使用前不创建。可以在 Lightning Experience 中实现,或利用不同的选项卡组件。
Lightning Experience 中的惰性实例化
Lightning App Builder 可以声明式实现渐进式披露,把组件放到 Lightning Experience 中惰性实例化的特定区域:标准选项卡组件(信息隐藏、用户选择时才加载)、Lightning 组件动作或快速动作(用户点击按钮时才加载)、Utility Bar(可添加到任何应用,按钮在用户点击时加载组件)。
自己组件中的惰性实例化
可以利用 lightning-tabset 和 lightning-tab 等选项卡组件,它们默认支持惰性实例化。注意:TabSet 和 App Builder 选项卡组件是惰性加载的,但 Lightning Console 中的选项卡作为工作区加载、子选项卡不是惰性加载。
条件渲染
条件渲染指对象或组件只有在状态或行为匹配时才出现。有三种条件渲染 Lightning Web Components 的选项:Lightning App Builder 动态组件可见性、lwc:if|elseif|else、CSS。
Lightning App Builder 动态组件可见性
第一种选项是声明式的、直接内置于 App Builder。动态组件可见性通过在 Lightning App Builder 中给组件属性添加过滤条件和逻辑来控制组件何时出现在 Lightning 页面。例如可以构造一个过滤器,让商机页上的富文本组件在商机金额大于等于 100 万美元时显示。
lwc:if/elseif/else
第二种选项让开发者用 lwc:if|elseif|else 条件渲染 DOM 元素,惰性实例化 UI 的某部分:如果条件为 true,第一个 div 及其所有子元素被创建,第二个 div 不渲染;条件变 false 时互换(第一个 div 销毁、第二个渲染)。
CSS
第三种选项用 CSS 样式切换可见性:div 及其所有子元素预先创建并渲染,但在 JavaScript 运行前对用户隐藏。用 CSS 会预先创建组件,所以页面加载时没有像前两种方法的性能收益,但 JavaScript 运行时组件立即显示、无需初始化或渲染。CSS 隐藏与 if:true/false 的重要区别:CSS 方式组件保持存活、状态被维护;if:true|false 会销毁并重建组件、状态丢失(重置)。
使用顺序:先考虑声明式选项(仅适用于为 App Builder 配置的组件),其次是 if:true|false(适用于所有组件),两者都通过推迟组件或封闭元素树的创建渲染来加快初始加载;第三种 CSS 用于开发者想预加载组件、条件满足时再显示的情况。
探索更多渲染选项
本单元介绍列表、事件、第三方库、Base 组件、图片优化和生命周期渲染等更多提升性能的选项。
学习目标
完成本单元后,你将能够:
- 描述列表和事件的选项。
- 描述如何使用第三方 JavaScript 库和样式表。
- 为 Lightning Web Components 优化图片。
- 解释 Base Lightning 组件的好处。
- 描述如何使用生命周期渲染和回流。
引言
多数 Lightning Web Components 的性能提升可以通过前几个单元的最佳实践实现,但还有一些额外的渲染选项可以进一步提升性能。
列表
列表便于显示大量数据,但准备不好可能显示过多数据。使用列表要注意:列表应用 for:each 或 iterator 创建(区别是 iterator 有 first/last 属性,可对数组首尾项应用特殊行为);创建自定义列表组件时不要支持无限列表项(大 org 记录多时严重影响性能,要么提供分页、要么虚拟化列表);每个列表元素必须有跨所有子元素唯一的 key;在列表中封装功能的 Lightning Web Component 会带来大量开销,尤其是大列表。
事件
事件是组件间通信的好方式,Lightning Web Components 派发标准 DOM 事件,组件也能创建和派发自定义事件。使用事件和事件处理器要注意:把事件处理器数量最小化(每个处理器都有开销);理解父子组件的冒泡和组合事件传播,通常用 bubbles:false、composed:false(最不具破坏性);同一 Lightning 页面或多页面间的兄弟组件通信可用 Lightning Message Service(跨 Visualforce、Aura、LWC、utility bar 组件和控制台应用页面选项卡);给非组件生命周期的东西(如 window、document)添加监听器时,要在 disconnectedCallback 中用 removeEventListener() 自己移除,否则会导致内存泄漏;列表场景中让事件冒泡、在父元素上注册单一事件监听器(而非每个列表项各一个)可显著减少监听器数量。
第三方 JavaScript 库和样式表
尽可能移除对不必要库的依赖。决定在 Lightning 组件中使用第三方库前,重新评估是否真的需要——尤其是 DOM 操作库(如 jQuery)和 UI 库(如 Bootstrap、jQuery UI)在 LWC 中可能不再需要。只有当 Salesforce Lightning Design System(SLDS)不满足需求时,才用第三方或自定义样式表。
DOM 操作库
JavaScript 近年来发展迅速,很多以前离不开的 DOM 操作工具(如 jQuery)现在已是语言标准功能。Lightning Web Components 等现代框架也提供了让 jQuery 不再那么必要的抽象。
UI 库
建议避免使用 Bootstrap、jQuery UI 等 UI 库。这些库虽然提供了有用的组件,但它们有自己的 UI 风格,可能与 Lightning Experience 的风格冲突。Base Lightning 组件和 SLDS 提供了类似能力,同时保证一致的用户体验。
MVC 框架
React、AngularJS 等库在高层与 Lightning Web Components 框架有相同的关注点:提供代码组织和创建组件的工具。不建议在组件内同时使用另一个 MVC 框架。不过可以用 Lightning 组件作为容器,在 Lightning Experience 中托管用其他框架(如 React、AngularJS)构建的组件,但这超出本单元范围。
自定义样式表
使用第三方 CSS 样式表或创建自己的样式可能引起性能问题、让 UI 对终端用户显得不一致。开发者应熟悉 Salesforce Lightning Design System(SLDS)——它不止是样式和 CSS,还包括设计指南和原则、组件蓝图(Breadcrumbs、Modals、Alerts 等),以及大量存储视觉设计属性(颜色、字体、间距、尺寸、触控)的 Design Tokens。利用 SLDS 还能节省构建组件的时间,因为它内置于 Lightning、无需自己创建和维护 CSS。
使用压缩版本
如果确实需要使用第三方库,务必使用库和样式表的压缩(minified)版本,以提升应用性能。
Base Lightning 组件
构建自定义 Lightning 组件前,先熟悉提供的 base 组件库(如 lightning-input-field、lightning-record-form 等),利用它们能显著加快开发。Base Lightning 组件的额外好处:样式(原生 Lightning 观感)、性能(已在客户端加载、无需额外下载处理)、响应式(默认响应式设计)、创新(lightning 命名空间积极开发新组件)、无障碍(为可访问性构建)、客户端验证(适用时内置)。
图片优化
尽可能使用(基于雪碧图的)SLDS 图标(用 lightning-icon 和 lightning-button-icon)而非自定义图标——Salesforce 有数百个图标可选。使用其他图片时,务必锁定图片尺寸以避免回流,并尽可能按该尺寸提供图片(例如不要加载高分辨率图片来显示缩略图)。
组件生命周期渲染与回流
Lightning Web Components 的生命周期由框架管理:框架创建组件、插入 DOM、渲染、从 DOM 移除。阅读渲染生命周期了解各方法何时触发。尽量减少组件重新渲染的次数;某些情况下锁定 DOM 区域为特定尺寸,避免周围区域的浏览器回流。
总结
应用性能受多种因素影响。本文描述的 Lightning Web Components 性能优化技术是通用指南,能帮你构建更快、响应更好的应用。在应用中试试吧。






























