9afce6f6创建于 2025年5月7日历史提交
/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { IWebParams } from '../common/WebParamsModel';
import { SubWeb } from './SubWeb';

/**
 * 场景描述: 本模块结合内存缓存和磁盘缓存实现了一个H5页面资源离线缓存案例
 *
 * 推荐场景: 网络不稳定或需要加快网页加载的场景,如:浏览网页等
 *
 * 核心组件:
 * 1. SubWeb
 *
 * 实现步骤:
 * 1.通过onInterceptRequest回调,拿到请求的url
 * 2.如果是需要缓存的资源,构造WebResourceResponse;否则,返回null,走正常的请求流程
 * 3.新建promise, 在promise回调中判断本地内存/硬盘缓存(本案例中内存缓存为LRUCache,磁盘缓存为手动实现的DiskLruCache)中是否存在对应的数据
 *(可以配置缓存优化策略,例如资源增加版本号,页面加载时优先使用缓存,保证页面快速加载,不影响用户体验,同时通过对比版本号等方法判断资源是否需要更新,
 * 如果需要,则发起请求更新缓存资源,后续重新加载页面时使用新的缓存)
 *    3.1 如果存在对应的数据,setResponseData给WebResourceResponse设置数据,调用resolve()使promise变成fulfilled状态(开发者可以增加自定义缓存逻辑,例如增加版本对比来实现缓存资源更新)
 *    3.2 如果不存在,手动创建http请求对应数据,在http回调中将数据保存到缓存中,同时通过setResponseData给WebResourceResponse设置数据,调用resolve()使promise变成fulfilled状态
 */
@Component
export struct H5Cache {
  pageInfos: NavPathStack = new NavPathStack();
  // 项目cache文件夹路径
  baseCacheDir: string = getContext(this).cacheDir;

  @Builder
  pagesMap(name: string, params: IWebParams) {
    SubWeb(params)
  }

  build() {
    Column() {
      Button('加载网页')
        .onClick(() => {
          const params: IWebParams = {
            url: $rawfile('example.html'),
            // WEB的title名
            title: '示例页面',
            // 目前只针对h5页面img、script等标签发起的资源类请求做缓存,尚未对作字体、音视频文件文件缓存
            cacheableResourceUrls: ['jpg', 'html', 'css', 'png', 'js'],
            // 磁盘缓存大小 3MB
            diskCacheCapacity: 3 * 1024 * 1024,
            // 内存缓存大小 1MB
            memoryCacheCapacity: 1024 * 1024,
            // 磁盘缓存路径
            diskCachePath: `${this.baseCacheDir}/example1`
          }
          this.pageInfos.pushPathByName('subWeb', params)
        })
      Navigation(this.pageInfos) {
      }
      .mode(NavigationMode.Stack)
      .navDestination(this.pagesMap)
    }
  }
}