HarmonyOS Lazy Loading Feature Development Notes
About HarmonyOS 5
HarmonyOS 5 (also known as HarmonyOS Next) represents a revolutionary step in the evolution of Huawei's distributed operating system. As someone who has been following its development closely, I can attest to the remarkable improvements in this version. The system's microkernel architecture not only enhances security but also provides unprecedented flexibility in cross-device collaboration. What excites me most about HarmonyOS 5 is its focus on developer experience—the new ArkTS language, enhanced UI components, and improved debugging tools have made development much more efficient. The distributed capabilities allow us to create truly seamless experiences across different devices, from smartphones to tablets, smart TVs, and IoT devices.
About the Author
I am a dedicated HarmonyOS developer based in China, with over three years of experience in the ecosystem. My journey with HarmonyOS began with its early versions, and I've witnessed its remarkable evolution. As a developer who has contributed to several open-source HarmonyOS projects, I've gained valuable insights into its architecture and best practices. I'm particularly passionate about performance optimization, lazy loading, and user experience, and I enjoy sharing my experiences through blogs and open-source contributions to help more developers embrace the HarmonyOS ecosystem.
Preface
Recently, while developing HarmonyOS applications, I found that data loading efficiency is always a headache. To improve user experience, I decided to use lazy loading technology to ensure data is loaded only when needed. Here I share my development insights.
I. Feature Description
The main features of lazy loading are as follows:
- Load data on demand
- Improve application performance
- Reduce memory usage
II. Implementation Process
Story 1: The Lazy Loading Crash Saga
When I first wrote this feature, I directly used the system's built-in lazy loading module, thinking, "Isn't this just calling an API? Easy!" But all sorts of problems followed. The funniest was when a user clicked the load button and the app crashed. The user was furious: "What is this? I want a friendly error message!" I thought, "Isn't that just an error message? Easy!" But once I started, I realized I needed to add try-catch and provide specific error info. It was a headache. After several revisions and adding a loading animation, things finally improved.
// Example: Lazy loading
class LazyLoader<T> {
private dataSource: IDataSource<T>;
constructor(dataSource: IDataSource<T>) {
this.dataSource = dataSource;
}
loadData(index: number): T {
return this.dataSource.getData(index);
}
}
Story 2: The Awkward Data Change Moment
Another time, a user said the data change feature didn't work well. At first, I felt wronged: "Isn't this simple?" But after trying it myself, I realized there was indeed a problem. The most awkward part was that there was no prompt when data changed, and sometimes loading failed. The user said, "Waited so long, but didn't know if it succeeded. So annoying!" I quickly revised it several times and added a success prompt. Now, thinking back, I'm grateful for that user's feedback—otherwise, I wouldn't have noticed the issue.
// Example: Data change listener
class DataChangeListener {
onDataReloaded(): void {}
onDataAdded(index: number): void {}
onDataMoved(from: number, to: number): void {}
onDataDeleted(index: number): void {}
onDataChanged(index: number): void {}
}
III. Usage Scenarios
- On-demand loading: Users can click a button to load data as needed, improving app performance.
- Data changes: Users can listen for data changes and update the UI in time.
- User feedback: Prompt messages let users know the result of their actions.
IV. Pitfalls and Issues
- Sometimes memory issues occur during lazy loading (occasionally OOM, really frustrating)
- Sometimes popups don't appear when data changes, which is annoying
- Sometimes strange errors pop up during user feedback, really frustrating
V. Complete Example
Here is the code I actually use in development for your reference:
// 1. Define the data source interface
interface IDataSource<T> {
totalCount(): number;
getData(index: number): T;
registerDataChangeListener(listener: DataChangeListener): void;
unregisterDataChangeListener(listener: DataChangeListener): void;
}
// 2. Define the data change listener
class DataChangeListener {
onDataReloaded(): void {}
onDataAdded(index: number): void {}
onDataMoved(from: number, to: number): void {}
onDataDeleted(index: number): void {}
onDataChanged(index: number): void {}
}
// 3. Implement the basic data source class
@Observed
class BasicDataSource<T> implements IDataSource<T> {
private listeners: DataChangeListener[] = [];
protected dataArray: T[] = [];
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): T {
return this.dataArray[index];
}
// Set the entire data list
public setData(array: T[]): void {
this.dataArray = array;
this.notifyDataReload();
}
// Add a single data item
public addData(item: T): void {
this.dataArray.push(item);
this.notifyDataAdd(this.dataArray.length - 1);
}
// Delete a single data item
public deleteData(index: number): void {
this.dataArray.splice(index, 1);
this.notifyDataDelete(index);
}
// Update a single data item
public updateData(index: number, data: T): void {
this.dataArray[index] = data;
this.notifyDataChange(index);
}
// Clear data
public clearData(): void {
this.dataArray = [];
this.notifyDataReload();
}
// Register data change listener
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
this.listeners.push(listener);
}
}
// Unregister data change listener
unregisterDataChangeListener(listener: DataChangeListener): void {
const index = this.listeners.indexOf(listener);
if (index >= 0) {
this.listeners.splice(index, 1);
}
}
// Notify data change methods
protected notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
});
}
protected notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdded(index);
});
}
protected notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChanged(index);
});
}
protected notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDeleted(index);
});
}
protected notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMoved(from, to);
});
}
}
// 4. Usage example
@Component
struct IconList {
@State iconList: BasicDataSource<IconItem> = new BasicDataSource<IconItem>();
build() {
Grid() {
LazyForEach(this.iconList, (icon: IconItem) => {
GridItem() {
Column() {
Image(icon.symbol)
.width(24)
.height(24)
Text(icon.name)
.fontSize(12)
}
}
}, (icon: IconItem, index: number) => {
return icon.name + index
})
}
.columnsTemplate('1fr 1fr 1fr 1fr')
.rowsGap(8)
.columnsGap(8)
}
}
VI. Summary
This lazy loading feature covers all the basics:
- Supports on-demand data loading
- Supports data change listening
- Provides user feedback
To be honest, developing this feature was a love-hate process. I loved seeing it grow from nothing to something useful, but hated all the pitfalls along the way. Looking back, those pitfalls were worth it! Without them, I wouldn't have found so many areas to optimize.
Some edge cases are still not fully resolved, such as occasional slow loading or UI stutter during data changes (and sometimes strange errors pop up, which is really frustrating). But it works for most scenarios, and user feedback has been positive. I'll keep optimizing as time allows—after all, good products are polished over time.
VII. Reference Resources
- HarmonyOS Development Documentation
- Lazy Loading Technology Documentation
Welcome to Experience
If you are also developing HarmonyOS apps, feel free to use this feature—I hope it helps you!
Author Information
Author: In the World of Development
Email: 1743914721@qq.com
Copyright Notice: This article is an original work by the CSDN blogger, please include the original source link and this statement when reprinting.
Top comments (0)