diff --git a/changes/changelog.d/310.bugfix b/changes/changelog.d/310.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..fed21ded8978942b3586334e51eefabd999e258e
--- /dev/null
+++ b/changes/changelog.d/310.bugfix
@@ -0,0 +1 @@
+Fixed current track restart/hiccup when shuffling queue, deleting track from queue or reordering (#310)
diff --git a/front/src/components/Sidebar.vue b/front/src/components/Sidebar.vue
index 5415e1b0e036e66b83cb72f4e8611b376550e15d..9eec6c0e2721f50ba9209474cabddf028ca4c163 100644
--- a/front/src/components/Sidebar.vue
+++ b/front/src/components/Sidebar.vue
@@ -116,8 +116,8 @@
     </div>
     <div class="ui bottom attached tab" data-tab="queue">
       <table class="ui compact inverted very basic fixed single line unstackable table">
-        <draggable v-model="queue.tracks" element="tbody" @update="reorder">
-          <tr @click="$store.dispatch('queue/currentIndex', index)" v-for="(track, index) in queue.tracks" :key="index" :class="[{'active': index === queue.currentIndex}]">
+        <draggable v-model="tracks" element="tbody" @update="reorder">
+          <tr @click="$store.dispatch('queue/currentIndex', index)" v-for="(track, index) in tracks" :key="index" :class="[{'active': index === queue.currentIndex}]">
               <td class="right aligned">{{ index + 1}}</td>
               <td class="center aligned">
                   <img class="ui mini image" v-if="track.album.cover" :src="$store.getters['instance/absoluteUrl'](track.album.cover)">
@@ -176,6 +176,7 @@ export default {
     return {
       selectedTab: 'library',
       backend: backend,
+      tracksChangeBuffer: null,
       isCollapsed: true,
       fetchInterval: null
     }
@@ -207,6 +208,14 @@ export default {
       return adminPermissions.filter(e => {
         return e
       }).length > 0
+    },
+    tracks: {
+      get () {
+        return this.$store.state.queue.tracks
+      },
+      set (value) {
+        this.tracksChangeBuffer = value
+      }
     }
   },
   methods: {
@@ -219,7 +228,7 @@ export default {
     },
     reorder: function (event) {
       this.$store.commit('queue/reorder', {
-        oldIndex: event.oldIndex, newIndex: event.newIndex})
+        tracks: this.tracksChangeBuffer, oldIndex: event.oldIndex, newIndex: event.newIndex})
     },
     scrollToCurrent () {
       let current = $(this.$el).find('[data-tab="queue"] .active')[0]
diff --git a/front/src/components/audio/Player.vue b/front/src/components/audio/Player.vue
index 1cc27970b47aabc5571047713d1ee45e3f7b853a..8eecb232f67b770be9f28477c4a3380f56a3607d 100644
--- a/front/src/components/audio/Player.vue
+++ b/front/src/components/audio/Player.vue
@@ -1,16 +1,16 @@
 <template>
   <div class="ui inverted segment player-wrapper" :style="style">
     <div class="player">
-      <audio-track
-        ref="currentAudio"
-        v-if="renderAudio && currentTrack"
-        :key="currentTrack.id"
-        :is-current="true"
-        :start-time="$store.state.player.currentTime"
-        :autoplay="$store.state.player.playing"
-        :track="currentTrack">
-      </audio-track>
-
+      <keep-alive>
+        <audio-track
+          ref="currentAudio"
+          v-if="renderAudio && currentTrack"
+          :is-current="true"
+          :start-time="$store.state.player.currentTime"
+          :autoplay="$store.state.player.playing"
+          :track="currentTrack">
+        </audio-track>
+      </keep-alive>
       <div v-if="currentTrack" class="track-area ui unstackable items">
         <div class="ui inverted item">
           <div class="ui tiny image">
diff --git a/front/src/components/audio/Track.vue b/front/src/components/audio/Track.vue
index 2ded7cb0076f29b2f78956aae2ff8703fb2da9c8..9be38337717e8d024e3f711e019a960762d7c355 100644
--- a/front/src/components/audio/Track.vue
+++ b/front/src/components/audio/Track.vue
@@ -4,7 +4,7 @@
     @error="errored"
     @loadeddata="loaded"
     @durationchange="updateDuration"
-    @timeupdate="updateProgress"
+    @timeupdate="updateProgressThrottled"
     @ended="ended"
     preload>
     <source
@@ -30,6 +30,7 @@ export default {
   },
   data () {
     return {
+      realTrack: this.track,
       sourceErrors: 0,
       isUpdatingTime: false
     }
@@ -43,7 +44,7 @@ export default {
       looping: state => state.player.looping
     }),
     srcs: function () {
-      let file = this.track.files[0]
+      let file = this.realTrack.files[0]
       if (!file) {
         this.$store.dispatch('player/trackErrored')
         return []
@@ -61,6 +62,9 @@ export default {
         })
       }
       return sources
+    },
+    updateProgressThrottled () {
+      return _.throttle(this.updateProgress, 250)
     }
   },
   methods: {
@@ -100,30 +104,40 @@ export default {
         }
       }
     },
-    updateProgress: _.throttle(function () {
+    updateProgress: function () {
       this.isUpdatingTime = true
       if (this.$refs.audio) {
         this.$store.dispatch('player/updateProgress', this.$refs.audio.currentTime)
       }
-    }, 250),
+    },
     ended: function () {
       let onlyTrack = this.$store.state.queue.tracks.length === 1
       if (this.looping === 1 || (onlyTrack && this.looping === 2)) {
         this.setCurrentTime(0)
         this.$refs.audio.play()
       } else {
-        this.$store.dispatch('player/trackEnded', this.track)
+        this.$store.dispatch('player/trackEnded', this.realTrack)
       }
     },
     setCurrentTime (t) {
       if (t < 0 | t > this.duration) {
         return
       }
-      this.updateProgress(t)
+      if (t === this.$refs.audio.currentTime) {
+        return
+      }
+      if (t === 0) {
+        this.updateProgressThrottled.cancel()
+      }
       this.$refs.audio.currentTime = t
     }
   },
   watch: {
+    track: _.debounce(function (newValue) {
+      this.realTrack = newValue
+      this.setCurrentTime(0)
+      this.$refs.audio.load()
+    }, 1000, {leading: true, trailing: true}),
     playing: function (newValue) {
       if (newValue === true) {
         this.$refs.audio.play()
@@ -131,6 +145,11 @@ export default {
         this.$refs.audio.pause()
       }
     },
+    '$store.state.queue.currentIndex' () {
+      if (this.$store.state.player.playing) {
+        this.$refs.audio.play()
+      }
+    },
     volume: function (newValue) {
       this.$refs.audio.volume = newValue
     },
diff --git a/front/src/store/queue.js b/front/src/store/queue.js
index 2d6c667b29ba5e87623f3cc60e7be31e0d5d3fc4..0435c867ee1137c308f997bd2442a330fa0ffcf8 100644
--- a/front/src/store/queue.js
+++ b/front/src/store/queue.js
@@ -31,9 +31,10 @@ export default {
     insert (state, {track, index}) {
       state.tracks.splice(index, 0, track)
     },
-    reorder (state, {oldIndex, newIndex}) {
+    reorder (state, {tracks, oldIndex, newIndex}) {
       // called when the user uses drag / drop to reorder
       // tracks in queue
+      state.tracks = tracks
       if (oldIndex === state.currentIndex) {
         state.currentIndex = newIndex
         return
@@ -102,7 +103,7 @@ export default {
       }
       if (current) {
         // we play next track, which now have the same index
-        dispatch('currentIndex', index)
+        commit('currentIndex', index)
       }
       if (state.currentIndex + 1 === state.tracks.length) {
         dispatch('radios/populateQueue', null, {root: true})
@@ -156,7 +157,6 @@ export default {
       let toKeep = state.tracks.slice(0, state.currentIndex + 1)
       let toShuffle = state.tracks.slice(state.currentIndex + 1)
       let shuffled = toKeep.concat(_.shuffle(toShuffle))
-      commit('player/currentTime', 0, {root: true})
       commit('tracks', [])
       let params = {tracks: shuffled}
       if (callback) {
diff --git a/front/test/unit/specs/store/queue.spec.js b/front/test/unit/specs/store/queue.spec.js
index 3a59117d54f8d833f0a35ffe63884981849030fd..cc2f04fa087714cd8a0fcb8afc03be87ab9688f9 100644
--- a/front/test/unit/specs/store/queue.spec.js
+++ b/front/test/unit/specs/store/queue.spec.js
@@ -169,11 +169,11 @@ describe('store/queue', () => {
         payload: 2,
         params: {state: {currentIndex: 2}},
         expectedMutations: [
-          { type: 'splice', payload: {start: 2, size: 1} }
+          { type: 'splice', payload: {start: 2, size: 1} },
+          { type: 'currentIndex', payload: 2 }
         ],
         expectedActions: [
-          { type: 'player/stop', payload: null, options: {root: true} },
-          { type: 'currentIndex', payload: 2 }
+          { type: 'player/stop', payload: null, options: {root: true} }
         ]
       }, done)
     })
@@ -324,7 +324,6 @@ describe('store/queue', () => {
         action: store.actions.shuffle,
         params: {state: {currentIndex: 1, tracks: tracks}},
         expectedMutations: [
-          { type: 'player/currentTime', payload: 0, options: {root: true} },
           { type: 'tracks', payload: [] }
         ],
         expectedActions: [
diff --git a/front/test/unit/specs/store/ui.spec.js b/front/test/unit/specs/store/ui.spec.js
index adcfa87d8f34bd600f113fc4100c0c6318bc730e..ddce055a571e887a3b7bf3bcefdff901e033ea40 100644
--- a/front/test/unit/specs/store/ui.spec.js
+++ b/front/test/unit/specs/store/ui.spec.js
@@ -1,7 +1,5 @@
 import store from '@/store/ui'
 
-import { testAction } from '../../utils'
-
 describe('store/ui', () => {
   describe('mutations', () => {
     it('addMessage', () => {