前端跨端方案的架构权衡:React Native、Flutter 与 Taro 在出行平台的对比复盘
前端跨端方案的架构权衡React Native、Flutter 与 Taro 在出行平台的对比复盘一、跨端需求的背景与约束出行平台有三个前端端乘客端H5 小程序、司机端App、管理后台Web。2024 年初团队评估跨端方案时的核心约束乘客端小程序微信生态内运营必须支持小程序且需与 H5 共享业务逻辑。司机端 App实时导航 WebSocket 推送对性能和原生交互能力要求高。管理后台 Web纯 Web不需要跨端。团队技术栈React/Vue3 TypeScript团队对 Dart 和原生开发经验为零。跨端方案的核心权衡维度渲染性能、开发效率、生态成熟度、原生能力、团队适配成本、长期维护成本。以下是基于出行平台实际验证的数据对比。二、React Native 在司机端的实践2.1 架构设计与性能实测司机端 App 的核心场景实时地图渲染、WebSocket 位置推送、导航交互。React Native 的新架构Fabric TurboModule对这三个场景的性能表现指标RN 旧架构RN 新架构 (Fabric)原生 (Swift/Kotlin)地图帧率42 FPS58 FPS60 FPSWebSocket 延迟180ms45ms15ms交互响应120ms35ms10msCold Start3.2s1.8s0.8s内存占用180MB95MB45MB// react-native/driver-app/DriverNavigation.tsx — 司机端导航组件 import React, { useEffect, useRef, useCallback } from react; import { View, Text, StyleSheet } from react-native; import MapView, { Marker, Polyline } from react-native-maps; import { useWebSocket } from ../hooks/useWebSocket; interface NavigationProps { orderId: string; destination: GeoPoint; } interface NavigationState { currentLocation: GeoPoint | null; routePoints: GeoPoint[]; remainingDistance: number; // 剩余距离(km) estimatedArrival: number; // 预估到达(分钟) orderStatus: OrderStatus; } export function DriverNavigation({ orderId, destination }: NavigationProps) { const mapRef useRefMapView(null); const ws useWebSocket(ws://api.example.com/driver/location/${orderId}); const [state, setState] React.useStateNavigationState({ currentLocation: null, routePoints: [], remainingDistance: 0, estimatedArrival: 0, orderStatus: navigating, }); // WebSocket实时位置推送TurboModule架构下延迟45ms useEffect(() { if (!ws.connected) return; ws.onMessage((data: LocationUpdate) { setState((prev) ({ ...prev, currentLocation: data.location, remainingDistance: data.remainingDistance, estimatedArrival: data.estimatedArrival, })); // 自动调整地图视角跟随当前位置 mapRef.current?.animateCamera({ center: data.location, zoom: 15, }); }); return () ws.offMessage(); }, [ws.connected, orderId]); // 接单操作通过TurboModule直接调用原生模块无JS Bridge开销 const handleAcceptOrder useCallback(async () { try { // TurboModule直接调用原生OrderService const NativeOrderService require(NativeOrderService).default; const result await NativeOrderService.acceptOrder(orderId); if (!result.success) { alert(result.reason ?? 接单失败); return; } setState((prev) ({ ...prev, orderStatus: accepted })); } catch (error) { alert(接单异常: ${(error as Error).message}); } }, [orderId]); return ( View style{styles.container} MapView ref{mapRef} style{styles.map} initialRegion{{ latitude: destination.latitude, longitude: destination.longitude, latitudeDelta: 0.02, longitudeDelta: 0.02, }} {/* 当前位置标记 */} {state.currentLocation ( Marker coordinate{state.currentLocation} title当前位置 pinColorblue / )} {/* 目的地标记 */} Marker coordinate{destination} title目的地 pinColorred / {/* 导航路线 */} {state.routePoints.length 0 ( Polyline coordinates{state.routePoints} strokeColor#4A90D9 strokeWidth{4} / )} /MapView {/* 底部信息面板 */} View style{styles.infoPanel} Text style{styles.distanceText} 剩余 {state.remainingDistance.toFixed(1)} km /Text Text style{styles.timeText} 预估 {state.estimatedArrival} 分钟到达 /Text /View /View ); } const styles StyleSheet.create({ container: { flex: 1 }, map: { flex: 1 }, infoPanel: { padding: 16, backgroundColor: white, borderTopWidth: 1, borderTopColor: #E0E0E0, }, distanceText: { fontSize: 18, fontWeight: 600 }, timeText: { fontSize: 14, color: #666, marginTop: 4 }, });2.2 React Native 的维护代价React Native 的维护代价集中在三个环节原生模块升级、版本兼容、调试工具链。// react-native/native-modules/NativeOrderService.ts — TurboModule原生模块定义 import { TurboModuleRegistry } from react-native; import type { TurboModule } from react-native/Libraries/TurboModule/TurboModule; export interface Spec extends TurboModule { // 接单操作直接调用原生OrderService绕过JS Bridge acceptOrder(orderId: string): Promise{ success: boolean; reason: string | null }; // 取消订单 cancelOrder(orderId: string): Promise{ success: boolean; reason: string | null }; // 获取订单详情 getOrderDetail(orderId: string): PromiseOrderDetail | null; } // TurboModule自动注册无需手动桥接 export default TurboModuleRegistry.getEnforcingSpec(NativeOrderService);原生模块的代价每个 TurboModule 需要同时维护 Swift 和 Kotlin 两套实现。出行平台司机端有 6 个原生模块每次 iOS/Android 系统升级后需要逐一验证兼容性。2024 年的数据原生模块维护占司机端总维护时间的 35%。三、Flutter 的评估与未采纳理由3.1 性能数据对比Flutter 在出行平台做了为期 2 周的技术验证实测数据指标FlutterReact Native (Fabric)差异地图帧率60 FPS58 FPS3.4%Cold Start1.2s1.8s-33%内存占用68MB95MB-28%交互响应12ms35ms-66%WebSocket 延迟20ms45ms-56%Flutter 的渲染性能确实优于 React Native。但性能差异在司机端场景中不是决定性因素58 FPS 对司机端的地图渲染已经足够流畅45ms 的 WebSocket 延迟在实时位置推送场景中用户感知差异不大100ms 的延迟人类几乎无法察觉。3.2 采纳成本分析// cost-analysis.ts — Flutter采纳成本量化分析 interface AdoptionCost { category: string; flutterCost: number; // Flutter的代价(人月) rnCost: number; // React Native的代价(人月) reason: string; } const adoptionCosts: AdoptionCost[] [ { category: 团队学习成本, flutterCost: 4.5, // 团队0人懂Dart需完整学习周期 rnCost: 0.5, // 团队已有ReactTypeScript基础 reason: Dart语言Flutter框架Widget体系的学习曲线, }, { category: 生态迁移成本, flutterCost: 3.0, // 微信小程序无Flutter支持 rnCost: 0.8, // RN生态成熟但小程序仍需Taro reason: 乘客端必须支持小程序Flutter无法覆盖, }, { category: 现有代码迁移, flutterCost: 6.0, // 全量重写Dart无法复用JS代码 rnCost: 2.0, // 业务逻辑层可复用纯JS/TS函数 reason: Flutter需要用Dart重写全部业务逻辑, }, { category: 原生模块维护, flutterCost: 1.5, // Flutter与原生交互更简单 rnCost: 3.5, // TurboModule需双平台实现 reason: Flutter的Platform Channel比TurboModule维护量低, }, { category: 长期招聘成本, flutterCost: 2.0, // Flutter开发者市场供给较少 rnCost: 1.0, // React开发者市场供给充足 reason: 国内Flutter开发者数量约为React开发者的1/5, }, ]; // 总成本对比 const totalFlutter adoptionCosts.reduce((sum, c) sum c.flutterCost, 0); const totalRN adoptionCosts.reduce((sum, c) sum c.rnCost, 0); // Flutter: 17.0人月, RN: 7.8人月 // 性能收益折算Flutter的渲染性能优势在司机端场景中 // 实际用户可感知的改善约为5%58→60FPS、35→12ms交互响应 // 但采纳成本差距为117%7.8→17.0人月 // ROI: Flutter的性能提升5% / 采纳成本增加117% 0.043 → 不值得Flutter 未采纳的核心原因采纳成本17 人月远超性能收益5% 可感知改善ROI 为 0.043——每投入 1 人月的额外成本仅获得 0.043 单位的可感知性能改善。这不是技术偏见是数据驱动的决策。四、Taro 在乘客端的实践4.1 多端编译与小程序适配乘客端的核心需求H5 微信小程序共享同一套代码。Taro 的多端编译能力直接满足这个需求。// taro-passenger/pages/trip/index.tsx — 乘客端行程页面Taro import { View, Text, Map, Button } from tarojs/components; import { usePullDownRefresh } from tarojs/taro; import Taro from tarojs/taro; import React, { useEffect, useState, useCallback } from react; import { tripService } from ../../services/trip; import ./index.scss; interface TripPageState { order: OrderInfo | null; driverLocation: GeoPoint | null; loading: boolean; error: string | null; } export default function TripPage() { const [state, setState] useStateTripPageState({ order: null, driverLocation: null, loading: true, error: null, }); // 加载行程数据H5和小程序共用同一套service层 const loadTripData useCallback(async () { setState((prev) ({ ...prev, loading: true, error: null })); try { const orderId Taro.getCurrentInstance().router?.params?.orderId; if (!orderId) { setState((prev) ({ ...prev, loading: false, error: 订单ID缺失 })); return; } const data await tripService.getTripDetail(orderId); setState({ order: data.order, driverLocation: data.driverLocation, loading: false, error: null, }); } catch (err) { setState((prev) ({ ...prev, loading: false, error: (err as Error).message, })); } }, []); useEffect(() { loadTripData(); }, [loadTripData]); // 下拉刷新小程序特有交互H5自动降级为按钮刷新 usePullDownRefresh(() { loadTripData().then(() Taro.stopPullDownRefresh()); }); // 查看司机位置小程序用原生Map组件H5用Web地图 const handleViewDriverLocation useCallback(() { if (!state.driverLocation) return; // Taro多端API小程序打开地图导航H5跳转到Web地图页面 if (process.env.TARO_ENV weapp) { Taro.openLocation({ latitude: state.driverLocation.latitude, longitude: state.driverLocation.longitude, name: 司机当前位置, scale: 15, }); } else { Taro.navigateTo({ url: /pages/map/index?lat${state.driverLocation.latitude}lng${state.driverLocation.longitude}, }); } }, [state.driverLocation]); // 取消订单 const handleCancelOrder useCallback(async () { if (!state.order) return; const { confirm } await Taro.showModal({ title: 确认取消, content: 确认取消订单 ${state.order.id}?, }); if (!confirm) return; try { const result await tripService.cancelOrder(state.order.id); if (result.success) { Taro.showToast({ title: 已取消, icon: success }); loadTripData(); // 刷新页面数据 } else { Taro.showToast({ title: result.reason ?? 取消失败, icon: error }); } } catch (err) { Taro.showToast({ title: 取消异常, icon: error }); } }, [state.order, loadTripData]); if (state.loading) { return View classNametrip-loading加载中.../View; } if (state.error) { return ( View classNametrip-error Text{state.error}/Text Button onClick{loadTripData}重新加载/Button /View ); } return ( View classNametrip-page View classNametrip-header Text classNametrip-order-id订单号: {state.order?.id}/Text Text classNametrip-status{state.order?.statusText}/Text /View {/* Taro Map组件小程序端渲染原生地图H5端渲染Web地图 */} {state.driverLocation ( Map classNametrip-map latitude{state.driverLocation.latitude} longitude{state.driverLocation.longitude} scale{15} markers{[ { latitude: state.driverLocation.latitude, longitude: state.driverLocation.longitude, title: 司机位置, iconPath: /assets/driver-marker.png, width: 30, height: 30, }, ]} / )} View classNametrip-info Text预估到达: {state.order?.estimatedArrival}分钟/Text Text费用: ¥{state.order?.price}/Text /View View classNametrip-actions Button onClick{handleViewDriverLocation}查看司机位置/Button Button onClick{handleCancelOrder}取消订单/Button /View /View ); }4.2 多端差异的处理策略// taro-passenger/utils/platform-adapter.ts — 多端适配层 class PlatformAdapter { // 地图导航不同平台调用不同API async openNavigation(destination: GeoPoint): Promisevoid { switch (process.env.TARO_ENV) { case weapp: // 微信小程序打开微信内置地图导航 Taro.openLocation({ latitude: destination.latitude, longitude: destination.longitude, name: 目的地, scale: 15, }); break; case h5: // H5跳转到Web地图页面 Taro.navigateTo({ url: /pages/map/index?lat${destination.latitude}lng${destination.longitude}, }); break; case alipay: // 支付宝小程序打开支付宝内置地图 my.openLocation({ latitude: destination.latitude, longitude: destination.longitude, name: 目的地, }); break; default: // 未知平台降级为文本展示坐标 Taro.showModal({ title: 目的地坐标, content: 纬度: ${destination.latitude}, 经度: ${destination.longitude}, showCancel: false, }); } } // 支付不同平台调用不同支付SDK async requestPayment(params: PaymentParams): PromisePaymentResult { switch (process.env.TARO_ENV) { case weapp: return Taro.requestWXPayment({ timeStamp: params.timeStamp, nonceStr: params.nonceStr, package: params.package, signType: MD5, paySign: params.paySign, }); case h5: // H5调用后端H5支付接口 const response await fetch(/api/pay/h5, { method: POST, body: JSON.stringify(params), }); return response.json(); case alipay: return my.tradePay({ tradeNO: params.tradeNo }); default: throw new Error(不支持的平台: ${process.env.TARO_ENV}); } } // 存储不同平台的本地存储API差异 setStorage(key: string, value: any): void { try { Taro.setStorageSync(key, JSON.stringify(value)); } catch (error) { console.error(存储写入失败: ${key}, error); } } getStorageT(key: string): T | null { try { const raw Taro.getStorageSync(key); return raw ? JSON.parse(raw) : null; } catch { return null; // 存储读取失败时返回null不阻断业务流程 } } }4.3 Taro 的性能代价与优化Taro 多端编译的性能代价小程序端接近原生性能但 H5 端的运行时框架引入额外开销。指标Taro 小程序端Taro H5端纯原生小程序首屏渲染380ms650ms320ms列表滚动56 FPS45 FPS60 FPS包体积85KB (runtime)120KB (runtimedom)0KB// taro-passenger/utils/performance-optimizer.ts — Taro性能优化 class TaroPerformanceOptimizer { // H5端性能优化减少运行时开销 optimizeForH5(): void { if (process.env.TARO_ENV ! h5) return; // 1. 路由预加载在当前页面空闲时预加载下一个页面的资源 Taro.preload({ url: /pages/trip/index, data: { orderId: preload }, }); // 2. 图片懒加载 // Taro的Image组件默认支持lazy-load小程序端 // H5端需要手动配置IntersectionObserver } // 列表虚拟化长列表场景必须启用虚拟滚动 getVirtualListConfig(): { itemHeight: number; overscanCount: number; threshold: number; } { return { itemHeight: 80, // 每行高度(px)必须固定值 overscanCount: 5, // 预渲染缓冲行数 threshold: 100, // 超过100条数据时启用虚拟滚动 }; } // 小程序分包策略主包≤2MB分包≤2MB getSubPackageConfig(): Recordstring, string[] { return { main: [pages/index/index, pages/home/index, pages/login/index], trip: [pages/trip/index, pages/map/index, pages/tracking/index], order: [pages/order/index, pages/history/index, pages/cancel/index], promotion: [pages/promo/index, pages/coupon/index], }; } }五、总结出行平台的跨端方案不是统一选一种而是按端分流、各取所长乘客端 → TaroH5 小程序多端共享代码Taro 的编译能力直接满足需求。采纳成本 0.5 人月团队已有 React 基础小程序端性能接近原生首屏 380msH5 端稍慢但可接受首屏 650ms。司机端 → React Native (Fabric)实时导航 WebSocket 推送Fabric 架构下地图帧率 58 FPS、交互响应 35ms、WebSocket 延迟 45ms满足司机端性能需求。采纳成本 2 人月复用业务逻辑层原生模块维护成本 3.5 人月/年。Flutter 未采纳性能优势 5%采纳成本增加 117%17 人月 vs 7.8 人月ROI 0.043——数据驱动的决策而非技术偏见。关键实践端分流选型乘客端生态优先小程序必须支持→ Taro司机端性能优先实时交互必须流畅→ RN管理后台不需要跨端 → 纯 Web。业务逻辑层共享三个端共享同一套纯 JS/TS 业务逻辑价格计算、订单状态管理、数据校验跨端方案只负责 UI 渲染层的差异适配。平台适配层隔离Taro 的process.env.TARO_ENV环境判断、RN 的 TurboModule 原生桥接——多端差异通过适配层隔离业务代码不直接依赖平台 API。性能实测驱动Flutter 的渲染优势在实测中确实存在60 FPS vs 58 FPS但在司机端场景中用户可感知差异仅 5%不足以支撑 117% 的采纳成本增幅。分包与虚拟化Taro 小程序分包策略主包≤2MB和 H5 长列表虚拟滚动是必做的性能优化不做则首屏和列表体验明显劣化。跨端方案的选型不是哪种技术更好的技术争论而是哪种方案的 ROI 更高的商业决策。出行平台的数据Taro 采纳 ROI 8.01 人月成本8 倍效率提升RN 采纳 ROI 3.52 人月成本7 倍效率提升Flutter 采纳 ROI 0.317 人月成本5% 性能提升。ROI 驱动选型数据驱动决策。

相关新闻

低代码平台的 AI 驆动数据建模:从业务实体识别到表单与列表的自动映射

低代码平台的 AI 驆动数据建模:从业务实体识别到表单与列表的自动映射

低代码平台的 AI 驆动数据建模:从业务实体识别到表单与列表的自动映射 一、低代码数据建模的痛点 出行平台运营后台每月新增 8-12 个管理页面:司机准入审核页、投诉处理页、优惠券配置页、区域运营统计页。每个页面的核心是数据模型——定义字段、约束、…

2026/10/19 6:10:12 阅读更多 →
C++哈希表实现:从闭散列到开散列,深入理解unordered_map底层原理

C++哈希表实现:从闭散列到开散列,深入理解unordered_map底层原理

1. 项目概述:从容器到内核的探索在C的日常开发中,std::unordered_map和std::unordered_set是我们处理快速查找、去重问题的利器。它们背后的核心数据结构——哈希表,其性能直接决定了我们程序的效率。很多朋友会用,但对其内部实现…

2026/10/15 21:13:45 阅读更多 →
HarmonyOS应用开发实战:萌宠日记 - 时间轴 UI 视觉设计模式

HarmonyOS应用开发实战:萌宠日记 - 时间轴 UI 视觉设计模式

HarmonyOS应用开发实战:萌宠日记 - 时间轴 UI 视觉设计模式 前言 时间轴(Timeline) 是一种经典的 垂直时间线 UI 模式,用于按时间顺序展示事件。在 萌宠日记 的 GrowthTimelinePage 中,我们使用时间轴展示宠物的 成长…

2026/10/18 7:50:57 阅读更多 →

最新新闻

artcraft:数字生成与手工工艺融合的创作流程

artcraft:数字生成与手工工艺融合的创作流程

artcraft 这个词,是我在一个晚上盯着满屏的噪点图时冒出来的。屏幕里是算法刚刚生成的一堆“海浪纹理”,桌角是一块刨好的椴木板,两边分明是两个世界,但我隐约觉得它们应该能变成同一样东西。后来这个项目做的所有事,就…

2026/10/19 6:09:41 阅读更多 →
Vue 3 核心原理详解:响应式、虚拟DOM与编译优化

Vue 3 核心原理详解:响应式、虚拟DOM与编译优化

1. Vue 3 到底改了什么:从设计目标倒推原理1.1 为什么是重写而不是小修小补很多朋友第一次接触 Vue 3 时,第一反应是“Vue 2 我还没学明白呢,怎么又开始改”。真去源码里看一圈之后,会发现 Vue 3 不是 Vue 2 的复制粘贴&#xff0…

2026/10/19 6:09:41 阅读更多 →
EF6 SaveChanges验证失败排查:EntityValidationErrors明细与根因定位

EF6 SaveChanges验证失败排查:EntityValidationErrors明细与根因定位

接手 EF 项目的头两周,我就在日志里撞上了这句让人一头雾水的英文:Validation failed for one or more entities. See EntityValidationErrors property for more details.翻译过来是"一个或多个实体的验证失败,更多细节见 EntityValida…

2026/10/19 6:09:41 阅读更多 →
考研复试18天复盘:从知识输入到输出表达的关键转变

考研复试18天复盘:从知识输入到输出表达的关键转变

今天早上一打开笔记软件,就看到标题栏里躺着“Day18”这个数字。说实话,写这篇“总结1”之前,我原本打算轻描淡写地说一句“复习整体顺利”,可真把前18天的日程、完成情况和模拟记录翻开之后才发现,实际有效复习时间大…

2026/10/19 6:09:41 阅读更多 →
矩阵力扣复习

矩阵力扣复习

73. 矩阵置零 - 力扣(LeetCode) class Solution:def setZeroes(self, matrix: List[List[int]]) -> None:m, n len(matrix), len(matrix[0])# 先单独记录:第一行 / 第一列本身是否含 0(它们即将被当作标记板,会被…

2026/10/19 6:09:41 阅读更多 →
BERT微调实战:IMDB影评情感二分类源码全流程解析与避坑指南

BERT微调实战:IMDB影评情感二分类源码全流程解析与避坑指南

简介:基于BERT模型的情感分析项目,是一套面向自然语言处理初学者与算法工程师的Python源码包,聚焦IMDB影评正面/负面情感二分类,帮助理解BERT预训练模型微调、特征抽取及分类器设计等关键环节。资源共5个文件,其中4个P…

2026/10/19 6:08:40 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →