1e41f4b71Sopenharmony_ci# @ohos.arkui.Prefetcher (Prefetching) 2e41f4b71Sopenharmony_ciUsed in conjunction with **LazyForEach**, the **Prefetcher** module provides content prefetching capabilities for container components such as **List**, **Grid**, **Waterfall**, and **Swiper** during scrolling, to enhance the user browsing experience. 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ci> **NOTE** 5e41f4b71Sopenharmony_ci> The initial APIs of this module are supported since API version 12. Updates will be marked with a superscript to indicate their earliest API version. 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci 8e41f4b71Sopenharmony_ci## IPrefetcher 9e41f4b71Sopenharmony_ciImplement this API to provide prefetching capabilities. 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci### setDataSource 16e41f4b71Sopenharmony_cisetDataSource(dataSource: IDataSourcePrefetching): void; 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ciSets the prefetching-capable data source to bind to the **Prefetcher** object. 19e41f4b71Sopenharmony_ci 20e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 21e41f4b71Sopenharmony_ci 22e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 23e41f4b71Sopenharmony_ci 24e41f4b71Sopenharmony_ci**Parameters** 25e41f4b71Sopenharmony_ci 26e41f4b71Sopenharmony_ci| Name | Type | Mandatory| Description | 27e41f4b71Sopenharmony_ci|------------|---------------------------------------------------|----|------------| 28e41f4b71Sopenharmony_ci| dataSource | [IDataSourcePrefetching](#idatasourceprefetching) | Yes | Prefetching-capable data source.| 29e41f4b71Sopenharmony_ci 30e41f4b71Sopenharmony_ci```typescript 31e41f4b71Sopenharmony_ciclass MyPrefetcher implements IPrefetcher { 32e41f4b71Sopenharmony_ci private dataSource?: IDataSourcePrefetching; 33e41f4b71Sopenharmony_ci 34e41f4b71Sopenharmony_ci setDataSource(dataSource: IDataSourcePrefetching): void { 35e41f4b71Sopenharmony_ci this.dataSource = dataSource; 36e41f4b71Sopenharmony_ci } 37e41f4b71Sopenharmony_ci} 38e41f4b71Sopenharmony_ci``` 39e41f4b71Sopenharmony_ci 40e41f4b71Sopenharmony_ci### visibleAreaChanged 41e41f4b71Sopenharmony_civisibleAreaChanged(minVisible: number, maxVisible: number): void 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ciCalled when the boundaries of the visible area change. It works with the **List**, **Grid**, **Waterfall**, and **Swiper** components. 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 48e41f4b71Sopenharmony_ci 49e41f4b71Sopenharmony_ci**Parameters** 50e41f4b71Sopenharmony_ci 51e41f4b71Sopenharmony_ci| Name | Type | Mandatory| Description | 52e41f4b71Sopenharmony_ci|------------|--------|----|-----------| 53e41f4b71Sopenharmony_ci| minVisible | number | Yes | Upper bound of the visible area.| 54e41f4b71Sopenharmony_ci| maxVisible | number | Yes | Lower bound of the visible area.| 55e41f4b71Sopenharmony_ci 56e41f4b71Sopenharmony_ci```typescript 57e41f4b71Sopenharmony_ciclass MyPrefetcher implements IPrefetcher { 58e41f4b71Sopenharmony_ci private dataSource?: IDataSourcePrefetching; 59e41f4b71Sopenharmony_ci 60e41f4b71Sopenharmony_ci visibleAreaChanged(minVisible: number, maxVisible: number): void { 61e41f4b71Sopenharmony_ci this.dataSource?.prefetch(minVisible); 62e41f4b71Sopenharmony_ci } 63e41f4b71Sopenharmony_ci} 64e41f4b71Sopenharmony_ci``` 65e41f4b71Sopenharmony_ci 66e41f4b71Sopenharmony_ci## BasicPrefetcher 67e41f4b71Sopenharmony_ciAs a fundamental implementation of **IPrefetcher**, offers an intelligent data prefetching algorithm that decides which data items to prefetch based on real-time changes in the visible area on the screen and variations in the prefetch duration. It can also determine which prefetch requests should be canceled based on the user's scrolling actions. 68e41f4b71Sopenharmony_ci 69e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 70e41f4b71Sopenharmony_ci 71e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 72e41f4b71Sopenharmony_ci 73e41f4b71Sopenharmony_ci### constructor 74e41f4b71Sopenharmony_ciconstructor(dataSource?: IDataSourcePrefetching) 75e41f4b71Sopenharmony_ci 76e41f4b71Sopenharmony_ciA constructor used to create a **DataSource** instance. 77e41f4b71Sopenharmony_ci 78e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 79e41f4b71Sopenharmony_ci 80e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 81e41f4b71Sopenharmony_ci 82e41f4b71Sopenharmony_ci**Parameters** 83e41f4b71Sopenharmony_ci 84e41f4b71Sopenharmony_ci| Name | Type | Mandatory| Description | 85e41f4b71Sopenharmony_ci|------------|---------------------------------------------------|----|------------| 86e41f4b71Sopenharmony_ci| dataSource | [IDataSourcePrefetching](#idatasourceprefetching) | No | Prefetching-capable data source.| 87e41f4b71Sopenharmony_ci 88e41f4b71Sopenharmony_ci### setDataSource 89e41f4b71Sopenharmony_cisetDataSource(dataSource: IDataSourcePrefetching): void; 90e41f4b71Sopenharmony_ci 91e41f4b71Sopenharmony_ciSets the prefetching-capable data source to bind to the **Prefetcher** object. 92e41f4b71Sopenharmony_ci 93e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 94e41f4b71Sopenharmony_ci 95e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 96e41f4b71Sopenharmony_ci 97e41f4b71Sopenharmony_ci**Parameters** 98e41f4b71Sopenharmony_ci 99e41f4b71Sopenharmony_ci| Name | Type | Mandatory| Description | 100e41f4b71Sopenharmony_ci|------------|---------------------------------------------------|----|------------| 101e41f4b71Sopenharmony_ci| dataSource | [IDataSourcePrefetching](#idatasourceprefetching) | Yes | Prefetching-capable data source.| 102e41f4b71Sopenharmony_ci 103e41f4b71Sopenharmony_ci### visibleAreaChanged 104e41f4b71Sopenharmony_civisibleAreaChanged(minVisible: number, maxVisible: number): void 105e41f4b71Sopenharmony_ci 106e41f4b71Sopenharmony_ciCalled when the boundaries of the visible area change. It works with the **List**, **Grid**, **Waterfall**, and **Swiper** components. 107e41f4b71Sopenharmony_ci 108e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 109e41f4b71Sopenharmony_ci 110e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 111e41f4b71Sopenharmony_ci 112e41f4b71Sopenharmony_ci**Parameters** 113e41f4b71Sopenharmony_ci 114e41f4b71Sopenharmony_ci| Name | Type | Mandatory| Description | 115e41f4b71Sopenharmony_ci|------------|--------|----|-----------| 116e41f4b71Sopenharmony_ci| minVisible | number | Yes | Upper bound of the visible area.| 117e41f4b71Sopenharmony_ci| maxVisible | number | Yes | Lower bound of the visible area.| 118e41f4b71Sopenharmony_ci 119e41f4b71Sopenharmony_ci## IDataSourcePrefetching 120e41f4b71Sopenharmony_ci 121e41f4b71Sopenharmony_ciImplements a prefetching-capable data source. 122e41f4b71Sopenharmony_ci 123e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 124e41f4b71Sopenharmony_ci 125e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 126e41f4b71Sopenharmony_ci 127e41f4b71Sopenharmony_ci### prefetch 128e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 129e41f4b71Sopenharmony_ci 130e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 131e41f4b71Sopenharmony_ci 132e41f4b71Sopenharmony_ci**Parameters** 133e41f4b71Sopenharmony_ci 134e41f4b71Sopenharmony_ci| Name | Type | Mandatory| Description | 135e41f4b71Sopenharmony_ci|-------|--------|----|----------| 136e41f4b71Sopenharmony_ci| index | number | Yes | Index of the data item to be prefetched.| 137e41f4b71Sopenharmony_ci 138e41f4b71Sopenharmony_ci### cancel 139e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 140e41f4b71Sopenharmony_ci 141e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 142e41f4b71Sopenharmony_ci 143e41f4b71Sopenharmony_ci**Parameters** 144e41f4b71Sopenharmony_ci 145e41f4b71Sopenharmony_ci| Name | Type | Mandatory| Description | 146e41f4b71Sopenharmony_ci|-------|--------|----|------------| 147e41f4b71Sopenharmony_ci| index | number | Yes | Index of the data item whose prefetching should be canceled.| 148e41f4b71Sopenharmony_ci 149e41f4b71Sopenharmony_ciWhen list content moves off the screen (for example, during fast scrolling scenarios), once the prefetching algorithm determines which items outside the screen can have their prefetching canceled, this API is called. For instance, if the HTTP framework supports request cancellation, network requests initiated in the **prefetch** API can be canceled here. 150e41f4b71Sopenharmony_ci 151e41f4b71Sopenharmony_ci## Example 152e41f4b71Sopenharmony_ci 153e41f4b71Sopenharmony_ci```typescript 154e41f4b71Sopenharmony_ciimport { BasicPrefetcher, IDataSourcePrefetching } from '@kit.ArkUI'; 155e41f4b71Sopenharmony_ciimport { image } from '@kit.ImageKit'; 156e41f4b71Sopenharmony_ci 157e41f4b71Sopenharmony_ciconst ITEMS_ON_SCREEN = 8; 158e41f4b71Sopenharmony_ci 159e41f4b71Sopenharmony_ci@Entry 160e41f4b71Sopenharmony_ci@Component 161e41f4b71Sopenharmony_cistruct PrefetcherDemoComponent { 162e41f4b71Sopenharmony_ci private readonly dataSource = new MyDataSource(2000, 500); 163e41f4b71Sopenharmony_ci private readonly prefetcher = new BasicPrefetcher(this.dataSource); 164e41f4b71Sopenharmony_ci 165e41f4b71Sopenharmony_ci build() { 166e41f4b71Sopenharmony_ci Column() { 167e41f4b71Sopenharmony_ci List() { 168e41f4b71Sopenharmony_ci LazyForEach(this.dataSource, (item: PictureItem) => { 169e41f4b71Sopenharmony_ci ListItem() { 170e41f4b71Sopenharmony_ci PictureItemComponent({ info: item }) 171e41f4b71Sopenharmony_ci .height(`${100 / ITEMS_ON_SCREEN}%`) 172e41f4b71Sopenharmony_ci } 173e41f4b71Sopenharmony_ci }, (item: PictureItem) => item.title) 174e41f4b71Sopenharmony_ci } 175e41f4b71Sopenharmony_ci .onScrollIndex((start: number, end: number) => { 176e41f4b71Sopenharmony_ci this.prefetcher.visibleAreaChanged(start, end); 177e41f4b71Sopenharmony_ci }) 178e41f4b71Sopenharmony_ci } 179e41f4b71Sopenharmony_ci } 180e41f4b71Sopenharmony_ci} 181e41f4b71Sopenharmony_ci 182e41f4b71Sopenharmony_ci@Component 183e41f4b71Sopenharmony_cistruct PictureItemComponent { 184e41f4b71Sopenharmony_ci @ObjectLink info: PictureItem; 185e41f4b71Sopenharmony_ci 186e41f4b71Sopenharmony_ci build() { 187e41f4b71Sopenharmony_ci Row() { 188e41f4b71Sopenharmony_ci Image(this.info.imagePixelMap) 189e41f4b71Sopenharmony_ci .objectFit(ImageFit.Contain) 190e41f4b71Sopenharmony_ci .width('40%') 191e41f4b71Sopenharmony_ci Text(this.info.title) 192e41f4b71Sopenharmony_ci .width('60%') 193e41f4b71Sopenharmony_ci } 194e41f4b71Sopenharmony_ci } 195e41f4b71Sopenharmony_ci} 196e41f4b71Sopenharmony_ci 197e41f4b71Sopenharmony_ci@Observed 198e41f4b71Sopenharmony_ciclass PictureItem { 199e41f4b71Sopenharmony_ci readonly color: number; 200e41f4b71Sopenharmony_ci title: string; 201e41f4b71Sopenharmony_ci imagePixelMap: image.PixelMap | undefined; 202e41f4b71Sopenharmony_ci key: string; 203e41f4b71Sopenharmony_ci 204e41f4b71Sopenharmony_ci constructor(color: number, title: string) { 205e41f4b71Sopenharmony_ci this.color = color; 206e41f4b71Sopenharmony_ci this.title = title; 207e41f4b71Sopenharmony_ci this.key = title; 208e41f4b71Sopenharmony_ci } 209e41f4b71Sopenharmony_ci} 210e41f4b71Sopenharmony_ci 211e41f4b71Sopenharmony_citype ItemIndex = number; 212e41f4b71Sopenharmony_citype TimerId = number; 213e41f4b71Sopenharmony_ci 214e41f4b71Sopenharmony_ciclass MyDataSource implements IDataSourcePrefetching { 215e41f4b71Sopenharmony_ci private readonly items: PictureItem[]; 216e41f4b71Sopenharmony_ci private readonly fetchDelayMs: number; 217e41f4b71Sopenharmony_ci private readonly fetches: Map<ItemIndex, TimerId> = new Map(); 218e41f4b71Sopenharmony_ci 219e41f4b71Sopenharmony_ci constructor(numItems: number, fetchDelayMs: number) { 220e41f4b71Sopenharmony_ci this.items = []; 221e41f4b71Sopenharmony_ci this.fetchDelayMs = fetchDelayMs; 222e41f4b71Sopenharmony_ci for (let i = 0; i < numItems; i++) { 223e41f4b71Sopenharmony_ci const item = new PictureItem(getRandomColor(), `Item ${i}`) 224e41f4b71Sopenharmony_ci this.items.push(item); 225e41f4b71Sopenharmony_ci } 226e41f4b71Sopenharmony_ci } 227e41f4b71Sopenharmony_ci 228e41f4b71Sopenharmony_ci async prefetch(index: number): Promise<void> { 229e41f4b71Sopenharmony_ci const item = this.items[index]; 230e41f4b71Sopenharmony_ci if (item.imagePixelMap) { 231e41f4b71Sopenharmony_ci return; 232e41f4b71Sopenharmony_ci } 233e41f4b71Sopenharmony_ci 234e41f4b71Sopenharmony_ci // Perform time-consuming operations. 235e41f4b71Sopenharmony_ci return new Promise<void>(resolve => { 236e41f4b71Sopenharmony_ci const timeoutId = setTimeout(async () => { 237e41f4b71Sopenharmony_ci this.fetches.delete(index); 238e41f4b71Sopenharmony_ci const bitmap = create10x10Bitmap(item.color); 239e41f4b71Sopenharmony_ci const imageSource: image.ImageSource = image.createImageSource(bitmap); 240e41f4b71Sopenharmony_ci item.imagePixelMap = await imageSource.createPixelMap(); 241e41f4b71Sopenharmony_ci resolve(); 242e41f4b71Sopenharmony_ci }, this.fetchDelayMs); 243e41f4b71Sopenharmony_ci 244e41f4b71Sopenharmony_ci this.fetches.set(index, timeoutId) 245e41f4b71Sopenharmony_ci }); 246e41f4b71Sopenharmony_ci } 247e41f4b71Sopenharmony_ci 248e41f4b71Sopenharmony_ci cancel(index: number): void { 249e41f4b71Sopenharmony_ci const timerId = this.fetches.get(index); 250e41f4b71Sopenharmony_ci if (timerId) { 251e41f4b71Sopenharmony_ci this.fetches.delete(index); 252e41f4b71Sopenharmony_ci clearTimeout(timerId); 253e41f4b71Sopenharmony_ci } 254e41f4b71Sopenharmony_ci } 255e41f4b71Sopenharmony_ci 256e41f4b71Sopenharmony_ci totalCount(): number { 257e41f4b71Sopenharmony_ci return this.items.length; 258e41f4b71Sopenharmony_ci } 259e41f4b71Sopenharmony_ci 260e41f4b71Sopenharmony_ci getData(index: number): PictureItem { 261e41f4b71Sopenharmony_ci return this.items[index]; 262e41f4b71Sopenharmony_ci } 263e41f4b71Sopenharmony_ci 264e41f4b71Sopenharmony_ci registerDataChangeListener(_: DataChangeListener): void { 265e41f4b71Sopenharmony_ci } 266e41f4b71Sopenharmony_ci 267e41f4b71Sopenharmony_ci unregisterDataChangeListener(_: DataChangeListener): void { 268e41f4b71Sopenharmony_ci } 269e41f4b71Sopenharmony_ci} 270e41f4b71Sopenharmony_ci 271e41f4b71Sopenharmony_cifunction getRandomColor(): number { 272e41f4b71Sopenharmony_ci const maxColorCode = 256; 273e41f4b71Sopenharmony_ci const r = Math.floor(Math.random() * maxColorCode); 274e41f4b71Sopenharmony_ci const g = Math.floor(Math.random() * maxColorCode); 275e41f4b71Sopenharmony_ci const b = Math.floor(Math.random() * maxColorCode); 276e41f4b71Sopenharmony_ci 277e41f4b71Sopenharmony_ci return (r * 256 + g) * 256 + b; 278e41f4b71Sopenharmony_ci} 279e41f4b71Sopenharmony_ci 280e41f4b71Sopenharmony_cifunction create10x10Bitmap(color: number): ArrayBuffer { 281e41f4b71Sopenharmony_ci const height = 10; 282e41f4b71Sopenharmony_ci const width = 10; 283e41f4b71Sopenharmony_ci 284e41f4b71Sopenharmony_ci const fileHeaderLength = 14; 285e41f4b71Sopenharmony_ci const bitmapInfoLength = 40; 286e41f4b71Sopenharmony_ci const headerLength = fileHeaderLength + bitmapInfoLength; 287e41f4b71Sopenharmony_ci const pixelSize = (width * 3 + 2) * height; 288e41f4b71Sopenharmony_ci 289e41f4b71Sopenharmony_ci let length = pixelSize + headerLength; 290e41f4b71Sopenharmony_ci 291e41f4b71Sopenharmony_ci const buffer = new ArrayBuffer(length); 292e41f4b71Sopenharmony_ci const view16 = new Uint16Array(buffer); 293e41f4b71Sopenharmony_ci 294e41f4b71Sopenharmony_ci view16[0] = 0x4D42; 295e41f4b71Sopenharmony_ci view16[1] = length & 0xffff; 296e41f4b71Sopenharmony_ci view16[2] = length >> 16; 297e41f4b71Sopenharmony_ci view16[5] = headerLength; 298e41f4b71Sopenharmony_ci 299e41f4b71Sopenharmony_ci let offset = 7; 300e41f4b71Sopenharmony_ci view16[offset++] = bitmapInfoLength & 0xffff; 301e41f4b71Sopenharmony_ci view16[offset++] = bitmapInfoLength >> 16; 302e41f4b71Sopenharmony_ci view16[offset++] = width & 0xffff; 303e41f4b71Sopenharmony_ci view16[offset++] = width >> 16; 304e41f4b71Sopenharmony_ci view16[offset++] = height & 0xffff; 305e41f4b71Sopenharmony_ci view16[offset++] = height >> 16; 306e41f4b71Sopenharmony_ci view16[offset++] = 1; 307e41f4b71Sopenharmony_ci view16[offset++] = 24; 308e41f4b71Sopenharmony_ci 309e41f4b71Sopenharmony_ci const b = color & 0xff; 310e41f4b71Sopenharmony_ci const g = (color >> 8) & 0xff; 311e41f4b71Sopenharmony_ci const r = color >> 16; 312e41f4b71Sopenharmony_ci offset = headerLength; 313e41f4b71Sopenharmony_ci const view8 = new Uint8Array(buffer); 314e41f4b71Sopenharmony_ci for (let y = 0; y < height; y++) { 315e41f4b71Sopenharmony_ci for (let x = 0; x < width; x++) { 316e41f4b71Sopenharmony_ci view8[offset++] = b; 317e41f4b71Sopenharmony_ci view8[offset++] = g; 318e41f4b71Sopenharmony_ci view8[offset++] = r; 319e41f4b71Sopenharmony_ci } 320e41f4b71Sopenharmony_ci offset += 2; 321e41f4b71Sopenharmony_ci } 322e41f4b71Sopenharmony_ci 323e41f4b71Sopenharmony_ci return buffer; 324e41f4b71Sopenharmony_ci} 325e41f4b71Sopenharmony_ci``` 326