整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Flutter Web在美团外卖的实践

Flutter Web在美团外卖的实践

多形态业务场景下,如何保障多端体验的一致性,是前端技术领域一个比较受关注的方向。美团外卖前端技术团队基于 Flutter Web 探索跨端(App\PC\H5)的解决方案,真正实现“Write Once & Run AnyWhere”。本文系该团队的实践经验总结,希望能对大家有所帮助或者启发。

一、背景

1.1 业务背景

美团外卖商家端业务形态

美团外卖商家端业务围绕数百万商家,在 PC 和 App 上分别提供了交易履约、运营、广告、营销等一系列功能,且经常有外投 H5 的场景(如外卖学院、商家社区、营销活动等)。在这种多形态的业务场景下,如何保障多端体验的一致性,以及如何提升多端迭代的效率,一直是商家端产研关注的重点。

1.1.1 保障多端体验一致性

由于端能力的不同,导致了业务在 App 和 Web 上存在较大的表现差异,例如:App 上自带动画转场,而在 Web 中的实现成本却较高,往往也就降级舍弃了这部分功能。此外,即使我们可利用公司内部的 Roo、MTDUI 等多端 UI 组件库来尽量抹平各端的 UI 差异,但由于组件库在各端的实现不尽相同,很难做到完美的一致性体验。

1.1.2 提升多端迭代效率

由于各端技术体系的不同,涉及多端的需求往往需要不同的开发、测试团队各自完成开发、联调、测试、上线等流程,占用资源巨大,在各团队不可并行支持的情况下,甚至可能导致整个业务交付周期被拉长。虽然 React Native、Flutter 等跨平台方案解决了一部分复用的问题,但显然在商家端业务场景下是远远不够的,我们的目标是要达到全平台(Android、iOS、PC、H5)复用,最大化地提升多端的迭代效率。

1.2 技术背景

1.2.1 Flutter 在美团外卖商家端的储备

MTFlutter 是美团外卖搭建起的公司级 Flutter 研发生态,它的架构图如下图所示:

MTFlutter 架构图

如图所示,MTFlutter 已涵盖研发、调试、测试、发布、线上运维及工程管理整套闭环,同时落地了动态化解决方案,支撑了公司多个业务发展。在大前端融合的趋势下,美团外卖商家端持续在探索更优的多端复用方案,通过 MTFlutter 生态的建设,目前 Flutter 技术栈已覆盖商家端 App 中 90%以上的业务,同时具备 Flutter 开发能力的同学也达到 90% 以上。因此,在有足够技术“储备”的前提下,我们能够基于 Flutter 做全平台(Android、iOS、PC、H5)复用的探索。

1.2.2 Flutter Web 的支持

2018 年 Google 首次公开 Flutter Web Beta 版,旨在进一步实现一份代码、多端运行的愿景。目前,Flutter Web 已被正式合入 Master,期间经过无数工程师的努力,Flutter Web 已能提供与 Flutter Natvie 较统一的交互行为和视觉体验。

Flutter Native VS Flutter Web

如上图可知,Flutter Web 与 Flutter Native 的整体架构相似,二者共用 Framework 层(绿色部分),提供了包括动画、手势、基础 Widget 类,以及大部分应用所需的 Material/Cupertino 主题 Widget 集合。区别在于:Flutter Web 重写了 dart:ui 层(黄色部分),利用 DOM、Canvas 对齐了 Flutter Native 的 UI 渲染能力,使得 Flutter 编写的 UI 能够在现代浏览器上正常展示。

此外,得益于 dart2js 这个早已成熟的工具,Dart 逻辑能够很容易的转换为 JavaScript,进而在 Web 中被正常运行。

二、面临的挑战

综上所述,我们选择基于 Flutter Web 探索跨端(App\PC\H5)解决方案,真正实现“Write Once & Run AnyWhere”。当然,面临挑战也是巨大的,主要体现在 Flutter 和 MTFlutter 现阶段对 Web 支持还不是很充足。

2.1 Flutter Web 现状

Google 官方目前对 Flutter Web 的工作主要还集中在 dart:ui(Web)的对齐,工程化和性能相关的事项做的还比较少,例如:

  • Flutter Web 构建产物较简陋,只是简单的输出 main.dart.js(1.1M,未 Gzip) 和 图片等静态资源,缺少 JS 拆包、文件 Hash、资源上传 CDN 等优化工作,极大影响了页面的加载性能。
  • 由于 Flutter Web 自身实现了一套页面滚动机制,页面滚动过程中,会频繁计算位置信息,引起滚动区域内容被重新创建,最终导致页面滚动性能较差。

2.2 MTFlutter 现状

虽然 MTFlutter 做了诸多 Flutter Native 层面的定制与优化,但在 Flutter Web 上的建设才刚起步,具体表现在:

  • MTFlutter 现有的基础依赖如:Request(请求封装)、Router(路由)、埋点、容器桥、前端监控,尚未支持在 Web 中的实现。
  • MTFlutter 已实现了完整的 Flutter Module 的打包发布流程,但并不支持 Web 的构建与部署。

三、整体设计

MTFlutter 架构图

上图为 MTFlutter + Web 架构图,由图可知 Flutter Web 页面要满足投产要求,还有大量的工作(上图黄色部分所示),主要包括:

  • 扩展基础依赖(如:Request、Router、埋点等)在 Web 侧的支持。
  • 完善工程化建设,例如:静态资源优化、构建与部署自动化。
  • 深入滚动性能与页面加载性能优化,使得 Flutter Web 能够满足基本的投产要求。

四、详细设计

4.1 基础依赖建设

企业级应用的基础开发依赖 (如:请求库、路由库、埋点库等),要重新在 Flutter 中用 Dart 搭建一套,时间成本、兼容性、风险等都是不可控的。而 MTFlutter 是基于原有 Native 基础依赖开发的 Plugin,因此并不支持 Web 端。此章节将展开介绍如何丝滑无感地扩展 MTFlutter 基础依赖在 Web 端的实现。

4.1.1 Flutter Package 分平台编程

在 Flutter 中通过使用 Package 可以创建易于共享的模块化代码。官方强烈推荐使用 Package 形式管理各种工具方法。在官方定义中 Package 包含以下两种类别:

  1. Dart Package:用 Dart 编写的常规 Package,其中一些可能包含依赖于 Flutter 框架的特定功能,其使用范围仅限于 Flutter,例如 path。
  2. Plugin Package:用 Dart 编写 API 多个平台各自实现的特殊 Dart Package。Plugin Package 可以为 Android(使用 Kotlin 或 Java)、iOS(使用 Swift 或 Objective-C)、Web、macOS、Windows 或 Linux 或其任意组合编写插件包。

下面分别对这两种类型 Package 中如何分平台编程进行介绍。

(1) Dart Package

Dart Package 是纯 Dart 编写,因此大部分代码均可由 dart2js 直接编译出 Web 平台可运行的代码,但某些涉及 Native 能力的库 (如 dart:io)是无法被转译的,因此需要有对平台进行兼容的方法,下面介绍两种在 Dart Package 中分平台编程的方案。

代码级别分平台

针对代码级别的分平台,我们可以借助 Flutter SDK 提供的一个常量 kIsWeb。使用方法如下:

查看源码可知,kIsWeb 之所以能被用于判断 Web 平台,是利用了 JavaScript 不支持整型的特征,在 Web 环境下,Dart 的 double 和 int 由相同类型的对象支持,浮点数 "0.0" 等于整数 "0",对于在 AOT 或 VM 上运行的 Dart 代码却并非如此。

import 'package:flutter/foundation.dart';
if (kIsWeb) {
  print('Web 端')
} else {
  print('其他端');
}

文件级别分平台

针对文件级别分平台,我们利用条件导入导出,其中条件导出具体用法如下:

// tool.dart
export 'src/tool_native.dart' // 兜底导出,即没有命中条件时导出的文件
  if (dart.library.html) 'src/tool_web.dart'; // web 端导出的文件,该文件中可以使用 dart:html,也可以通过判断 dart.library.js 导出 Web 端文件。
// 引入 tool.dart
import 'package:tool/tool.dart';
void main() {
  print('import tool');
}

条件导入和条件导出类似,仅需将 export 改为 import 即可。在业务开发中这也是一种非常实用的分平台编程方法。

(2) Plugin Package

Plugin Package (下文简称为 Plugin) 在 Android 和 iOS 平台都是通过 MethodChannel 实现在 UI 层和 Platform 层传递消息从而达到特定平台支持的,官方文档中也全方位介绍了在 Android 和 iOS 平台的具体实现方法及例子,Web 平台的实现却介绍的较少。总结起来,Web 平台和 Native 平台实现方式的不同主要集中在下面两点。

首先,Web Plugin 推荐的方式不是以其平台特有的 JS 语言实现,而是通过 Dart Library 或 Package 实现,对于已有现成可用的 JS SDK 或需要大量使用 JS 实现功能的情况下,官方提供了 package:js 包调用 Javascript,从而实现与 Javascript 的交互。

其次,Web Plugin 不是通过注册 MethodChannel 传递消息的,Flutter 内部可直接调用通过官方指定形式 (Federated Plugin) 编写的 Flutter Web Plugin 类。

下图完整的展示了一个 Plugin 的整体架构:

4.1.2 基础依赖建设

整体来讲,MTFlutter 基础依赖都是使用 Plugin 的形式开发维护的。为处理依赖中的公共逻辑,提高 Plugin 的可扩展性,MTFlutter Plugin 在 Flutter Plugin 架构(各平台原生实现层和 Plugin Interface 层)之上又增加了公共逻辑处理层,最终暴露给用户是 Plugin API 层提供的接口。MTFlutter Plugin 架构图如下:

MTFlutter Plugin 架构图

在细节实现上,由于项目中各种依赖的类型之间存在着差异,因此在依赖处理上也略有不同,下面介绍拥有不同特点的依赖所对应解决方案。

(1)各平台实现能在 Web 侧对齐的场景,如埋点库

埋点库无论在 Native 端还是在 Web 端都是使用公司统一提供的 SDK,在 API 设计上具有天然的一致性,因此我们完全有能力在 Plugin Interface 层对齐所有接口,上层业务逻辑只需按需做些兼容处理即可。埋点库 Web 端扩展的整体设计思路如下:

  1. 在业务项目的 web/index.html 文件中直接引入 Script 脚本并且进行初始化 (注意:引入 Script 的位置,需要放在 main.dart.js 前面)。
  2. 借助 package:js 库调用埋点 JS SDK,对齐 Flutter 埋点库的 API ,实现 Flutter Plugin 的 Web 端支持,详细架构图如下图所示:

(2)各平台实现在 Web 侧无法对齐的场景,如路由库

MTFlutter 路由库是 Native 底层维护的一套全新的路由体系,依靠原生支持提供了强大的定制化功能,而在 Web 端无法这些无法在各平台原生实现层达到 100% 支持。由于 MTFlutter Plugin 最终暴露的是 Plugin API,因此我们选择直接对齐 Plugin API 实现路由库在 Web 端的支持(借助 Flutter Navigator、dart:html 用纯 Dart 语言完成了扩展),详细架构如下图所示:

路由库架构图

(3)Web 端需要通过大量 JS 实现功能的依赖库,如请求库

由于在现有的 Web 请求中统一封装着大量的业务处理逻辑(如拦截器、异常上报等),如果用 Dart 重新实现一遍,成本还是较高的。想复用原有基于 Axios( JS 请求库) 封装的请求库就相当于让 Plugin 的 Web 平台实现使用 JS 语言。Dart 和 JS 交互是通过 package:js 进行接口调用,因此我们在公共逻辑处理层用 Dart 对齐了相应的 API,详细架构图如下图所示:

请求库架构图

4.2 性能优化

常规的 Web 项目中,为了保证页面有更好的加载和渲染性能,在静态资源文件的处理方面,我们需要做很多的工作,例如:资源文件 Hash 化、CDN 化、按需加载处理等,这些可以通过 Webpack、Rollup 等构建工具进行预处理。但在 Flutter Web 中,这些预处理的操作目前官方还不支持,原因是 Flutter 暴露给我们的命令只有一个 flutter build web,导致我们无法直接进行更细粒度的个性化定制。如果想要让 Flutter Web 达到企业级应用的标准,我们需要更深层次的探索 Flutter SDK 的运行原理。下面我们列出目前遇到的性能问题及其解决方案。

4.2.1 目前存在的性能问题

Google 官方对 Flutter Web 性能优化所做的事项还比较少,编译输出的页面存在较大的性能问题,主要体现在以下两方面:

  1. 首屏渲染时间长。即使使用了 FutureBuilder 把业务代码拆分成 xxx.part.js 之后,main.dart.js 体积依然维持在 1.1M。单一文件加载、解析时间过长,且静态资源缺少 CDN 化的支持,势必会影响首屏的渲染时间。
  2. 滚动性能较差。 Flutter Web 自身实现了一套页面滚动机制,在页面滚动过程中,会频繁的创建 Canvas,最终导致滚动性能问题,甚至引起页面 Crash。

通过下图对浏览器网络监控情况的展示,可以清晰的反映出以上问题:



为了解决上述的性能问题,我们探索了 Flutter SDK 编译过程,总结出从 Flutter 业务代码到 Web 产物的整体流程,详细流程如下图所示:

从流程中我们可以看到,Flutter 在 Web 端目前只支持 Dart-->JS 的转换,以及 UI 层的对齐,在工程化和性能优化方面做的工作并不多。

因此,我们必须解决以上的性能问题,才能保证我们的业务可以正常的交付。通过对编译流程的仔细分析与梳理,我们在 AOT 产物生成之前对 Flutter SDK 进行定制,分别进行加载性能优化内存性能优化,下面分别介绍这两部分的内容。

Flutter SDK 进行定制后的流程

4.2.2 加载性能优化

运行 flutter build web 命令之后,我们得到的主要静态资源有:主文件 main.dart.js(1.1M),各页面的业务代码 xxx.part.js(使用 FutureBuilder 后)、图片文件。直接应用这些资源到项目中,会遇到以下问题:

  1. 功能无法及时更新:浏览器对同名文件的缓存,可能导致程序代码不被及时更新或者出现执行错乱。
  2. 首屏渲染性能差:main.dart.js 文件过大,单一文件加载、解析时间过长,势必会影响首屏的渲染时间。
  3. 无法使用 CDN:Flutter 仅支持相对路径的加载方式,无法使用当前域名以外的 CDN 域名,导致无法享受 CDN 带来的优势。

为此,在加载部分我们对 Flutter SDK 增加了如下三方面的优化,以达到线上运行的标准,优化步骤如下图所示:

优化步骤

资源文件 Hash 化

除了 web/index.html 文件之外,我们要对所有的引用到文件进行 Hash 化。对 build_system/web.dart 的修改按以下步骤进行:

  1. 遍历产物目录,并建立 ResourceMap。
  2. 分别计算每个文件的 Hash 值。
  3. 为新文件命名为 name-[hash].xxx。
  4. 修改新文件名在对应文件中的引用关系。

大文件分片

Flutter Web 编译之后会生成 main.dart.js 这一主文件,体积为1.1M( Gzip 之后约 400K ),这给页面的加载性能带来很大的影响。为此,我们对代码进行分片,借助浏览器对多文件并行加载的特性,可以有效提升页面的加载性能。

具体实施步骤是:将 main.dart.js 在 Dart 侧拆分成多份纯文本文件,前端通过 XHR 的方式并行加载并按顺序拼接成 Javascript 代码置于 <script> 标签中,从而实现分片文件的并行加载。

Hash化以及分片之后,静态资源的引用关系

资源文件 CDN 化

由于 Flutter Web 资源引用机制的不同,即使在资源文件 Hash 化的过程中,把文件的相对路径替换成带 CDN 域名的绝对路径,也无法实现 CDN 资源的加载。同时本地测试发现图片和 Javascript 资源的加载逻辑还不尽相同,为此针对各自的加载逻辑要分别进行优化。

  • 图片处理:经过对源码的大量阅读及梳理,我们发现图片请求的 URL 首先会读取 meta 标签中 assetBase 值进行 URL 路径拼接,根据拼接好的 URL 来获取资源。目前,在项目 web/index.html 模板文件中并没有 meta 标签,于是就会根据相对路径进行请求。解决方案是在编译过程中,根据请求环境增加 meta 标签并把 content 设置为 CDN 路径。
  • JavaScript 处理:为了解决图片资源文件的加载问题,我们虽然增加了 assetBasemeta 标签,但发现 xxx.part.js 文件依然使用当前域名进行加载,可见 Javascript 资源的加载和图片资源加载的逻辑不尽相同。对 main.dart.js 源码分析,我们发现请求 xxx.part.js 的域名取决于包含 main.dart.js 内容的 Script 标签的 src 属性。通过对 js_helper.dart 的动态编译,我们把读取 src 属性修改为读取 window.assetBase 这一全局变量(meta标签中 assetBase 值加工后的变量)来实现 xxx.part.js 文件的 CDN 加载。

4.2.3 滚动性能优化

当页面出现可滚动区域时,每次页面滚动会创建大量的 Canvas。使用 Safari 的 Canvas 分析工具,我们发现问题的根本原因是页面滚动的过程中,Flutter 会频繁的创建滚动区域的 Canvas,每次创建的 Canvas 内存都在10~70M 不等,滚动的内容越多,内存的占用就会越大,这样滚动几帧之后,内存的占用就会超过浏览器的阈值。

Safari 图形工具中展示 Canvas 的占用

Flutter 对 Canvas 的管理有一个 ReusablePool 的概念,在初始过程中会创建一定的数量的 Canvas,页面交互过程中没有变化的部分,会优先使用 pool 中已经缓存过的 Canvas 以便能够节省内存。由于 Flutter Web 自身实现了一套页面滚动机制,页面滚动过程中,会频繁计算位置信息,引起滚动区域内容被重新创建,这就是为什么每次滚动都会创建 Canvas 的原因。

我们设计的解决方案是:修改 FlutterSDK,在滚动的过程中定义一个阈值,当滚动的高度在阈值范围内,我们就会把当前的 Canvas 缓存起来。这样选择性的创建和销毁 Canvas 可以有效的缓解内存压力,从而提升页面滚动性能。

优化之后浏览器创建和销毁 Canvas 的过程

4.3 构建与部署

4.3.1 Docker 镜像定制

由于 MTFlutter Web 环境安装步骤较固定,且整个安装过程耗时较长 ( > 80s ) 。因此将其定制为 Docker 镜像并集成至 Talos,Flutter Web 编译阶段便能免去安装流程,有效提升构建效率。Docker 镜像定制和发布的详细流程见官方文档,本文不再赘述。其中用于定制 Flutter Web 镜像的 Dockerfile 文件如下:

FROM $BaseImage \# 继承基础镜像
RUN apt-get update
RUN apt-get install rubygems -y
RUN gem install flutter-cli
RUN flutter-cli install
ENV PATH="/$User/.flutter_sdk/bin:${PATH}"
ENV PUB\_HOSTED\_URL="https://xxx.com" \# 私有pub服务
ENV FLUTTER\_STORAGE\_BASE_URL="https://storage.flutter-io.cn"
RUN ~/.flutter_sdk/bin/flutter config --enable-web

4.3.2 持续交付与部署

为了实现持续交付与部署,我们建立起了 Flutter Web 在 Talos(美团内部前端持续交付解决方案) 中的发布流水线:

Talos 发布流水线

可以看到,流水线中已经免去了 MTFlutter Web 环境的安装流程,现有流水线中重要节点介绍如下:

  • Flutter-Web-Build 利用 Docker 内置的 MTFlutter 进行 Web 编译。
  • Flutter-Web-Publish 负责将编译产物上传美团资源存储服务器。

五、成果展示

5.1 效果展示

我们在美团外卖商家学院(一个以文章、视频等形式帮助商家学习外卖运营知识、了解行业发展和平台策略的平台,它有很强的传播属性,具有外部投放的场景)率先落地了 Flutter Web,现以商家学院视频内容页为例,对比 Flutter Native 和 Flutter Web 的展现效果:


Flutter Web

可以看出,两者的交互、视觉体验是高度一致的,既保证了业务在 App 内接近 Native 的体验,又极大提高了 Web 与 Flutter Native 的体验一致性。

5.2 页面加载性能

如前文所述,我们实施了一系列针对 Flutter Web 的资源优化手段,使得页面加载性能有较大提升,其中页面完全加载时间大致由 1300ms (TP50) 降到了 580ms(TP50),更多的性能指标数据见下图:

某7日性能趋势图

可以看到 Flutter Web 与现有 Web 项目性能指标数据差距已不大,可满足日常业务要求。但加载性能数据仍有较大的优化空间,我们会持续对其进行探索。

5.3 滚动性能

针对滚动优化,我们通过修改 Flutter SDK,使得 Canvas 在页面滚动时无需重复创建,而是被缓存起来。这样大大节省了内存的开销(优化后页面内存占用稳定为 100M 左右,与常规 Web 页面无异),同时在一定程度上提升了滚动性能。以商家学院文章内容页为例,对比优化前后滚动 FPS :

优化前 FPS

优化后 FPS

可以看到,Flutter Web 页面滚动性能已得到较大提升,足以应对大部分业务场景。但由于 Flutter Web 页面滚动过程中会频繁进行位置信息的计算,在复杂的业务场景(如页面存在大量动画) 仍然会暴露出一定的问题。因此对滚动性能的进一步优化也会是我们未来的工作重心。

5.4 业务迭代效率

基于团队对 Flutter Web 工程化能力的建设和 Flutter 良好的跨平台特性,Flutter Web 在美团外卖商家学院改版需求的落地,大大提升了迭代效率,估算人效提升 40% 以上,计算公式为:

其中 E 代表人效提升,Ci 指的是兼容和适配所耗费的时间,Np 表示业务跨端数量,目前美团外卖商家学院在 Native 和 H5 两端完成了复用,后续在 PC 侧需求的对齐中,效率提升数值会被放大,预计人效提升达 60% 以上。同时我们将在更多的业务中进行推广与应用,提升整体业务的迭代效率。

六、总结与展望

综上所述,美团外卖商家端多元的业务形态和足够的技术“储备”,使得基于 Flutter 实现多端复用成为了可能。而 Flutter Web 在美团外卖商家学院业务中也取得了阶段性的成果,实现了 App、H5 侧的体验一致性,为后续推动更多业务线实现 App-Web 一体化打下了坚实的基础。

可以预见的是,基于 Flutter Web 实现的多端复用,势必会有效缩短项目交付周期。但由于我们对页面加载性能、滚动性能做的仍不够完美,不足以应对更加复杂的业务场景,因此我们依然还有许多工作:

  • 页面滚动性能优化: 由于 Flutter 与 Web 的布局差异,使得 dart:ui ( Web ) 也受 Flutter Native 的布局约束,如何打破这样的约束,是解决滚动性能问题的关键。
  • 页面加载性能优化: 当前的页面加载性能仍有较大优化空间,需要对 Flutter 进行编译干预与优化(如按需分离 main.dart.js),减小资源包大小,有效提升页面加载性能。
  • Flutter Web 基建:完善并优化开发、调试、编译、构建、部署链路,使得新老项目能快速接入 Flutter Web。
  • Flutter Web 在 PC 侧的复用:与 UED 团队共同制订 PC 与 App 适配规范,同时基于 Dart2js 和 dart:ui (Web)的强大能力,实现逻辑的抽象,完成组件、模块的适配,达到提效最大化;
  • 跟进 Flutter 官方动向:Flutter 2.0 的发布,稳定了对 Web 的支持,同时默认采用 Canvaskit 编译模式,此模式下对页面滚动性能有较大提升。但由于 canvaskit.wasm 文件过于庞大(2.5M),降低了加载性能,因此目前仍不建议在 Web 侧直接使用 Canvaskit。不过官方承诺会在 2021 年对性能进行整体优化,还是值得期待的,我们也将保持跟进和沟通。

我们会持续基于 Flutter Web 做更多的探索和尝试。如果您对 Flutter Web 也感兴趣,欢迎大家在文末评论区留言或者给出建议,非常感谢。

版权声明

本文系美团技术团队出品,著作权归属美团。欢迎出于分享和交流等非商业目的转载或使用本文内容,敬请注明“内容转载自美团技术团队”。本文未经许可,不得进行商业性转载或者使用。任何商用行为,请发送邮件至tech@meituan.com申请授权。

去3年,当我们谈论疫情的同时,有一个话题始终绕不开:

经济。

没有人想感染病毒,但问题是,病毒突起,不得不防。而疫情防控使得一些社会经济活动暂停,势必会对经济造成影响。两难之间只能不断找寻政策最佳发力点。

过去3年,中国经济不容易,每一个中国人都不容易,有不同的困惑与担忧也自然难免。

从这三个维度出发,能看清明年的经济形势。

不少人都说,大环境会影响个体的发展。同样,中国经济,也受制于大环境。

2022年,全球经济怎么样?

通胀处于几十年来最高水平;

增长处于自1970年衰退后复苏以来的最严重下滑;

全球消费者信心下降幅度远超前几次全球经济衰退前的降幅。

即便已经如此,但最糟糕的情况还未到来——国际货币基金组织(IMF)发出警告,很多人将在2023年感受到经济衰退。言下之意,2022年,只是经济衰退的边缘,2023年,有可能才是经济衰退的开始。

全球更严峻的情况,可能还在后面。

中国出口行业,已经感受到了寒气。最新的数据显示,11月我国出口同比下降8.7%。

大家都知道,在过去几年里,中国的出口“一枝独秀”,对整个经济大盘起到了非常难得的支撑作用。但从最新的数据来看,出口也开始出现了比较大的隐忧。

大环境不景气的影响,会直接体现在今年中国国内生产总值(GDP)的增速上。

但实际上,回过头看过去,中国一路发展过来,周围的大环境本就不都是顺风顺水。

国际货币基金组织的官方报告将人均GDP下降的程度视为衡量世界经济衰退的指标,这是2008年以来世界人均GDP的走势图:

可以发现,2008年后,世界经济有过三次明显的衰退期。最近的一次,就是新冠肺炎疫情暴发后。我们,也正在亲身经历着。

从图上也可以看出,此次疫情引发的衰退,还没有超过此前两次衰退的程度。

2008年,世界各国平均通胀率上升至10年来的新高。世界GDP增长率也从2007年的4.5%变成了2009年的-1.3%。

更重要的是,这场由美国引发、蔓延全球的经济危机让中国人明白了防范金融风险的重要性。

2014年的衰退,同样严重——2014年到2016年,世界GDP增长率出现下滑:

||2014年世界GDP增长率为3.1%;

2015年世界GDP增长率为3.1%;

2016年世界GDP增长率为2.8%。

与此同时,中国经济仍稳住了自己的节奏,可以看一组数据:

2013年至2021年,我国国内生产总值(GDP)年均增长6.6%,高于同期世界2.6%和发展中经济体3.7%的平均增长水平。

这期间,中国人均GDP从6000多美元上升至超过12000美元,世界排名提升了几十名。

大环境时有波动,但是我们都闯过来了,而且是以可控的较小代价。

让我们来算笔账,会更加直观:

2013年,全球GDP总量为77.61万亿美元,2021年,全球GDP总量为96.1万亿美元。近10年间,全球GDP总量增长了18.49万亿美元。

这18.49万亿美元中,中国增长了8.16万亿美元,占比44%。

其实,一路走来,我们周遭的惊涛骇浪从未缺席过。中国勇于开顶风船,善于在恶劣的环境中化危机为机遇。但风险与挑战,一波接着一波,一浪高过一浪。

2018年,美国对中国发起贸易战。

贸易战一开始,和今天一样,不少人都对中国经济的前景产生担忧,极个别人甚至说出“现在向美国投降是代价最小的”论调。

此后,美国政府鼓吹“脱钩”“断链”,在各个层面围堵中国。

现在,四年过去了。结果如何,大家心里都清楚:

中美贸易额不降反增,中美双边货物贸易总额由2018年的6335.2亿美元上升到2021年的7556.45亿美元。

中国与美国发展差距不断缩小,GDP总量差值由2018年的6.69万亿美元,缩小到2021年的5.26万亿美元。

就在不久前,世界贸易组织(WTO)发布报告,裁定2018年美国对进口钢铁和铝产品加征关税的措施违反了世贸组织相关规定。这意味着,中美贸易战,我们不仅赢于力,更赢于理。

所以,无论是全球经济发展过程中的阶段性、周期性的问题,还是由某些国家想要发起的逆全球化的趋势,我们都经历过,现在回头看,我们让很多人的唱衰不断破产。

眼下,大家对于困难的感受更为真切,对于复苏的疑问更多,也很正常——环境势必对我们有影响。

但环境,并不决定我们的去留,行动的主动权,在我们手里。

还记不记得这张图:

这是2020年,中国经济的折线图。这样的反弹,我们刚刚经历过。

在中国疫情防控措施优化后,美国投行摩根大通上调了中国明年的经济增长幅度,上调原因是,中国经济复苏的大门已经打开。与此同时,高盛、普华永道等机构都表示了对2023年中国经济的看好。

刚刚闭幕的中央经济工作会议所传递出的信号也更加强烈。这两天,中央财经委员会办公室分管日常工作的副主任韩文秀给出了更加明确的判断:综合研判,明年世界经济增速可能会明显下滑,而我国经济可能会总体回升,从而形成一个独立的向上运行的轨迹。

当然,过去的经验模板无法原封不动地套用到现在。

特别是我们在谈论中国经济预期这样宏大的话题时,对一些现实正在发生的具体问题同样要给出答案,看中国经济,同样要关照当下。

比如说,前不久的快递运力问题成为大家关注的焦点,不少人就发出疑问,快递都送不了,中国经济真的能复苏吗?

但让大家没想到的是,短短几天,运力不足的问题就得到了缓解。

原因很简单,快递运力不足,只是人手不够,是“没米下锅”,运力调度也只是技术问题,而基础设施等硬件的那个“锅”,我们一直在提前布局不断完善。随着运力补充,这个问题也就不再困扰大家。

快递小哥的背后,连接着互联网、物联网、云计算、大数据、5G、智慧物流等。这些词,除了体现在“江浙沪包邮”的日常生活,也在深刻改变着中国经济的格局。

△你可能想不到,每当你点一次外卖,会牵动至少106个产业

问题快速解决是过去5年、10年甚至十几年间,这些技术在中国不同的区域落地生根的结果。幅员辽阔的中国给这些技术提供了相当丰富和充足的应用场景,使得它们能够以全球其他地区难以企及的速度不断地运行、升级、优化。

这反映的是中国发展的纵深感。随着疫情防控政策的调整变化,国内不同省份、不同城市的放开节奏是梯次的、渐进的。也就是说,供应链的韧性能够让我们高效调动积累的资源去解决一些焦点问题,只要拉开节奏和间隙,这样集中力量解决问题的方式也将使得我们更快地走向复苏。

这是中国供应链的韧性,这种韧性,也在给中国产业复苏,提供很强的支撑力。

最近,很多人都关注到了多个省份包机出海的事情。

江苏有一家企业去了南非。在南非,这家企业考察了当地的矿山、仓库和港口,最终做出了积极布局南非市场的决定,签署了订单。

企业出海拓展市场,肯定要解决要素跨越物理空间移动的问题,基础设施的联通和供应链就至关重要。

值得一提的是,这家企业在多年前就考察过南非市场。显然,那时候深入南非的时机还没有那么成熟,尤其是基础设施的联通今非昔比——这家企业参观的南非德班港,是金砖国家新开发银行参与改造的项目。

过去这些年,有很多像南非这样的国家,在共建“一带一路”的过程中,不仅改善了自身的基础设施,赢得了更多的发展机遇。在与中国企业的交往过程中,彼此加深了解,拓展了双方的发展空间。

企业,在拓展着各自的半径。半径的延伸,就是新的机会。

通过对公开数据的挖掘,我们发现,在“新十条”发布后,有至少23个省市出台了支持企业境外拓展市场的政策。

要看到,支撑经济发展的基础条件并没有改变,一个强大的供应网络一直都在,当产业活力亟待重新激发的时候,中国经济也将迸发出强大的动力。

几天前,中央经济工作会议召开,为2023年的经济发展定调。

会议闭幕后,很多解读和分析纷纷出炉,讨论明年中国经济“怎么干”的问题。其中关注的一个焦点是扩大国内需求。因为五项重点工作任务,第一项就是着力扩大国内需求,同时提到要把恢复和扩大消费摆在优先位置。

很多人看到后感到不理解,现在疫情的高峰还没到来,很多人都不愿意出门消费。恢复和扩大消费摆在优先位置,可行吗?靠刺激消费来扩大国内需求,靠谱吗?

不知道各位有没有注意到另一句话:

大力提振市场信心,把实施扩大内需战略同深化供给侧结构性改革有机结合起来。

供给侧结构性改革,这个词,对于跟踪关注中国经济的人来说肯定不陌生。供给侧结构性改革的核心在于全要素生产率,也就是要素投入转化成产出的总体效率。我们要以供给侧结构性改革为主线,推动经济发展质量变革、效率变革、动力变革,才能不断增强我国经济创新力和竞争力。

可见,与深化供给侧结构性改革相结合的扩大内需,并不是简单地刺激消费,而是以新的供给、新的创新作为撬动内需和提升消费的抓手。

举个简单的例子,在苹果手机出现前,绝大多数手机都是有键盘的,但苹果手机用自己新的供给创造出触摸屏手机这样一个广阔的市场。苹果手机用持续的技术创新,满足甚至引导了新的消费需求,这就是供给侧结构性改革。

此次中央经济工作会议上,支持住房改善、新能源汽车、养老服务等被列为明年消费重点。这三个领域尤其是后两个领域,因为供给端的生产能力和产品品质的提升,拓展消费空间,想必很多人已经感同身受。

以新能源车为例,新能源汽车不仅在国内消费领域风生水起,今年前10个月,出口达到了49.9万辆,同比增长96.7%。

这个数字是怎么来的?正是汽车行业抓住了高质量发展的窗口期,成为中国智能制造的一支“生力军”。2021年,中国新能源汽车出口超过40万辆,同比增长近3倍,欧洲已经成为一个主要市场。

更重要的是,和当地汽车品牌的竞争,将加快国产新能源汽车的升级优化。比如,更有针对性的定制化生产服务,使得“柔性化”生产发展更加深入新能源车领域,反过来也为国内创造新的消费场景,让中国消费者享受到更加质优价廉的产品。

这两天,全国政协经济委员会副主任宁吉喆在分析明年形势时也明确指出,明年要继续支持线上线下商品消费融合发展,发展智慧超市、智慧商店、智慧餐厅等新零售业态,培育互联网+社会数字、数字+生活服务新模式,发展智慧家庭、智慧康养、智慧旅游、智慧出行、智慧广电、智慧体育等新型数字消费业态。促进共享经济等消费新业态发展,支持社交电商、网络直播等新个体经济模式发展。

这些无疑是中国经济提前布局数字经济,新供给拓展新需求的好案例。

供给侧结构性改革归根到底是一场改革。这场改革会助力中国经济复苏从过去外延式扩张真正向内涵式发展转变,推动中国经济实现质量变革、效率变革和动力变革。深化供给侧结构性改革相结合的扩大内需,解决的不仅是中国经济短期复苏的问题,更为中国经济高质量发展奠定坚实基础。

改革考验的是智慧、勇气和行动力。

△通过对公开数据的挖掘我们发现,12月7日“新十条”发布后,多地就立即采取行动,优化疫情防控措施

眼下,随着各地新一轮防控政策调整到位,短期内可能还会有一波疫情压力。但是正如中央经济工作会议中提出的:加强统筹衔接,有序组织实施,顺利渡过流行期,确保平稳转段和社会秩序稳定。

人民对美好生活的向往不变,中国深化改革,迈向高质量发展的步伐也不会停。

我们国家有9亿劳动年龄人口,这9亿人,每天会出门赚钱,都在为生计奔波。他们是爸爸或是妈妈,是儿子或者女儿,每个人,都渴望更好的生活。

每个人的愿望都微不足道,但汇集起来,就是推动这个国家不断向前的不竭动力。

只要14亿多中国人在努力,中国经济就有动力,谁也不会失掉对中国经济的信心。

来源: 玉渊谭天

作烘焙面包蛋糕小程序的前期准备

在制作烘焙面包小程序的前期准备阶段,需要通过系统性的业务调研,全面收集并分析了市场需求与潜在客户的期望。通过在线问卷、用户访谈和社交媒体分析等多种方式,深入洞察了烘焙爱好者的行为偏好、学习需求以及使用习惯,为小程序的功能设计和内容规划提供了坚实的数据支撑。

针对收集到的客户需求进行了细致的分类和整理,确定了小程序的核心功能,旨在为用户打造一个全方位、多功能的烘焙小程序商城。在主题设计上,需要结合烘焙文化的特色与现代审美趋势,明确小程序的视觉风格和界面布局。通过色彩搭配、图标设计和页面排版等细节处理,力求为用户带来温馨、专业的使用体验。同时还需要注重了小程序的用户友好性,通过优化操作流程、简化交互设计等方式,降低用户的学习成本,提高使用效率。

为什么你的企业需要制作烘焙面包小程序?

企业为何需要制作烘焙面包小程序,原因显而易见且充满战略意义。首先,烘焙面包小程序能够为企业提供一个直接触达消费者的渠道,通过个性化推荐、会员优惠等功能,增强用户粘性和忠诚度。其次,小程序具备轻便、快捷的特点,用户无需下载安装即可使用,极大提升了用户体验和便利性。此外,烘焙面包小程序还可以帮助企业精准把握市场脉搏,通过收集用户数据,深入分析消费趋势,从而制定更加有效的营销策略。

烘焙面包小程序能够为企业创造新的增长点。通过线上商城功能,企业可以拓展销售渠道,实现线上线下融合,提高销售额。同时,小程序还支持社交分享功能,用户可以将喜欢的烘焙产品分享给朋友,进一步扩大品牌影响力。

烘焙面包小程序不仅能够帮助企业提升用户体验、增强用户粘性,还能为企业创造新的增长点,拓展销售渠道,提高品牌影响力。因此,对于烘焙行业的企业来说,制作烘焙面包小程序是顺应市场趋势、实现持续发展的重要举措。

使用模板制作烘焙面包小程序的好处?

使用模板制作烘焙面包小程序,带来了诸多显著的好处。首先,模板提供了标准化的设计和功能框架,使得小程序开发过程更加高效和便捷。企业无需从零开始设计,而是可以直接基于模板进行定制和优化,大大缩短了开发周期,降低了开发成本。

模板小程序通常经过精心设计和测试,具备良好的用户体验和稳定性。这意味着使用模板制作的小程序不仅外观精美,而且运行流畅,能够为用户提供更加优质的烘焙学习和购物体验。

模板制作的小程序还具备高度的可扩展性和灵活性。企业可以根据自身需求,轻松添加或删除功能模块,满足不断变化的业务需求。同时,模板还支持多种自定义设置,企业可以根据品牌形象和市场定位,调整小程序的色彩、字体和图标等元素,打造出独具特色的小程序。

使用模板制作烘焙面包小程序还能够降低企业的技术门槛。企业无需具备专业的技术团队,也能够快速搭建出功能齐全、稳定可靠的小程序,实现业务目标。

能够为企业带来高效、稳定、灵活和易用的开发体验,是企业快速搭建烘焙小程序、实现数字化转型的明智之选。

从零开始制作烘焙面包小程序商城

借助先进的小程序制作工具,打造烘焙面包小程序商城变得轻而易举。快速搭建,最快一天内即可上线运营,远超传统建站方式的速度与便捷。无需具备深厚的技术背景,无需聘请专业程序员,仅需简单的在线操作,就如同编辑PPT一般轻松。这不仅是对烘焙爱好者的一次技术革新,更是为企业提供了高效、灵活的线上销售新渠道。

step1,在「易极赞」的小程序模板中,选中烘焙面包小程序模板,一键即可生成发布自己的品牌小程序

step2,一键生成烘焙面包小程序,进入可视化编辑器可以对站点文案图片进行修改

step3,在线编辑修改站点内容,设计完成后,点击发布这样一个烘焙面包小程序就制作完成了

烘焙面包小程序主题模板展示

烘焙面包小程序已成为品牌与消费者间不可或缺的沟通桥梁。在烘焙行业,一个功能全面、设计精致的小程序,不仅能展现品牌的独特魅力,更能有效吸引并稳固忠实的用户群体。想要迅速搭建这样一款小程序?无需从零开始,只需借助成熟的小程序模板,通过简单的定制与调整,即可轻松实现。这不仅节省了大量时间与成本,更让品牌快速融入数字化时代,与消费者建立更紧密的联系。

易极赞提供超80套小程序模板案例,开箱即用,在线编辑

制作一个烘焙面包小程序需要多少钱

对于想要进军烘焙行业的创业者来说,制作一款烘焙面包小程序可能是一个令人兴奋但又有些疑虑的决策。担心高昂的开发成本和复杂的技术门槛吗?其实,随着小程序开发工具的不断发展,制作一款烘焙面包小程序已经变得既简单又经济。

无需专业的编程或设计背景,只需选择一款与烘焙行业相契合的小程序模板,借助这些工具,你可以快速搭建起你的烘焙面包小程序框架。接着,通过简单的操作,你可以自定义上传图片、调整文案,轻松实现小程序的个性化设置。与传统的开发方式相比,使用小程序开发工具不仅降低了技术门槛,还大大节省了开发成本。

更值得一提的是,这些小程序开发工具通常提供一站式的服务,包括小程序的托管、安全、备份和性能优化等。你无需为服务器和带宽支付额外费用,也无需雇佣专业技术人员进行小程序的日常维护和更新。这让你能够专注于烘焙面包的研发和销售,而无需为小程序的运营而分心。因此,烘焙面包小程序不仅是一个展示产品的平台,更是一个降低成本、提高效率、助力业务发展的得力助手。

如何推广烘焙面包小程序

推广烘焙面包小程序时,首要任务是明确我们的目标用户群体,并深入探究他们的烘焙需求和口味偏好。通过细致的市场调研和数据分析,我们能够精准地锁定潜在用户,并量身定制出有效的推广策略。我们可以充分利用微信生态内的资源,如微信公众号、微信朋友圈等,发布有关烘焙面包小程序的精彩文章、图文消息和诱人视频,吸引用户点击并体验。同时,与行业内的意见领袖、网红或烘焙专家合作,邀请他们体验并推荐我们的小程序,将能迅速提升小程序的知名度和影响力。

除了线上推广,我们也不能忽视线下渠道的潜力。在实体烘焙店铺内张贴小程序二维码,鼓励顾客扫码下单或获取优惠;在烘焙课程或活动中设置小程序互动环节,增强用户参与感和粘性。此外,我们还需注重用户体验和口碑传播。不断优化小程序的功能和界面设计,确保用户在使用时能够享受到流畅、便捷的体验。同时,积极收集用户反馈,持续改进和完善小程序,提高用户满意度和忠诚度。设置分享奖励机制,鼓励用户将小程序分享给亲朋好友,形成口碑传播效应。

与合作伙伴建立紧密的合作关系,共同推广烘焙面包小程序。与电商平台携手,将小程序嵌入到商品详情页或购物车中,方便用户直接购买;与线下商家合作,提供优惠券或积分兑换等福利,吸引用户到店体验。通过多方合作,共同拓展市场份额,让烘焙面包小程序成为烘焙爱好者们的首选平台。

原文出自易极赞

https://www.yjzan.com/yjznews/fc0afdd5.html