【问题标题】:Faster API calls with Javascript使用 Javascript 更快地调用 API
【发布时间】:2013-08-13 17:46:55
【问题描述】:

我正在制作一个名为“Your Life in Music”的应用程序,用户在其中插入他/她的生日,该应用程序会显示自他们出生以来每个生日的热门广告牌。该应用程序目前非常慢,因为从 Last.fm api 检索所有专辑封面图像需要一段时间。我想知道如何使用 JS/jQuery 加速 API 调用。似乎线程可以解决这个问题,但我不确定如何实现......

这是应用程序:http://www.dailyspiro.com

以及关键代码:

function compileDisplay(birthDays) {
    // create an HTML list that for each birthday displays top song, artist, and album art
    htmlObj = {}
    for (i = 0; i < birthDays.length; i++) {
        var age = birthDays[i][0]; // age isn't equal to i if user was born before 1958
        var date = birthDays[i][1];
        try {
            var track = billboard[date]['song'];
        } catch (err) {
            console.log(date)
        }
        var artist = billboard[date]['artist'];
        getAlbumArt(age, track, artist, birthDays);
    }
}

function getAlbumArt(age, track, artist, birthDays) {
    $.getJSON("http://ws.audioscrobbler.com/2.0/?method=track.getInfo&api_key=6ad5bad28ffc4dedbcf1115b3ddf5273&artist=" + artist + "&track=" + track + "&format=json&callback=?", function (data) {
        try {
            var image = data.track.album.image[2]['#text'];
            if (image == 'http://cdn.last.fm/flatness/catalogue/noimage/2/default_album_medium.png') {
                throw 'generic image';
            }
        } catch (err) {
            var image = 'images/' + track + '.jpg';
        }
        compileHtml(age, track, artist, image, birthDays)
    })
}

【问题讨论】:

  • 这取决于服务 api .. 这不取决于你 .. 不能用 javascript 加速它。
  • ajax 调用已经是异步的,看起来你并没有在任何地方阻塞。您可以查看浏览器工具的网络选项卡,了解每个请求实际花费了多长时间。
  • API 调用已经是并行的(但很多,不确定是否可以优化)。然而,您的应用程序感觉缓慢似乎来自轮播脚本等待所有图像加载(这需要相当长的时间)
  • 您可以做的一件事是为所有可能的生日预加载数据——也许一旦他们填写了月份,而不是当天,开始获取该月所有日子的 JSON?不过,他们可能不喜欢你一次访问他们的服务器 30 次。
  • 看起来您的 javascript 大约需要 140 毫秒,而 ajax 调用(对我来说)大约需要 1.5 秒。所以花费的时间是在显示轮播之前加载图像。如果您可以将所有 API 调用合并到一个请求中,您可能需要一秒钟左右的时间。您也可以尝试在以某种方式显示轮播之前不要等待所有图像加载。

标签: javascript jquery performance api


【解决方案1】:

这确实需要很长时间……尤其是对于像我这样的老前辈!

我建议您开始使用默认图像构建轮播,然后在加载时将其替换为实际图像。

顺便说一句,好主意!

【讨论】:

  • 谢谢!那是个很好的观点。我只是做了类似的事情......改变了轮播,这样它就不会在显示之前预加载所有图像。现在速度有点快……
【解决方案2】:

一般说明:

  1. 您缺少很多 ;在某些行的末尾

  2. birthDays 对象的最后一个元素后面有一个 , 这是错误的

  3. birthDays 对象很大(如果可以,请尝试找出另一种处理方式。

  4. 除了上面提出的家伙的建议(特别是@Jason P 关于将所有请求合并为一个的评论),我建议以下:


由于birthDays 很大,我建议每隔 5 年或 10 年创建多个对象 这将加快循环速度


缺点是你现在必须循环多个对象,所以也许你可以像这样组织它们

{ d60To65:{........}, d65To70:{........} ..... }

另外,这会增加代码的复杂性


注意:js 对象按照规范是无序的(你的内部对象就是这种情况 - 生日)

出于这个原因,我建议您使用 JS 链表来确保排序

http://www.nczonline.net/blog/2009/04/13/computer-science-in-javascript-linked-list/

5- 修复你的循环可能像这样for (var i = 0, l = birthDay.length; i &lt; l; i++)

6- 将变量直接放在函数启动之后,而不是在每个循环中创建它们

 var age = 0; //number as it can't be otherwise and now you can easily make checks on it
    var date = ""; //a string for the same reasons as age
    var artist = ""; //same comment
    var track = ""; //same comment

对函数中的变量的相同注释(您可能会在其中找到它们)

7- 如果您发现自己使用 js 日期,您可能需要检查 Moment.js,因为它有一些实用功能

希望对你有所帮助

由于某种原因,轮播无法在 Firefox 22 上运行(如果您需要支持)

【讨论】:

  • 非常有用的答案和很棒的提示!作为后续问题,我如何将 API 调用合并到一个请求中? (我是一个新手,所以不知道如何做到这一点......)
  • 来自 api,我没有看到任何为您的案例提供合并的东西。但是,我注意到您可能可以使用其他 api 调用,特别是 last.fm/api/show/user.getTopTracks,如果您可以在 last.fm 帐户上列出与birthDays 相同的热门曲目列表(这次按排名排序到 last.fm 的日期)并在birthDays 中将日期与排名相匹配,例如“9-8-1990”:“1”(在您的情况下为“艺术家”:“Jon Bon Jovi”,“歌曲”:“Blaze Of Glory"
  • 继续这个想法,按日期排序(所以我上面的例子不正确),因此 1 将匹配 "8-9-1958": {"artist": "Ricky Nelson" , "song": "Poor Little Fool"} 等等,这将使您更容易过滤它们并提取所需的信息请注意,如果您获得所有信息,如果您可以遵循@skatanick 的建议,那就是最好的,因为我认为信息不会从请求更改为其他信息(因此在您的服务器上缓存是可行的方法),如果您可以根据需要进行一些服务器排序和过滤,那将是您的最佳选择
  • 大声笑“你需要在行尾使用分号”。这个答案是旧的!
【解决方案3】:

如果 API 允许(检查用户协议),您可以尝试将 API 数据缓存或存储在您的服务器上,这样您就不必在每次加载应用程序时都连接到 API。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 2020-10-03
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    相关资源
    最近更新 更多