鸿蒙5开发宝藏案例分享---Web开发优化案例分享

简介: 本文深入解读鸿蒙官方文档中的 `ArkWeb` 性能优化技巧,从预启动进程到预渲染,涵盖预下载、预连接、预取POST等八大优化策略。通过代码示例详解如何提升Web页面加载速度,助你打造流畅的HarmonyOS应用体验。内容实用,按需选用,让H5页面快到飞起!

好的,老铁们!鸿蒙官方文档里其实藏着不少“硬核”性能优化案例,我之前愣是没发现,感觉错过了一个亿!特别是关于 `ArkWeb`(方舟Web)组件加载Web页面的优化技巧,简直是提升应用流畅度的神兵利器。官方文档写得比较“正经”,我这就把它掰开了、揉碎了,加上我自己的理解,再配上点“栗子”(代码),跟大家好好唠唠,保证让你看得懂、用得上!🚀

**开头打个招呼:**

嘿,各位鸿蒙开发者们,大家好啊!是不是经常被Web页面加载慢、卡顿搞得头大?尤其是在咱们的HarmonyOS应用里嵌入个H5页面,用户等得花儿都谢了还没出来,体验分分钟掉光?别慌!今天给大家分享一个我从鸿蒙官方文档里挖出来的“性能优化宝藏地图”——专门针对`ArkWeb`组件的Web加载速度优化方案。官方其实提供了超多实用案例和指导,但可能藏得有点深,今天我带大家捋一捋,重点讲讲那些能立竿见影的优化手段,配上代码讲解,包你学完就能用!

**正文详解(案例+讲解+代码):**

官方文档里把Web加载流程拆得很细,提出了基于“**预处理**”思想的一系列优化手段。核心思路就是:**在用户真正需要看到页面之前,提前把能干的活儿都干了!** 咱们一个个来看这些“预”字诀的妙招:

1.  **预启动Web渲染进程(Pre-Launch)**

-   -   **痛点:** 每次打开一个WebView,系统都要花时间(约140ms)去拉起背后的渲染进程,这个时间用户是实打实等着的。

   -   **妙招:** 在用户可能用到WebView之前(比如App冷启动时、首页加载完的空档期、或者广告展示时),**偷偷地、悄悄地**创建一个**空白**的Web组件并加载一个空白页(比如 `about:blank`)。只要这个“影子武士”活着,渲染进程就一直存在。

   -   **效果:** 当用户真正点击打开目标Web页面时,直接复用这个现成的进程,省掉拉起时间,页面“唰”一下就出来了!

   -   **代价:** 稍微多占点内存和一点点CPU(养着这个“影子”)。

   -   **适用场景:** App里高频使用的Web页面(比如首页某个重要入口、用户中心的某个H5模块)。

   -   **代码示意 (ArkTS):**

```

import webview from '@ohos.web.webview';

// 假设在应用冷启动的某个合适时机(如onWindowStageCreate)

let preloadWebView: webview.WebviewController | null = null;

function preLaunchWebProcess() {

 // 1. 创建Web组件 (这里简化了UI构建过程,实际你可能需要将其添加到某个容器但设置为不可见或极小)

 preloadWebView = webview.createWebview();

 // 2. 加载一个极轻量的页面(空白页是最佳实践)

 preloadWebView.loadUrl('about:blank');

 // 3. 注意:你需要管理这个preloadWebView的生命周期,在真正需要显示目标页面时,可以复用这个Controller或者销毁它再创建新的(但进程还在)

}

// 当真正需要打开目标页面时,比如点击某个按钮:

function openTargetWebPage() {

 // 方式一:如果preloadWebView还在且可用,直接用它加载目标URL

 if (preloadWebView) {

   preloadWebView.loadUrl('https://www.your-target-page.com');

   // ... 然后将这个WebView显示出来(可能是同一个组件,也可能是新创建的复用同一个进程)

 } else {

   // 方式二:即使prelaunch失效了,正常创建新的。但理想情况是prelaunch一直有效。

   let targetWebView = webview.createWebview();

   targetWebView.loadUrl('https://www.your-target-page.com');

   // ... 显示targetWebView

 }

}

// 注意:在应用退出或确定不再需要预加载时,记得销毁 preloadWebView 释放资源

function cleanupPreload() {

 if (preloadWebView) {

   preloadWebView.destroy();

   preloadWebView = null;

 }

}

```

2.  **预解析 (Pre-Resolve) & 预连接 (Pre-Connect)**

-   -   **痛点:** 用户访问一个网址,第一步得解析域名(DNS, ~66ms),第二步得建立网络连接(TCP握手/TLS协商, 加起来~80ms)。网络差点,这100多ms就没了。

   -   **妙招:**

<!---->

-   -   -   **预解析 (Pre-Resolve):** 提前把你**知道**用户接下来**很可能**访问的域名拿去解析好,把IP地址缓存起来。

       -   **预连接 (Pre-Connect):** 更狠!在预解析的基础上,**提前和服务器建立好Socket连接**(甚至完成TLS握手)。等用户真要访问时,直接在这个“VIP通道”上传数据!

<!---->

-   -   **效果:** 砍掉DNS解析和建连时间,让网络请求“起跑”更快。

   -   **代价:** 可能提前消耗了点网络资源(流量、连接数),解析/连接了用户最终没访问的域名就有点浪费。

   -   **适用场景:** 主流程必经的、或者用户大概率点击的Web链接域名。

   -   **代码示意 (概念性, ArkWeb可能封装或需结合系统网络API):**

<!---->

-   -   -   目前鸿蒙 `ArkWeb` 可能没有直接暴露 `preconnect` 这样的API。

       -   一种思路是利用系统网络能力(如`@ohos.net.http`)进行预连接,但需注意连接管理和复用。

       -   **更常见的实践是:** 在预加载/预渲染(下面会讲)某个页面时,其内部的资源请求自然就会触发对该域名的解析和连接,这本身也是一种“预”。所以可以结合预加载使用。

       -   **官方文档重点提示了此优化,开发者需关注API更新或在设计预加载策略时利用此特性。**

3.  **预下载 (Pre-Fetch/DownLoad)**

-   -   **痛点:** 页面里的图片、CSS、JS等资源,边下载边解析渲染,遇到大文件或慢网络就卡住了。

   -   **妙招:** 在用户访问页面前,**提前把这些关键静态资源(图片、CSS、JS、字体等)下载好,缓存起来**(内存或磁盘)。

   -   **效果:** 页面加载时,资源直接从本地拿,省去网络等待,大幅减少阻塞(~641ms),渲染更顺滑。

   -   **代价:** 消耗额外网络流量和存储空间。下多了下错了就浪费了。

   -   **适用场景:** 核心页面的核心、体积较大、加载慢的资源。

   -   **代码示意 (利用资源拦截 + 缓存):**

<!---->

-   -   -   鸿蒙 `ArkWeb` 提供了强大的 `onInterceptRequest` 拦截能力。我们可以结合本地缓存策略实现预下载。

```

import webview from '@ohos.web.webview';

let cachedResources: Map<string, ArrayBuffer> = new Map(); // 简单内存缓存,实际可用文件缓存

// 步骤1:预下载关键资源 (在空闲时或预加载页面时进行)

async function prefetchResource(url: string) {

 try {

   // 使用网络库下载资源 (如 @ohos.net.http)

   let response = await myHttpModule.request(url); // 伪代码,实际使用http模块API

   if (response && response.data) {

     // 假设response.data是ArrayBuffer格式

     cachedResources.set(url, response.data);

     console.log(`Prefetched and cached: ${url}`);

   }

 } catch (error) {

   console.error(`Prefetch failed for ${url}:`, error);

 }

}

// 步骤2:在WebView中设置拦截,命中缓存

let webViewController = webview.createWebview();

webViewController.onInterceptRequest((request) => {

 let url = request.requestUrl;

 if (cachedResources.has(url)) {

   console.log(`Intercepting and serving from cache: ${url}`);

   // 构造一个拦截响应

   let interceptResponse: webview.WebResourceResponse = {

     data: cachedResources.get(url),

     mimeType: getMimeTypeFromUrl(url), // 需要根据url推断MIME类型

     encoding: 'utf-8', // 根据实际情况调整

     statusCode: 200,

     reasonPhrase: 'OK',

     responseHeaders: { 'from-cache': 'prefetch' },

   };

   return interceptResponse; // 返回缓存数据,WebView不再发起网络请求

 }

 return null; // 不拦截,WebView按原流程请求

});

// 步骤3:加载目标页面 (可能是在预加载或用户实际触发时)

webViewController.loadUrl('https://www.your-target-page.com');

```

4.  **预渲染 (Pre-Render)**

-   -   **痛点:** 即使资源都下载好了,浏览器还得解析HTML、构建DOM树、应用CSS、执行JS、布局、绘制...这一套流程走完才能看到完整页面。

   -   **妙招:** 终极奥义!在后台**完整地、偷偷地加载、解析、渲染整个目标页面**(包括执行JS)。等用户真点进去的时候,直接把这个渲染好的“成品”页面瞬间切到前台展示,实现真正的“**秒开**”(~486ms收益)!

   -   **效果:** 体验爆炸!用户几乎无感知加载过程。

   -   **代价:** 消耗较大!网络(下载全量资源)、CPU(执行JS、渲染)、内存(存储渲染结果)、存储。要是用户没点进去,这开销就白费了。

   -   **适用场景:** **超高概率、必须保证体验的核心入口页面**(比如App首页的某个核心运营位、活动页入口)。

   -   **代码示意 (ArkTS):**

<!---->

-   -   -   鸿蒙 `ArkWeb` 的 `WebviewController` 提供了 `prerender` 方法。

```

import webview from '@ohos.web.webview';

let prerenderController: webview.WebviewController | null = null;

// 在非常确定用户将访问特定URL时 (如首页加载完毕且用户行为分析指向该页面)

function startPrerender(targetUrl: string) {

 // 1. 创建一个专门用于预渲染的WebView

 prerenderController = webview.createWebview();

 // 2. 关键!监听页面是否完成预渲染(通常监听特定事件或检查状态)

 // 注意:ArkWeb预渲染完成事件可能需要查阅最新API文档,这里用伪事件名`onPrerenderFinished`

 prerenderController.on('prerenderFinished', (event) => { // 事件名需确认,如`onPageFinished`可能不够精准

   console.log('预渲染完成! 页面已准备好秒开!');

   // 此时 prerenderController 背后已经渲染好页面了

 });

 // 3. 开始预渲染 (指定目标URL)

 prerenderController.prerender(targetUrl); // 使用prerender方法,而非loadUrl

}

// 当用户点击打开该页面时:

function showPrerenderedPage() {

 if (prerenderController && prerenderController.isPrerendered) { // 假设有状态检查

   // 方式一:直接显示这个预渲染好的WebView(如果UI结构允许)

   // myContainer.addChild(prerenderController.getComponent()); // 伪代码,显示组件

   // 方式二(更常见):将预渲染的内容“转移”或“激活”到前台可见的WebView

   // 注意:ArkWeb的具体激活API需确认,可能类似于:

   let visibleWebView = webview.createWebview();

   visibleWebView.activatePrerenderedPage(prerenderController); // 伪API,将预渲染结果激活到当前WebView

   // ... 显示 visibleWebView

 } else {

   // 预渲染未完成或失败,降级为正常加载

   let fallbackWebView = webview.createWebview();

   fallbackWebView.loadUrl(targetUrl);

   // ... 显示 fallbackWebView

 }

}

// 重要:谨慎使用,及时销毁未使用的预渲染实例释放资源

```

5.  **预取POST (Pre-Fetch POST)**

-   -   **痛点:** 有些页面一加载就要发起耗时的POST请求(比如提交初始数据、获取动态内容),用户得等这个请求回来才能看到完整内容(~313ms)。

   -   **妙招:** 提前把这个POST请求发出去,把响应数据**预取**并**缓存**下来。等用户打开页面,JS发起这个POST请求时,**拦截它,直接返回缓存好的数据**!

   -   **效果:** 消除关键POST请求的网络延迟。

   -   **代价:** 额外网络请求,存储响应数据。POST请求通常有副作用,**必须确保预取请求是安全的(只读、无副作用)** !否则提前提交数据会出大问题!

   -   **适用场景:** **安全、幂等的、耗时的初始化POST请求**。

   -   **代码示意 (结合拦截和缓存):**

<!---->

-   -   -   类似于预下载的拦截,但更关注识别特定POST请求。

```

import webview from '@ohos.web.webview';

let cachedPostResponse: Map<string, any> = new Map(); // 缓存Key可以是URL+请求体特征

// 步骤1:安全地预取POST数据 (确保无副作用!)

async function prefetchPostData(url: string, postData: string | Object) {

 try {

   // 使用网络库模拟发起POST请求 (如 @ohos.net.http)

   let response = await myHttpModule.post(url, postData); // 伪代码

   if (response && response.data) {

     let cacheKey = `${url}_${hash(postData)}`; // 生成唯一Key标识请求

     cachedPostResponse.set(cacheKey, response.data);

     console.log(`Prefetched POST data for ${cacheKey}`);

   }

 } catch (error) {

   console.error(`Prefetch POST failed:`, error);

 }

}

// 步骤2:在WebView中拦截特定的POST请求

webViewController.onInterceptRequest((request) => {

 if (request.method === 'POST') {

   let url = request.requestUrl;

   let postBody = request.body; // 注意获取请求体,可能是string或ArrayBuffer

   // 根据URL和body生成特征Key (需要实现一个可靠的hash/序列化函数)

   let cacheKey = generateCacheKey(url, postBody);

   if (cachedPostResponse.has(cacheKey)) {

     console.log(`Intercepting and serving cached POST response for ${cacheKey}`);

     let cachedData = cachedPostResponse.get(cacheKey);

     // 构造拦截响应 (格式同预下载)

     let interceptResponse: webview.WebResourceResponse = {

       data: cachedData,

       mimeType: 'application/json', // 根据实际响应类型调整

       encoding: 'utf-8',

       statusCode: 200,

       reasonPhrase: 'OK',

       responseHeaders: { 'from-cache': 'prefetch-post' },

     };

     return interceptResponse;

   }

 }

 return null; // 不拦截

});

```

6.  **预编译JavaScript生成字节码缓存 (Code Cache)**

-   -   **痛点:** JS文件下载后,浏览器需要先把它编译成字节码才能执行。JS越大越复杂,编译时间越长(官方例子:5.76MB JS编译~2915ms!)。

   -   **妙招:**

<!---->

-   -   -   **首次加载优化 (V8 Code Cache):** 浏览器(如V8引擎)在第一次执行JS后,会把编译好的字节码缓存起来。下次再加载**同一个**JS文件(URL完全匹配且未修改),就直接用缓存好的字节码,跳过编译。

       -   **资源拦截替换优化:** 如果你用了资源拦截替换(比如上面预下载),把网络JS替换成了本地内容。这种情况下,`ArkWeb` 也提供了 `setJavaScriptProxy` 配合 `removeJavaScriptCache` 等方法来管理缓存,确保拦截后的JS也能利用字节码缓存优化后续加载速度(官方例子:2.4MB JS后续加载节省~67ms)。

<!---->

-   -   **效果:** 省掉JS编译时间,尤其对大JS文件显著。

   -   **代价:** 额外存储空间存放字节码。

   -   **适用场景:** 所有包含JS的Web页面,特别是JS体积较大的页面。对于拦截替换的资源,需要正确管理缓存。

   -   **代码示意 (主要依赖浏览器/V8机制,鸿蒙提供缓存管理API):**

```

import webview from '@ohos.web.webview';

// 对于拦截替换的资源,为了确保后续加载能利用字节码缓存,通常需要:

// 1. 在拦截时返回正确的资源数据

// 2. (可选但推荐) 在资源内容**发生改变**时,清除旧的字节码缓存

webViewController.setJavaScriptProxy({

 // ... 其他方法

 onResourceLoad: (request) => {

   if (request.resourceType === webview.ResourceType.SCRIPT && request.url === yourJsUrl) {

     let newJsContent = getUpdatedJsContent(); // 获取最新的JS内容

     // 清除旧的缓存 (非常重要!否则即使内容变了,可能还在用旧的字节码)

     webViewController.removeJavaScriptCache(request.url); // 移除指定URL的JS缓存

     return { data: newJsContent }; // 返回新的JS内容

   }

   return null;

 },

});

// 注意:浏览器自身的首次编译缓存是自动的,无需特殊代码。重点是处理拦截替换时的缓存一致性问题。

```

7.  **离线资源免拦截注入**

-   -   **痛点:** 即使用拦截,资源首次加载到内存也需要时间。

   -   **妙招:** 更进一步!在页面加载**之前**,直接把需要的资源内容(图片、CSS、JS)**预先注入到WebView的内存缓存**里。

   -   **效果:** 连拦截匹配的过程都省了,资源瞬间可用(~1240ms for 25MB)。

   -   **代价:** 较大内存占用(资源常驻内存)。

   -   **适用场景:** 体积不大、超高频率使用的核心资源(如基础库JS、核心CSS、小图标)。

   -   **代码示意 (概念性,API需确认):**

<!---->

-   -   -   鸿蒙 `ArkWeb` 可能提供类似 `loadWithContent` 或直接操作内存缓存的API(文档或示例中寻找)。一种思路是在创建WebView后,`loadUrl`前注入。

```

// 伪代码,展示概念。实际API可能为 `injectResource` 或 `preloadToCache`

webViewController.injectResource('https://cdn.example.com/core.js', jsContentArrayBuffer);

webViewController.injectResource('https://cdn.example.com/styles.css', cssContentArrayBuffer);

webViewController.injectResource('https://cdn.example.com/logo.png', imageDataArrayBuffer, 'image/png');

// 然后加载页面,页面内请求这些URL的资源时,会直接从内存缓存读取,无需拦截和网络请求。

webViewController.loadUrl('https://www.your-target-page.com');

```

8.  **资源拦截替换加速 (ArrayBuffer 优化)**

-   -   **痛点:** 使用 `onInterceptRequest` 进行资源替换时,如果替换的数据是 `ArrayBuffer` 格式(图片、音视频、字体、压缩JS/CSS等二进制常用),在应用层可能需要转换格式(比如 `string` 转 `ArrayBuffer`),或在 `ArkWeb` 内部需要转换,消耗时间。

   -   **妙招:** `ArkWeb` 的拦截接口 **原生支持** 直接返回 `ArrayBuffer` 格式的数据。开发者在拦截时,尽量直接提供 `ArrayBuffer` 数据,避免不必要的格式转换开销。

   -   **效果:** 节省格式转换时间 (~20ms for 10Kb),尤其是对于大量或大体积的二进制资源拦截。

   -   **代价:** 开发者需确保能获取到资源的 `ArrayBuffer` 格式(下载时、本地读取时)。

   -   **适用场景:** **所有需要拦截替换的二进制资源**(图片、字体、wasm、音视频、压缩过的JS/CSS)。

   -   **代码示意 (正确姿势):**

```

webViewController.onInterceptRequest((request) => {

 if (shouldIntercept(request.url)) {

   // 最佳实践:你的缓存或资源获取逻辑直接返回ArrayBuffer

   let resourceArrayBuffer: ArrayBuffer = getResourceAsArrayBuffer(request.url);

   return {

     data: resourceArrayBuffer, // 直接返回ArrayBuffer!

     mimeType: getMimeType(request.url),

     encoding: 'identity', // 二进制资源通常不需要字符编码

     statusCode: 200,

     reasonPhrase: 'OK',

   };

 }

 return null;

});

```

**总结与结尾:**

怎么样,老铁们?是不是感觉鸿蒙官方给的这些Web优化“黑科技”相当给力!从“预启动”进程到终极“预渲染”,从“预下载”资源到利用好“字节码缓存”和“ArrayBuffer优化”,这套组合拳打下来,绝对能让你的HarmonyOS应用里的H5页面快到飞起,用户体验直接拉满!🌟

官方文档就像个宝库,这次挖到的 `ArkWeb` 性能优化指南真是干货满满。咱们在实际开发中,不用一股脑全上,得**按需选择、量力而行**:

-   **预启动进程**是性价比极高的首选,适合高频页面。

-   **预下载/拦截替换**非常灵活实用,结合好 `ArrayBuffer` 和字节码缓存管理。

-   **预渲染**效果炸裂但开销巨大,留给最重要的“王炸”页面。

-   **预连接/预解析**最好结合其他优化(如预加载)使用。

-   **预取POST**务必注意安全性!

-   **字节码缓存**和 **ArrayBuffer优化**是基本功,尽量做好。

建议大家收藏好这篇解读,下次做HarmonyOS应用性能优化时,别忘了试试这些大招!亲测有效,谁用谁知道!

**结尾互动:**

大家在实际项目中有没有用到过这些优化技巧?效果如何?或者有没有遇到什么坑?欢迎在评论区一起交流讨论!也欢迎大家分享自己挖到的鸿蒙开发宝藏知识!一起学习,共同进步!💪 #HarmonyOS #ArkWeb #性能优化 #Web加载 #开发者宝藏

相关文章
|
1月前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
213 5
|
1月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
237 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
1月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
203 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
5月前
|
容器
HarmonyOS NEXT仓颉开发语言实战案例:外卖App
仓颉语言实战分享,教你如何用仓颉开发外卖App界面。内容包括页面布局、导航栏自定义、搜索框实现、列表模块构建等,附完整代码示例。轻松掌握Scroll、List等组件使用技巧,提升HarmonyOS应用开发能力。
|
1月前
|
移动开发 Rust JavaScript
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
516 4
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
4月前
|
安全 JavaScript API
鸿蒙开发核心要素
鸿蒙开发核心要素
|
5月前
|
存储 IDE 定位技术
【HarmonyOS 5】鸿蒙组件&模板服务详解 - 助力高效开发的利器
在移动应用开发领域,效率与质量始终是开发者追求的核心目标。鸿蒙系统作为新兴的操作系统,为开发者提供了丰富且强大的开发资源,其中鸿蒙组件&模板服务更是成为开发者快速构建高质量应用的得力助手。
191 0
HarmonyOS NEXT仓颉开发语言实战案例:电影App
周末好!本文分享使用仓颉语言重构ArkTS实现的电影App案例,对比两者在UI布局、组件写法及语法差异。内容包括页面结构、列表分组、分类切换与电影展示等。通过代码演示仓颉在HarmonyOS开发中的应用。##仓颉##ArkTS##HarmonyOS开发
|
1月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
121 0
|
5月前
|
容器
HarmonyOS NEXT仓颉开发语言实战案例:健身App
本期分享一个健身App首页的布局实现,顶部采用Stack容器实现重叠背景与偏移效果,列表部分使用List结合Scroll实现可滚动内容。代码结构清晰,适合学习HarmonyOS布局技巧。

热门文章

最新文章

下一篇
oss云网关配置