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