From 4474658d39abe377d8980fef7c42b1c1755d3597 Mon Sep 17 00:00:00 2001 From: jcass Date: Sat, 16 Apr 2016 17:10:52 +0200 Subject: [PATCH] Reduce number of DOM manipulations to improve performance. --- .gitignore | 2 + README.rst | 3 + .../static/js/functionsvars.js | 67 +++++++++++-------- mopidy_musicbox_webclient/static/js/gui.js | 1 - .../static/js/process_ws.js | 13 ++-- mopidy_musicbox_webclient/static/mb.appcache | 2 +- 6 files changed, 52 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index e66dbe5..8c6a739 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ npm-debug.log .project *.pbxproj *.egg-info +.cache +.eggs diff --git a/README.rst b/README.rst index 00fa03e..6076f85 100644 --- a/README.rst +++ b/README.rst @@ -85,6 +85,7 @@ v2.3.0 (UNRELEASED) (Addresses: `#133 `_). - Optimized updating of 'now playing' icons in tracklists. (Addresses: `#184 `_). +- Optimized rendering of large lists of tracks to make UI more responsive. **Fixes** @@ -93,6 +94,8 @@ v2.3.0 (UNRELEASED) - last.fm artist image lookups should now always return the correct image for similarly named artists. - Ensure that browsed tracks are always added to the queue using the track URI rather than the track's position in the folder. (Fixes: `#124 `_). +- Fixed an issue where searches would be performed as soon as the user switches to the 'Search' pane, + instead of waiting for the 'Search!' button to be clicked. v2.2.0 (2016-03-01) ------------------- diff --git a/mopidy_musicbox_webclient/static/js/functionsvars.js b/mopidy_musicbox_webclient/static/js/functionsvars.js index 83bb401..7079d62 100644 --- a/mopidy_musicbox_webclient/static/js/functionsvars.js +++ b/mopidy_musicbox_webclient/static/js/functionsvars.js @@ -175,6 +175,7 @@ function artistsToString (artists, max) { *********************************************************/ function albumTracksToTable (pl, target, uri) { var track, previousTrack, nextTrack + var html = '' $(target).empty() $(target).attr('data', uri) for (var i = 0; i < pl.length; i++) { @@ -182,8 +183,9 @@ function albumTracksToTable (pl, target, uri) { nextTrack = i < pl.length - 1 ? pl[i + 1] : undefined track = pl[i] popupData[track.uri] = track - renderSongLi(previousTrack, track, nextTrack, uri, '', target, i, pl.length) + html += renderSongLi(previousTrack, track, nextTrack, uri, '', target, i, pl.length) } + $(target).append(html) updatePlayIcons(songdata.track.uri, songdata.tlid, controls.getIconForAction()) } @@ -191,15 +193,16 @@ function renderSongLi (previousTrack, track, nextTrack, uri, tlid, target, curre var name var tlidParameter = '' var onClick = '' + var html = '' track.name = validateTrackName(track, currentIndex) // Leave out unplayable items if (track.name.substring(0, 12) === '[unplayable]') { - return + return html } // Streams if (track.length === -1) { - $(target).append('
  • ' + track.name + ' [Stream]

  • ') - return + html += '
  • ' + track.name + ' [Stream]

  • ' + return html } if (target === CURRENT_PLAYLIST_TABLE && typeof tlid === 'number' && tlid >= 0) { // Current queue: Show popup menu icon. onClick plays track. @@ -209,33 +212,33 @@ function renderSongLi (previousTrack, track, nextTrack, uri, tlid, target, curre onClick = 'return controls.playTracks(\'\', mopidy, \'' + track.uri + '\', \'' + uri + '\');' } - $(target).append( + html += '
  • ' + '' + '' + - '

    ' + track.name + '

  • ' - ) + '

    ' + track.name + '

    ' + if (listLength === 1 || !hasSameAlbum(previousTrack, track) && !hasSameAlbum(track, nextTrack)) { - renderSongLiAlbumInfo(track, target) - } - // TODO: remove this hard-coded conditions for 'ALBUM_TABLE' and 'BROWSE_TABLE' - if (target !== ALBUM_TABLE && target !== BROWSE_TABLE && !hasSameAlbum(previousTrack, track)) { - // Starting to render a new album in the list. - renderSongLiDivider(track, nextTrack, currentIndex, target) + html += renderSongLiAlbumInfo(track) } + html += '
    ' + return html } +/* Tracklist renderer for track artist and album name. */ function renderSongLiAlbumInfo (track, target) { - var html = '

    ' - html += renderSongLiTrackArtists(track) + var html = renderSongLiTrackArtists(track) if (track.album && track.album.name) { html += ' - ' + track.album.name + '

    ' } - target = getjQueryID(target, track.uri, true) - $(target).children('a').eq(1).append(html) - $(target + ' a h1 i').addClass(getMediaClass(track.uri)) + if (typeof target !== 'undefined' && target.length > 0) { + target = getjQueryID(target, track.uri, true) + $(target).children('a').eq(1).append(html) + } + return html } +/* Tracklist renderer for track artist information. */ function renderSongLiTrackArtists (track) { var html = '' if (track.artists) { @@ -252,23 +255,28 @@ function renderSongLiTrackArtists (track) { return html } -function renderSongLiDivider (track, nextTrack, currentIndex, target) { - target = getjQueryID(target, track.uri, true) - // Render differently if part of an album - if (hasSameAlbum(track, nextTrack)) { - // Large divider with album cover - $(target).before( +/* Tracklist renderer to insert dividers between albums. */ +function renderSongLiDivider (previousTrack, track, nextTrack, currentIndex, target) { + var html = '' + // Render differently if part of an album. + if (!hasSameAlbum(previousTrack, track) && hasSameAlbum(track, nextTrack)) { + // Large divider with album cover. + html += '
  • ' + '' + '

    ' + track.album.name + '

    ' + renderSongLiTrackArtists(track) + '

  • ' - ) // Retrieve album covers images.setAlbumImage(track.uri, getjQueryID(target + '-cover', track.uri, true), mopidy, 'small') - } else if (currentIndex > 0) { + } else if (!hasSameAlbum(track, nextTrack) && currentIndex > 0) { // Small divider - $(target).before('
  •  
  • ') + html += '
  •  
  • ' } + if (typeof target !== 'undefined' && target.length > 0) { + target = getjQueryID(target, track.uri, true) + $(target).before(html) + } + return html } function renderSongLiBackButton (results, target, onClick, optional) { @@ -317,6 +325,7 @@ function resultsToTables (results, target, uri, onClickBack, backIsOptional) { $(target).attr('data', uri) var track, previousTrack, nextTrack, tlid + var html = '' // Break into albums and put in tables for (i = 0; i < results.length; i++) { @@ -331,9 +340,11 @@ function resultsToTables (results, target, uri, onClickBack, backIsOptional) { nextTrack = nextTrack ? nextTrack.track : undefined } popupData[track.uri] = track - renderSongLi(previousTrack, track, nextTrack, uri, tlid, target, i, results.length) + html += renderSongLiDivider(previousTrack, track, nextTrack, i, target) + html += renderSongLi(previousTrack, track, nextTrack, uri, tlid, target, i, results.length) } } + $(target).append(html) updatePlayIcons(songdata.track.uri, songdata.tlid, controls.getIconForAction()) } diff --git a/mopidy_musicbox_webclient/static/js/gui.js b/mopidy_musicbox_webclient/static/js/gui.js index 41f1dca..a175b52 100644 --- a/mopidy_musicbox_webclient/static/js/gui.js +++ b/mopidy_musicbox_webclient/static/js/gui.js @@ -419,7 +419,6 @@ function locationHashChanged () { case 'search': $('#navsearch a').addClass($.mobile.activeBtnClass) $('#searchinput').focus() - library.initSearch($('#searchinput').val()) break case 'stream': $('#navstream a').addClass('ui-state-active ui-state-persist ui-btn-active') diff --git a/mopidy_musicbox_webclient/static/js/process_ws.js b/mopidy_musicbox_webclient/static/js/process_ws.js index b6464d4..794c17e 100644 --- a/mopidy_musicbox_webclient/static/js/process_ws.js +++ b/mopidy_musicbox_webclient/static/js/process_ws.js @@ -89,6 +89,7 @@ function processBrowseDir (resultArr) { var uri = resultArr[0].uri var length = 0 || resultArr.length customTracklists[BROWSE_TABLE] = [] + var html = '' for (var i = 0, index = 0; i < resultArr.length; i++) { if (resultArr[i].type === 'track') { @@ -100,7 +101,7 @@ function processBrowseDir (resultArr) { customTracklists[BROWSE_TABLE].push(ref) uris.push(ref.uri) - renderSongLi(previousRef, ref, nextRef, BROWSE_TABLE, '', BROWSE_TABLE, index, resultArr.length) + html += renderSongLi(previousRef, ref, nextRef, BROWSE_TABLE, '', BROWSE_TABLE, index, resultArr.length) index++ } else { @@ -110,13 +111,13 @@ function processBrowseDir (resultArr) { } else { iconClass = getMediaClass(resultArr[i].uri) } - $(BROWSE_TABLE).append( - '
  • ' + - '

    ' + resultArr[i].name + '

  • ' - ) + html += '
  • ' + + '

    ' + resultArr[i].name + '

  • ' } } + $(BROWSE_TABLE).append(html) + updatePlayIcons(songdata.track.uri, songdata.tlid, controls.getIconForAction()) if (uris.length > 0) { @@ -138,7 +139,7 @@ function processBrowseDir (resultArr) { } if (!hasSameAlbum(previousTrack, track)) { // Starting to render a new album in the list. - renderSongLiDivider(track, nextTrack, i, BROWSE_TABLE) + renderSongLiDivider(previousTrack, track, nextTrack, i, BROWSE_TABLE) } } }) diff --git a/mopidy_musicbox_webclient/static/mb.appcache b/mopidy_musicbox_webclient/static/mb.appcache index 6e558db..eca4c70 100644 --- a/mopidy_musicbox_webclient/static/mb.appcache +++ b/mopidy_musicbox_webclient/static/mb.appcache @@ -1,6 +1,6 @@ CACHE MANIFEST -# 2016-04-26:v2 +# 2016-04-27:v1 NETWORK: *