惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Register - Security
The Register - Security
美团技术团队
Recent Announcements
Recent Announcements
MongoDB | Blog
MongoDB | Blog
Jina AI
Jina AI
C
Check Point Blog
aimingoo的专栏
aimingoo的专栏
I
InfoQ
S
Securelist
T
Tor Project blog
GbyAI
GbyAI
L
LINUX DO - 热门话题
V
Visual Studio Blog
AWS News Blog
AWS News Blog
The Cloudflare Blog
腾讯CDC
K
Kaspersky official blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recorded Future
Recorded Future
李成银的技术随笔
W
WeLiveSecurity
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
M
Microsoft Research Blog - Microsoft Research
G
Google Developers Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Schneier on Security
Schneier on Security
B
Blog
IT之家
IT之家
爱范儿
爱范儿
H
Help Net Security
Simon Willison's Weblog
Simon Willison's Weblog
NISL@THU
NISL@THU
J
Java Code Geeks
博客园 - 聂微东
T
The Exploit Database - CXSecurity.com
Cyberwarzone
Cyberwarzone
博客园 - 叶小钗
MyScale Blog
MyScale Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Project Zero
Project Zero
F
Future of Privacy Forum
D
Darknet – Hacking Tools, Hacker News & Cyber Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Hacker News: Ask HN
Hacker News: Ask HN
D
Docker
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog RSS Feed
V
Vulnerabilities – Threatpost

DEV Community

How to Tailor Your Resume to a Job Description in 5 Minutes (A Method That Actually Works) JWT vs Session Tokens in Spring Boot: A Senior Dev's Decision Guide How to Choose an AI Gateway in 2026 How to Teach Source Evaluation When Your Students Use ChatGPT Why Passwordless B2C Rollouts Stall at 5% (and How to Reach 60%) Rmux Review: Rust Terminal Multiplexer Built for AI Agents I realized I was only using half of what Claude Code has to offer DevOps & Deployment Essentials: Your Practical CI/CD Guide How next-generation captchas work and why it matters for automation Chat is Dead: How JSON Prompting Cut My AI Costs by 73% What if Everybody Were Suddenly... Better? OCI Web Application Firewall (WAF) Deep Dive: Architecture, Traffic Inspection, Threat Protection, and Enterprise Security Design Selling Digital Products in a Country PayPal Refuses to Touch PostgreSQL backup tool Databasus released backup verification in real database Docker containers We Connected an LLM to a 12-Year-Old Codebase. Here's What Broke. The Fallacy of Digital Platforms: Why Stripe Isn't Always King Sizce Google'ın 26 Mayıs tarihinde arama bölümünü tamamen yapay zekaya devredecek olması açık webin devamı için nasıl sonuçlanır? When Should You Use GraphRAG Instead of RAG? Big Data Is Not Just About “Huge Data” The Prefix Bubble MPP TestKit VSCode Extension - Inline HTTP 402 Payment Flow Hints The README Was a Protocol. The Entrypoint Was Still Optional. After AI Healthcare, Medical World Models May Be the Next Life-Science AI Platform Your AI Agent Doesn't Need an API Key: Entra Agent ID and Anthropic's Workload Identity Federation ECDSA - The Math That Only Goes One Way S3 Files Killed My Least Favorite Lambda Pattern BNB RPC Endpoints for Production Apps and Backend Workloads I Used to Get Excited About New Tools Now I Feel Tired. Google I/O 2026 — What I Hoped to See Beyond the Model Announcements Most 'AI agents' are just scripts with a marketing budget 🚀 Replicating the evasive VoidLink: My Journey Building Cortex C2 # new stuff dropped in duckkit 🦆 Paying the bills in a restricted country with cryptocurrency: the lie that almost killed our digital product Building Global Economies Through Better APIs: Lessons from PayPal vs Crypto for Crypto Payments in Developing Countries Verified or Not? Ep. 2 — Snyk's Own Test App Scanned With 9 Engines 17 SessionAuth Tools in OpenClaw: Integrate Any AI Framework with Wallet Infrastructure WebMCP and the Citation Paradox — What Agent-Ready Websites Actually Mean for GEO What Gemma 4 Doesn't Know About Cameroon — and What That Taught Me About Building AI for the Real World AI Can Generate Code — And Interactive Coding Playgrounds Are Becoming Essential Modern Web Guidance: Teaching AI Agents to Stop Coding Like It's 2019 The Discipline We Forgot We Had I Built a 3-Agent AI Research Crew in 250 Lines of Python (LangGraph + Free Gemini) PostgreSQL MCP: Let Claude query your databases in plain English Building digital products and Android apps under IteraTrail Fuel Price API for Fleet Cost Planning Linux File System Explained Simply Building a shot-detection worker for an upload pipeline with PySceneDetect 0.7 Wiring VMAF (and PSNR) into your encoder CI with FFmpeg 8.1 and ffmpeg-quality-metrics Bikin Chatbot Sendiri yang Bisa Jawab Pertanyaan dari Dokumen kamu Learning Arabic: Where to Start
2026年的Flutter与React Native:我用两者都构建了同一个应用
Davide Mibel · 2026-05-21 · via DEV Community

我花了三个周末重复构建同一个应用。不是出于实验——我面临着一个真正的决定。我们在工作中的一个内部工具中添加一个移动伴侣,这是一个基于Spring Boot微服务运行的任务管理系统。我的团队之前接触过Dart;而我更习惯JavaScript。我们两个在过去两年里都没有发布过严肃的移动应用。选择技术栈的唯一诚实方式是在两个框架中构建一些真实的东西,并比较我所发现的情况。

我开发的这个应用不是玩具。它从REST API获取任务,使用SQLite本地缓存,在截止日期临近时触发计划推送通知,并在具有三个标签的底部导航布局上实现平滑的列表动画。简单到可以在周末完成。复杂到足以揭示这两个框架之间的真实差异。

这是我发现的内容——包括一个令我惊讶的结果。

应用程序

比较之前,我先具体说明我构建的内容。两个版本:

  • 从分页的REST端点获取任务并带认证头
  • 使用SQLite本地缓存响应
  • 在标记任务完成时支持乐观更新
  • 在每次任务截止时间前一小时安排本地推送通知
  • 使用带三个标签的底部导航栏

这不是生产代码——这是一个受控的比较。两款应用都访问运行在我MacBook上的同一个模拟API。相同的UI设计,相同的功能集,不同的框架.

设置与开发者体验

Flutter的设置前期更复杂。你需要运行flutter doctor,追赶 Android SDK 版本,配置 Xcode 命令行工具。在一个干净的 Mac 上,我花了大约 45 分钟在两个模拟器上得到一个绿色的构建。错误消息通常足够具体来指导你,但它是一项机械性的工作.

使用 React Native 和 Expo 只花了 15 分钟。npx create-expo-app,选择一个模板,运行npx expo start,扫描二维码。完成。摩擦差是真实的,特别是如果你正在为新接触移动开发的团队进行入职培训.

难点在于:Expo的托管工作流程在需要Expo SDK中不包含的原生模块时工作得非常出色。然后你退出,你大致回到了与裸React Native设置相同的复杂程度。对于这个测试应用,我保持在托管Expo中并且没有遇到任何障碍.

Flutter app and React Native app running side-by-side in iOS and Android simulators, both showing the same task list with identical data and a bottom navigation bar with three tabs

编写UI代码

这是框架在日常使用中最能体现差异的地方。

Flutter 使用组件——所有东西都是组件,可组合且明确。这是任务列表项:

class TaskTile extends StatelessWidget {
  final Task task;
  final VoidCallback onComplete;

  const TaskTile({super.key, required this.task, required this.onComplete});

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text(
        task.title,
        style: task.completed
            ? const TextStyle(decoration: TextDecoration.lineThrough)
            : null,
      ),
      subtitle: Text(task.dueAt.toLocal().toString().substring(0, 16)),
      trailing: task.completed
          ? const Icon(Icons.check_circle, color: Colors.green)
          : IconButton(
              icon: const Icon(Icons.radio_button_unchecked),
              onPressed: onComplete,
            ),
    );
  }
}

进入全屏模式 退出全屏模式

React Native with TypeScript:

type TaskTileProps = {
  task: Task;
  onComplete: () => void;
};

export function TaskTile({ task, onComplete }: TaskTileProps) {
  return (
    <TouchableOpacity
      style={styles.row}
      onPress={task.completed ? undefined : onComplete}
    >
      <View style={styles.info}>
        <Text style={[styles.title, task.completed && styles.completed]}>
          {task.title}
        </Text>
        <Text style={styles.due}>{formatDate(task.dueAt)}</Text>
      </View>
      {task.completed ? (
        <Ionicons name="checkmark-circle" size={22} color="#4CAF50" />
      ) : (
        <Ionicons name="radio-button-off" size={22} color="#999" />
      )}
    </TouchableOpacity>
  );
}

进入全屏模式 退出全屏模式

两者都易于阅读。Flutter版本更冗长但更有结构——你始终处于一个显式的、类型化的组件树中。React Native版本如果你为Web编写React,会感觉立刻熟悉,这取决于你团队的背景,是优势还是劣势。

我注意到一件事:在一天的完整开发过程中,Flutter的热重载比React Native更快、更可靠。不是戏剧性的——而是持续稳定的。

状态管理

我在Flutter中使用了Riverpod,在React Native中使用了Zustand。两者都很轻量级且明确。我故意避免了Provider或Redux,因为这个项目规模不大。

使用Riverpod的Flutter:

final tasksProvider = AsyncNotifierProvider<TasksNotifier, List<Task>>(
  TasksNotifier.new,
);

class TasksNotifier extends AsyncNotifier<List<Task>> {
  @override
  Future<List<Task>> build() => _fetchTasks();

  Future<void> completeTask(String id) async {
    final previous = state;
    state = AsyncData(
      state.value!
          .map((t) => t.id == id ? t.copyWith(completed: true) : t)
          .toList(),
    );
    try {
      await TasksApi.complete(id);
    } catch (_) {
      state = previous;
    }
  }
}

进入全屏模式 退出全屏模式

使用Zustand的React Native:

interface TaskStore {
  tasks: Task[];
  loading: boolean;
  fetchTasks: () => Promise<void>;
  completeTask: (id: string) => Promise<void>;
}

export const useTaskStore = create<TaskStore>((set, get) => ({
  tasks: [],
  loading: false,
  fetchTasks: async () => {
    set({ loading: true });
    const tasks = await TasksApi.fetchAll();
    set({ tasks, loading: false });
  },
  completeTask: async (id) => {
    const previous = get().tasks;
    set({
      tasks: previous.map((t) => (t.id === id ? { ...t, completed: true } : t)),
    });
    try {
      await TasksApi.complete(id);
    } catch {
      set({ tasks: previous });
    }
  },
}));

进入全屏模式 退出全屏模式

这些模式几乎一样——乐观更新,失败时回滚。操作体验差不多。如果你已经了解其中一个库,下午就能熟悉另一个。

性能

这就是我个人的叙事转折点。

Flutter 通过自己的引擎渲染。到 2026 年,Impeller 将成为 iOS 和 Android 的默认选项。它不使用原生 UI 组件 — 它自己绘制所有内容。这意味着跨平台完美的帧率一致性和不依赖于 JavaScript 线程的动画。

React Native 的新架构 — JSI 加 Fabric,自 RN 0.74 起默认启用,消除了旧的异步桥接。线程通信现在变为同步。这于 2024-2025 年关闭了显著的性能差距。

Side-by-side architecture comparison — Flutter's Dart VM plus Impeller rendering pipeline on the left, React Native's JSI plus Fabric architecture on the right, showing how UI updates flow from app code to the screen in each case

实际上,对于这个应用,我在现代设备上无法可靠地区分差异。在列表滚动时,两者都达到了60fps。差距出现在你用力推时——复杂的自定义动画、繁重的计算、非常长的列表。Flutter在那里仍然获胜,但你必须构建一些有要求的东西才会关心。

构建大小:Flutter发布APK是21MB。React Native裸是18MB。Flutter带着它的引擎到处走。

生态系统和第三方库

React Native受益于整个JavaScript生态系统。需要日期选择器、图表库、PDF生成器?npm上都有现成的包。问题在于它是否有真正的原生绑定,还是纯JavaScript的回退方案。

Flutter 的 pub.dev 更小但更经过精心挑选。包通常质量更高且维护得更好,因为社区更加专注。对于常见需求——HTTP 客户端、SQLite、推送通知、状态管理——Flutter 生态系统很稳固。

Flutter 仍然存在不足之处:一些 SDK 会先发布它们的 React Native 版本,然后才发布 Flutter 版本,有时会延迟数月。分析工具、一些支付网关、特定的第三方集成。如果你的应用依赖其中之一,请在确定之前检查 Flutter SDK 的可用性。

对于推送通知来说,两者flutter_local_notifications 和 Expo 通知在我的测试中运行顺畅。API质量没有明显差异。Flutter的设置需要直接触摸原生配置文件;Expo将这一点抽象化了.

我发布的

我发布了Flutter版本。这个决定是基于我特定情况下的因素.

界面一致性 — 我们的 App 拥有自定义列表动画和一种需要在 iOS 和 Android 上看起来完全一致的设计语言。Flutter 的渲染器保证了这一点,不会出现平台差异。

现有的 Dart 暴露 — 我的团队在 2023 年短暂使用过 Flutter。与切换到每个人都需要从零开始学习的移动特定 React/TypeScript 设置相比,启动成本较低。

没有异国情调的 SDK 要求 — 我们不依赖任何第三方SDK,这样可以避免我们面临“即将推出Flutter SDK”的问题。

桌面端已在路线图中 — Flutter在移动端、桌面端和Web端的单一代码库对我们很重要。我们已经运行着Spring Boot后端;为内部运营添加Flutter桌面客户端是直截了当的。

如果我们的团队使用 JavaScript 较多,或者如果我们需要与 Web 前端共享组件,那么 React Native 将是正确的选择.

真实总结

当 Flutter 更有意义时:

  • 像素级自定义 UI — 你完全控制渲染器
  • 性能密集型动画 — 没有 JS 线程瓶颈
  • 超越移动端的定位 — 2026年Flutter桌面和网页版是真实的选择
  • 团队愿意学习Dart — 投资看起来比实际小

当以下情况时React Native更合适:

  • 以JS为主的团队 — 如果你的团队已经熟悉React,则无需磨合
  • 与网页共享逻辑 — React Native Web 和共享业务逻辑已经成熟
  • Expo 加速 MVP 开发 — 托管的 Expo 确实是开发可运行应用的最快路径
  • 广泛的 SDK 可用性 — 一些第三方 SDK 仍然优先考虑 React Native 绑定

2026年,这两个框架都不是错误。2019-2022年的"Flutter与React Native"之争产生了许多时效性不佳的激烈观点。两者都能发布真实的生产应用。两者都有活跃的社区。两者已经足够趋同,以至于你的团队背景比框架的原始能力更重要。

我唯一要反对的一点是:不要仅仅因为团队里每个人都熟悉 JavaScript 就选择 React Native。移动开发已经有很多平台特有的怪癖——权限流程、后台任务、通知权限、密钥串存储——因此框架的选择不如理解 iOS 和 Android 实际工作原理来得重要。无论哪种方式,这种学习都是必需的。


2026年你在移动生产中运行的是什么?如果你在某个时候切换了框架——从Flutter切换到React Native或者反过来——是什么最终促使你下定决心?


最初发表于Medium