Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 日韩中文字幕精品,久久不射电影,亚洲综合色婷婷在线观看

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          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


          主站蜘蛛池模板: 国产精品一区二区久久精品无码 | 一区二区三区精品视频| 国偷自产视频一区二区久| 精品无码综合一区| 国产精品一区不卡| 麻豆AV无码精品一区二区| 清纯唯美经典一区二区| 国产亚洲综合一区二区三区| 亚洲熟妇AV一区二区三区浪潮| 国产丝袜美女一区二区三区| 一区二区三区免费视频播放器| 国产萌白酱在线一区二区| 亚洲sm另类一区二区三区| 亚洲福利一区二区三区| 2020天堂中文字幕一区在线观| 亚洲AV午夜福利精品一区二区 | 精品无码日韩一区二区三区不卡| 国产精品污WWW一区二区三区| 精品3d动漫视频一区在线观看| 极品少妇一区二区三区四区| 国产乱码精品一区二区三区| 久久青青草原一区二区| 国产成人久久一区二区不卡三区 | 国产福利91精品一区二区 | 在线精品国产一区二区三区| 一区免费在线观看| 亚洲片一区二区三区| 无码日韩人妻AV一区免费l | 久久精品一区二区免费看| 亚洲色精品vr一区二区三区| 久久99精品国产一区二区三区 | 亚洲一区二区三区久久| 国产美女一区二区三区| 无码人妻啪啪一区二区| 怡红院一区二区在线观看| 婷婷国产成人精品一区二| 国产一区二区三区免费观在线| 亚洲av午夜福利精品一区人妖| 国产91大片精品一区在线观看| 亚洲熟女乱色一区二区三区| 国产一区在线视频观看|