NativeScript 性能优化 #
性能优化概述 #
性能优化是提升用户体验的关键,良好的性能让应用更加流畅。
text
┌─────────────────────────────────────────────────────────────┐
│ 优化领域 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 启动优化 │
│ ├── 减少初始化代码 │
│ ├── 延迟加载模块 │
│ └── 优化启动画面 │
│ │
│ 渲染优化 │
│ ├── 减少布局嵌套 │
│ ├── 使用虚拟滚动 │
│ └── 优化动画性能 │
│ │
│ 内存优化 │
│ ├── 避免内存泄漏 │
│ ├── 图片优化 │
│ └── 及时释放资源 │
│ │
│ 网络优化 │
│ ├── 请求缓存 │
│ ├── 数据压缩 │
│ └── 并行请求 │
│ │
└─────────────────────────────────────────────────────────────┘
启动优化 #
减少启动时间 #
typescript
// app.ts
import { Application } from '@nativescript/core';
// 避免在启动时执行耗时操作
Application.run({ moduleName: 'main-page' });
// 延迟初始化非必要服务
setTimeout(() => {
initAnalytics();
initPushNotifications();
}, 2000);
懒加载模块 #
typescript
// Angular 懒加载
const routes: Routes = [
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
}
];
// Vue 懒加载
const routes = [
{
path: '/admin',
component: () => import('./components/Admin.vue')
}
];
优化启动画面 #
xml
<!-- App_Resources/iOS/LaunchScreen.storyboard -->
<!-- 使用简单的启动画面 -->
渲染优化 #
减少布局嵌套 #
xml
<!-- 不推荐:过度嵌套 -->
<StackLayout>
<StackLayout>
<GridLayout>
<StackLayout>
<Label text="Content" />
</StackLayout>
</GridLayout>
</StackLayout>
</StackLayout>
<!-- 推荐:扁平布局 -->
<GridLayout>
<Label text="Content" />
</GridLayout>
使用 GridLayout #
xml
<!-- GridLayout 通常比嵌套布局更高效 -->
<GridLayout rows="auto, *, auto" columns="*, auto">
<Label text="Header" row="0" col="0" colSpan="2" />
<Label text="Content" row="1" col="0" />
<Label text="Sidebar" row="1" col="1" />
<Label text="Footer" row="2" col="0" colSpan="2" />
</GridLayout>
ListView 优化 #
typescript
// 使用 itemLoading 优化
export function onItemLoading(args: ItemEventData) {
const view = args.view;
// 复用视图
if (!view) {
view = createItemView();
}
// 更新数据
updateViewData(view, args.bindingContext);
args.view = view;
}
xml
<!-- 简化 itemTemplate -->
<ListView items="{{ items }}" itemLoading="onItemLoading">
<ListView.itemTemplate>
<GridLayout columns="auto, *">
<Image src="{{ image }}" col="0" />
<Label text="{{ title }}" col="1" />
</GridLayout>
</ListView.itemTemplate>
</ListView>
虚拟滚动 #
xml
<!-- 使用 RadListView 的虚拟滚动 -->
<RadListView items="{{ items }}" loadOnDemandMode="Auto">
<RadListView.listViewLayout>
<ListViewLinearLayout scrollDirection="Vertical" />
</RadListView.listViewLayout>
<RadListView.itemTemplate>
<!-- 简化的模板 -->
</RadListView.itemTemplate>
</RadListView>
避免频繁更新 #
typescript
// 不推荐:频繁更新
items.forEach((item, index) => {
observableArray.setItem(index, item);
});
// 推荐:批量更新
observableArray.splice(0, observableArray.length, ...items);
内存优化 #
避免内存泄漏 #
typescript
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
@Component({
// ...
})
export class MyComponent implements OnInit, OnDestroy {
private subscriptions: Subscription[] = [];
ngOnInit() {
this.subscriptions.push(
this.service.getData().subscribe(data => {
// 处理数据
})
);
}
ngOnDestroy() {
this.subscriptions.forEach(sub => sub.unsubscribe());
}
}
图片优化 #
typescript
// 使用缩略图
const thumbnailUrl = `${imageUrl}?width=200&height=200`;
// 图片缓存
<Image src="{{ imageUrl }}" cache="true" />
// 延迟加载图片
export class LazyImageLoader {
private loadedImages = new Set<string>();
loadImage(url: string): Promise<ImageSource> {
if (this.loadedImages.has(url)) {
return Promise.resolve(this.getCachedImage(url));
}
return ImageSource.fromUrl(url).then(image => {
this.loadedImages.add(url);
this.cacheImage(url, image);
return image;
});
}
}
及时释放资源 #
typescript
export class ResourceManager {
private resources: any[] = [];
register(resource: any): void {
this.resources.push(resource);
}
releaseAll(): void {
this.resources.forEach(resource => {
if (resource.close) {
resource.close();
} else if (resource.dispose) {
resource.dispose();
}
});
this.resources = [];
}
}
监控内存使用 #
typescript
import { Application } from '@nativescript/core';
// Android 内存监控
if (global.isAndroid) {
Application.android.on(Application.android.lowMemoryEvent, () => {
console.log('Low memory warning');
// 释放非必要资源
});
}
动画性能 #
使用 transform #
typescript
// 推荐:使用 transform
view.animate({
translate: { x: 100, y: 0 },
scale: { x: 1.5, y: 1.5 },
rotate: 45,
duration: 300
});
// 不推荐:动画布局属性
view.animate({
width: 200,
height: 200,
duration: 300
});
使用 will-change #
css
.animated-element {
will-change: transform, opacity;
}
避免布局抖动 #
typescript
// 批量更新视图属性
view.width = 100;
view.height = 100;
view.marginLeft = 10;
// 而不是
view.width = 100;
view.height = 100;
view.marginLeft = 10;
网络优化 #
请求缓存 #
typescript
// services/cache.service.ts
export class CacheService {
private cache = new Map<string, { data: any, timestamp: number }>();
private ttl = 5 * 60 * 1000; // 5分钟
get<T>(key: string): T | null {
const cached = this.cache.get(key);
if (cached && Date.now() - cached.timestamp < this.ttl) {
return cached.data;
}
return null;
}
set<T>(key: string, data: T): void {
this.cache.set(key, {
data,
timestamp: Date.now()
});
}
}
数据压缩 #
typescript
// 使用 gzip 压缩
const response = await fetch(url, {
headers: {
'Accept-Encoding': 'gzip'
}
});
并行请求 #
typescript
// 并行请求
const [users, products, orders] = await Promise.all([
api.getUsers(),
api.getProducts(),
api.getOrders()
]);
请求去重 #
typescript
export class RequestDeduplicator {
private pendingRequests = new Map<string, Promise<any>>();
async request<T>(key: string, requestFn: () => Promise<T>): Promise<T> {
if (this.pendingRequests.has(key)) {
return this.pendingRequests.get(key);
}
const promise = requestFn().finally(() => {
this.pendingRequests.delete(key);
});
this.pendingRequests.set(key, promise);
return promise;
}
}
代码优化 #
避免重复计算 #
typescript
// 使用 memoization
function memoize<T>(fn: (...args: any[]) => T): (...args: any[]) => T {
const cache = new Map<string, T>();
return (...args: any[]) => {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = fn(...args);
cache.set(key, result);
return result;
};
}
const expensiveCalculation = memoize((data: any) => {
// 复杂计算
return result;
});
使用 Web Workers #
typescript
// 主线程
const worker = new Worker('~/workers/worker.js');
worker.onmessage = (e) => {
console.log('Result:', e.data);
};
worker.postMessage({ data: largeData });
// worker.js
self.onmessage = (e) => {
const result = processLargeData(e.data);
self.postMessage(result);
};
延迟执行 #
typescript
// 使用 setTimeout 延迟非关键操作
setTimeout(() => {
// 非关键操作
updateAnalytics();
prefetchData();
}, 0);
性能监控 #
使用性能 API #
typescript
import { profiling } from '@nativescript/core';
// 开始计时
const timer = profiling.start('myOperation');
// 执行操作
doSomething();
// 结束计时
profiling.stop(timer);
自定义性能监控 #
typescript
export class PerformanceMonitor {
private static metrics = new Map<string, number[]>();
static startMeasure(name: string): number {
return Date.now();
}
static endMeasure(name: string, startTime: number): void {
const duration = Date.now() - startTime;
if (!this.metrics.has(name)) {
this.metrics.set(name, []);
}
this.metrics.get(name).push(duration);
}
static getAverageTime(name: string): number {
const times = this.metrics.get(name);
if (!times || times.length === 0) return 0;
return times.reduce((a, b) => a + b, 0) / times.length;
}
static getMetrics(): Map<string, { avg: number, min: number, max: number }> {
const result = new Map();
this.metrics.forEach((times, name) => {
result.set(name, {
avg: times.reduce((a, b) => a + b, 0) / times.length,
min: Math.min(...times),
max: Math.max(...times)
});
});
return result;
}
}
性能检查清单 #
text
┌─────────────────────────────────────────────────────────────┐
│ 性能检查清单 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 启动性能 │
│ □ 减少启动时代码执行 │
│ □ 使用懒加载模块 │
│ □ 优化启动画面 │
│ │
│ 渲染性能 │
│ □ 减少布局嵌套 │
│ □ 使用虚拟滚动 │
│ □ 优化 ListView 模板 │
│ □ 使用 transform 动画 │
│ │
│ 内存管理 │
│ □ 避免内存泄漏 │
│ □ 及时释放资源 │
│ □ 优化图片加载 │
│ │
│ 网络性能 │
│ □ 使用请求缓存 │
│ □ 并行请求 │
│ □ 压缩数据 │
│ │
└─────────────────────────────────────────────────────────────┘
下一步 #
现在你已经掌握了性能优化,接下来学习 测试策略,了解如何测试应用!
最后更新:2026-03-29