【问题标题】:Slow loading images nativescript加载缓慢的图像 nativescript
【发布时间】:2019-12-24 21:57:22
【问题描述】:

我正在使用 nativescript + angular 创建一个社交媒体应用程序。我不确定这是否只是原生脚本,但我的图片加载速度都很慢——它们是通过不同的 URL 动态加载的。在下面的链接中,它显示了我所说的“图像加载缓慢”的意思。有什么办法可以让它们加载得更快吗?我有这些想法,但不知道它们是否会起作用

  1. 在上传到网络服务器时为它们设置一个高度,以便加载速度更快(目前仅使用模拟数据,因此无法对此进行测试)
    • 可能会使用 cloudinary 来存储图像(不确定这是最好的还是最具成本效益的,所以如果有人对此有任何意见,请告诉我)
  2. 在 UI 中设置它们的高度(我认为这仍然会缓慢加载它们)

如果有人对我能做什么有任何想法,请告诉我。

我正在写的视频被称为“Slow-loading-images-android”(我还在屏幕上显示了一些代码,以便您可以看到其中的内容),还有另一个带有在 iOS 上加载奇怪的图像的问题,但我认为如果我在 android 上解决这个问题,它也可能会解决 iOS 上的问题

https://1drv.ms/u/s!AqCHfupkDPkD81s7dtGhImTkbtb-?e=44OyNk

【问题讨论】:

  • 您可以使用nativescript-image等插件,帮助您缓存远程图像,在下载原始图像时显示占位符图像等,
  • 如果图像每次都不同,缓存远程图像会有帮助吗?我不认为它会,但也许我错了?
  • 如果图像更改,您将拥有一个版本密钥或不同的 url。如果您不这样做,我可能会说这不是最佳设计,您可能需要重新考虑。而且插件缓存了图片,所以下载的时候可以显示正在加载的图片。
  • 我找到了另一种解决方案,它不是这样的 ^。它只是使用图像的 decodeHeight 和 decodeWidth 属性,因此它加载得更快,然后当用户点击图像时,它将正确加载图像。谢谢你的帮助。它也是一个社交媒体应用程序,因此用户将上传图像,因此它将保存并从数据库中读取图像 URL,因为当图像上传时,它们将存储在云图像存储中,并且 URL 将保存到数据库中
  • 我猜插件也有相同的选项,必须仔细检查。但我确信图像模块中的解码宽度/高度是 Android 独有的属性。通常,Android 在图像处理上会占用大量内存。

标签: android ios angular nativescript


【解决方案1】:

我发现解决此问题的一种方法是使用 nativescript-image-cache 但这并不总是很好,因为图像加载速度仍然很慢。我想出的解决方案是向 API 添加分页并使用 angular *ngFor 而不是 ListView。这样它们就不会因为 ListView 而消失,并且用户可以加载任意数量的图像,当他们想要它们时,它不会降低性能并且在 UI 方面看起来更好。

如果其他人遇到这样的问题并且不知道该怎么办,这里是代码:

之前(使用 ListView - 不好)

    <ListView [items]="feeds" height="100%">
                <ng-template let-item="item" class="feed">

                    <StackLayout>
                        <StackLayout>
                            <GridLayout class="feed-user" columns="50,20,*" (tap)="getUserById(item.userId)">
                                <Image class="user" [src]="item.mainImage" col="0"></Image>
                                <Label [text]="item.username" class="username" col="2"></Label>
                            </GridLayout>
                            <Image *ngIf="item.isImage" class="feed-image" [src]="item.photoUrl"></Image>
                            <VideoPlayer *ngIf="!item.isImage" [src]="item.photoUrl" autoplay="true" muted="true"
                                height="300">
                            </VideoPlayer>
                            <GridLayout class="like-sect" columns="*,*" (tap)="like(item)">
                                <Image class="like" col="0" src="~/app/_assets/ui-images/like.png"></Image>
                                <Label col="1" class="likes" [text]="item.likes"></Label>
                            </GridLayout>
                            <Label class="caption" [text]="item.description"></Label>
                        </StackLayout>
                    </StackLayout>

                </ng-template>
            </ListView>

之后(没有 ListView - 好)

    <ScrollView [height]="height">

        <StackLayout>

            <StackLayout *ngFor="let item of feeds">
                <StackLayout class="feed-body">
                    <StackLayout>
                        <Image *ngIf="item.isImage" class="feed-image" [src]="item.photoUrl"></Image>
                        <VideoPlayer *ngIf="!item.isImage" [src]="item.photoUrl" autoplay="true" muted="true"
                            height="300">
                        </VideoPlayer>
                        <GridLayout class="like-sect" columns="*,*" (tap)="like(item)">
                            <Image class="like" col="0" src="~/app/_assets/ui-images/like.png"></Image>
                            <Label col="1" class="likes" [text]="item.likes"></Label>
                        </GridLayout>
                        <StackLayout class="feed-info">
                            <Label class="caption" [text]="item.description" textWrap="true"></Label>
                            <Label [text]="item.username + ' | ' + item.dateCreated" (tap)="getUserById(item.userId)"></Label>
                        </StackLayout>
                    </StackLayout>
                </StackLayout>
                <StackLayout class="hr" height="1"></StackLayout>
            </StackLayout>

<!-- Instead of this stackLayout below, you should use RadListView and when the user scrolls to the bottom of the screen, it should automatically run the 'nextPage()' function -->

            <StackLayout>
                <Label *ngIf="!noMoreItems" class="load-more" horizontalAlignment="center" text="Load More.."
                    (tap)="nextPage()"></Label>
                <Label *ngIf="noMoreItems" class="load-more" horizontalAlignment="center"
                    text="You've viewed everything!"></Label>
            </StackLayout>

        </StackLayout>

    </ScrollView>

这是打字稿文件,如果有人想看的话:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { FeedService } from '~/app/_mocks/feed.service';
import { EventService } from '~/app/_services/event.service';
import * as utils from "tns-core-modules/utils/utils";
import * as application from "tns-core-modules/application"
import { registerElement } from "nativescript-angular/element-registry";
import { Video } from 'nativescript-videoplayer';
import { RouterExtensions } from 'nativescript-angular/router';
import { HttpClient } from '@angular/common/http';
import { GoToService } from '~/app/_services/go-to/go-to.service';
import { UserService } from '~/app/_services/user.service';
registerElement("VideoPlayer", () => Video);
import { screen } from "tns-core-modules/platform/platform"
import { environment } from '~/app/environments/environment';

@Component({
    selector: 'ns-feed',
    templateUrl: './feed.component.html',
    styleUrls: ['./feed.component.css']
})
export class FeedComponent implements OnInit {

    constructor(private mockFeedService: FeedService, private eventService: EventService
        , private router: RouterExtensions, private http: HttpClient, private goTo: GoToService,
        private userService: UserService) { }
    baseUrl = environment.apiUrl + 'feeds/'
    public isAndroid: boolean;
    public isIos: boolean;
    feeds: any;
    loaded = true
    today: '18/12/2019'
    show: any;
    start = 0
    end = 7
    pageNumber = 1;
    userImg = '~/app/_assets/-user.png'
    height: number = screen.mainScreen.heightDIPs * 1;
    noMoreItems = false;

    ngOnInit() {
        if (application.ios) {
            this.isAndroid = false;
            this.isIos = true;
        } else if (application.android) {
            this.isAndroid = true;
            this.isIos = false;
        }

        this.getFeed();
        this.show = 'false'
        console.log(this.feeds)
    }

    getFeed() {
        this.baseUrl = environment.apiUrl + 'feeds' + '?pageNumber=' + this.pageNumber
        this.http.get(this.baseUrl).subscribe(response => {
            const feeds = response;
            this.pushToUi(feeds)
            // console.log(this.feeds)
            if (!feeds) {
                console.log('no response')
            }
        }, error => {
            console.log(error);
        });
    }

    pushToUi(items) {
        if (items.length == 0) {
            console.log('no items')
            this.noMoreItems = true;
        }
        if (this.feeds) {
            this.feeds = this.feeds.concat(items)
        } else {
            this.feeds = items
        }
        // this.ArrayOptimization()
    }

    ArrayOptimization() {
        // if (this.feeds.length >= 5) {
        //     console.log('length > 5, length = ' + this.feeds.length)
        // }

        // THE CODE BELOW IS THE ACTUAL CODE THAT WILL BE USED:

        // THIS MAY NOT EVEN BE NECCESSARY, NEED TO DO TESTING

        // if (this.feeds.length >= 11) {
        //     this.feeds.splice(0, 5)
        //     console.log(this.feeds.length)
        // }
    }

    getUserById(item) {
        let newUrl = 'http://10.0.2.2:5000/api/users/' + item
        console.log(newUrl)
        this.http.get(newUrl).subscribe(response => {
            this.userService.singleUser = response;
            console.log(this.userService.singleUser)
            this.router.navigate(['/single-user/' + item])
        }, error => {
            console.log(error);
        });
    }

    like(item) {
        console.log(item.likes)
        item.likes = item.likes + 1
        console.log(item.likes)
    }

    goToUrl(url) {
        utils.openUrl('https://' + url);
    }

    loadVideoIOS() {
        this.router.navigate(['/video'])
    }

    nextPage() {
        this.pageNumber = this.pageNumber + 1
        this.getFeed()
    }


}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-17
    • 1970-01-01
    • 2021-04-21
    • 1970-01-01
    • 1970-01-01
    • 2016-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多