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