HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Retrieve and load playlists from YouTube

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
youtuberetrieveloadandfromplaylists

Problem

I have this code I am using in a private project. The following is a snippet of code I use to retrieve and load playlists from YouTube:

for (feedEntry in a.feed.entry) {
  if (a.feed.entry.hasOwnProperty(feedEntry)) {
  feedTitle = a.feed.entry[feedEntry].title.$t.replace('] - ', ']').replace(' : ', '').replace(/\(.*?\)/g, "").replace(/\[.*?\]/g, "");
  feedURL = a.feed.entry[feedEntry].link[1].href;
  fragments = feedURL.split("/");
  videoID = fragments[fragments.length - 2];
  url = videoURL + videoID;
  var c = feedTitle.split(' - ');
  tracklist.push({
    'title': c[1],
    'artist': c[0],
    'url': 'http://youtubeinmp3.com/fetch/?video=http://www.youtube.com/watch?v=' + videoID + '',
    'album': 'YouTube'
  })
}


This code, understandably, causes the browser to freeze a few seconds when loading larger playlists.

What ways could I go about optimizing this?

Solution

The freezing comes primarily from the fact that JavaScript is single-threaded so when your loop is busy-looping everything else will wait until the scope has finished before the browser can continue to poll on the event queue.

To solve this you can convert your code to asynchronous executing using setTimeout() to allow the browser to do other tasks in-between.

Another thing is that for in loops are very slow so this can be replaced by using Object keys instead.

Your parsing can be optimized by caching the current object as well as re-factor the parsing itself to a separate function method:

var keys = Object.keys(a.feed.entry),  // retrieve all keys from the object
    count = keys.length,               // number of keys to parse
    segment = 10,                      // number to parse each segment
    current;                           // counter for segment

// start loop
(function doSegment() {

    current = segment;                 // reset segment counter for each iteration

    while(current-- && count)
        parseFeedEntry(a.feed.entry[keys[--count]]);

    if (count)
        setTimeout(doSegment, 11);     // delay 11ms to allow browser to breath
})();

function parseFeedEntry(entry) {
    // parse the entry here
    var feedTitle = entry.title.$t.replace('] - ', ']'). ...8X...
    // etc., notice entry is now cached
}


Online demo

Hope this helps!

Code Snippets

var keys = Object.keys(a.feed.entry),  // retrieve all keys from the object
    count = keys.length,               // number of keys to parse
    segment = 10,                      // number to parse each segment
    current;                           // counter for segment

// start loop
(function doSegment() {

    current = segment;                 // reset segment counter for each iteration

    while(current-- && count)
        parseFeedEntry(a.feed.entry[keys[--count]]);

    if (count)
        setTimeout(doSegment, 11);     // delay 11ms to allow browser to breath
})();

function parseFeedEntry(entry) {
    // parse the entry here
    var feedTitle = entry.title.$t.replace('] - ', ']'). ...8X...
    // etc., notice entry is now cached
}

Context

StackExchange Code Review Q#41804, answer score: 7

Revisions (0)

No revisions yet.