Web TippsUse custom web fonts in Google Sheets charts(08.09.2026 um 17:05 Uhr)
Web TippsIntroducing the new 1Password App for Google Chat(08.09.2026 um 18:02 Uhr)
Web TippsUse custom web fonts in Google Sheets charts(08.09.2026 um 17:05 Uhr)
Web TippsIntroducing the new 1Password App for Google Chat(08.09.2026 um 18:02 Uhr)

🔧 Programmierung 🕛 vor 1 Jahr 2 Min Lesezeit
0

探究是否用 @ViewBuilder 替换 AnyView

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht




起因



里面,使用了分栏式的展示逻辑,即点击列表中的一个示例,在详细页面 detail view 里展示一个相关地图功能。每一个功能都有很丰富的交互,因此每个详细功能页面少则占用10M+,多则100M+的内存才能加载。



由于每个页面都算很“重”的视图,因此避免 SwiftUI 因视图 identity 改变而重新计算,变得尤为重要。



在这个 app 最初设计时,遇到了这样的问题:我有一个 所包装,一旦其被创建,后面渲染的时间是一样的。这样,我们可以只关注 AnyView@ViewBuilder 所产生的包装层的时间差别。



依据我的测试,当我遍历创建整个 app 里的200个左右示例页面,使用




CODE
func makeBody() -> AnyView { .init(\(sample.viewName)()) }

// 遍历所有示例并创建视图
var bodies: [AnyView] = []
for sample in SamplesApp.samples {
bodies.append(sample.makeBody())
}











CODE
@ViewBuilder
func view(for sample: Sample) -> some View {
switch sample {
case is AddPointCloudLayerFromFile:
AddPointCloudLayerFromFileView()
case is SelectFeaturesInFeatureLayer:
SelectFeaturesInFeatureLayerView()
// ...
default:
fatalError("Unknown \(sample.name) sample view generated.")
}
}

// 遍历所有示例并创建视图
var bodies: [any View] = []
for sample in SamplesApp.samples {
bodies.append(view(for: sample))
}






两个方法时 @ViewBuilder 的方法平均时间比 AnyView 要慢5%左右(50ms vs 55ms)。



这样的结果有些出乎我的意料。毕竟,如果理论上创建 AnyView 需要花更多时间来确定其运行时的类型,难道不应该花更多时间吗?



更令人意想不到的是接下来的发现。当我试图分析 @ViewBuilder func view(for sample: Sample) -> some View 这个方法返回的视图类型时,发现其并非如老版本中使用 _ConditionalContent 来包装视图,而是直接使用了 AnyView !即在调试器中,print(type(of: view(for: sample))) 的结果是 AnyView 。在调试器变量区显示的类型则是 <<opaque return type of ArcGIS_Maps_SDK_Samples.ContentView.view(for: ArcGIS_Maps_SDK_Samples.Sample) -> some>>.0



作为对比,在我第一次测试 @ViewBuilder 的结果时,它的类型是类似于如下的二叉树状结构的。当时我觉得这很合理——相当于用二叉搜索快速确定一个 result builder 的结果类型,应该性能上很不错。




CODE
_ConditionalContent<
_ConditionalContent<
_ConditionalContent<
AddRasterFromFileView,
AddSceneLayerFromServiceView
>,
_ConditionalContent<
BrowseBuildingFloorsView,
ClipGeometryView
>
>,
_ConditionalContent<
_ConditionalContent<
CreatePlanarAndGeodeticBuffersView,
CutGeometryView
>,
_ConditionalContent<
DisplayFeatureLayersView,
DisplayMapView
>
>
>,
// …






但是经过这次测试得到意想不到的结果,也能明白为什么 @ViewBuilderAnyView 要慢了。因为最终创建的都是 AnyView 的前提下,@ViewBuilder 多了花在 switch-case 判断的时间,比起直接从示例类型生成视图,相当于额外的时间。






测试3:大量 AnyView



用类似如下视图来测试 AnyView 在列表这种动态计算的视图中的性能影响。这个示例创建 50000 个 HStackAnyView 包装的文本视图。




CODE
import SwiftUI

class Model {
static let items50K = (0 ..< 50_000).map { Item(id: $0) }
}

struct Item: Identifiable {
let id: Int
var text: String { String(id) }
}

struct NormalItemView: View {
let item: Item

var body: some View {
HStack { Text(item.text) }
}
}

struct AnyItemView: View {
let item: Item

var body: some View {
AnyView(Text(item.text))
}
}

struct NormalListView: View {
var items: [Item]

var body: some View {
List(items) { item in
NormalItemView(item: item)
}
.listStyle(.plain)
}
}

struct AnyListView: View {
var items: [Item]

var body: some View {
List(items) { item in
AnyItemView(item: item)
}
.listStyle(.plain)
}
}

struct ContentView: View {
var body: some View {
NavigationView {
VStack(spacing: 20) {
NavigationLink {
NormalListView(items: Model.items50K)
} label: { Text("NormalView 50K") }

NavigationLink {
AnyListView(items: Model.items50K)
} label: { Text("AnyView 50K") }
}
}
}
}






明显可以看到,当打开 AnyView 的列表时,有很长一段卡死的时间。但是当 AnyView较少,比如一千个以下时,造成的性能影响并不大,不足以拖慢 app 的运行速度。






结论





  1. AnyView 个数不多,对性能影响不太大

  2. 使用 @ViewBuilder 替代 AnyView,在一些情况下并不能提升性能






参考链接





Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
3 Quellen
Use custom web fonts in Google Sheets charts
2 Quellen
Introducing the new 1Password App for Google Chat
1 Quelle
Context-aware access controls are available for Gemini Enterprise in the Admin console
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten 探究是否用 @ViewBuilder 替换 AnyView

Thematisch verwandte Begriffe: 探究是否用, ViewBuilder, AnyView · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...