 						]
 						console.log 'resolving layoutReady with', scope.parentSize
 						$timeout () ->
-							spinner.add(element)
+							if not spinnerTimer?
+								spinnerTimer = setTimeout () ->
+									spinner.add(element)
+									spinnerTimer = null
+								, 100
 							layoutReady.resolve scope.parentSize
 							scope.$emit 'flash-controls'
 
-				updateLayout()
+				layoutTimer = null
+				queueLayout = () ->
+					console.log 'call to queue layout'
+					return if layoutTimer?
+					console.log 'added to queue layoyt'
+					layoutReady = $q.defer()
+					layoutTimer = setTimeout () ->
+						console.log 'calling update layout'
+						updateLayout()
+						console.log 'setting layout timer to null'
+						layoutTimer = null
+					, 0
+
+				queueLayout()
+
+				scope.$on 'layout:pdf:view', (e, args) ->
+					console.log 'pdf view change', element, e, args
+					queueLayout()
 
 				scope.$on 'layout:main:resize', () ->
 					console.log 'GOT LAYOUT-MAIN-RESIZE EVENT'
-					updateLayout()
+					queueLayout()
 
 				scope.$on 'layout:pdf:resize', () ->
 					# FIXME we get this event twice
 					# also we need to start a new layout when we get it
 					console.log 'GOT LAYOUT-PDF-RESIZE EVENT'
-					updateLayout()
+					queueLayout()
 
 				scope.$on 'pdf:error', (event, error) ->
 					return if error == 'cancelled'

					# console.log 'forceCheck', newVal, oldVal
					return unless newVal?
					scope.adjustingScroll = true  # temporarily disable scroll
					doRescale scope.scale

				scope.$watch('parentSize', (newVal, oldVal) ->
					# console.log 'XXX in parentSize watch', newVal, oldVal

					# return unless oldVal?
					# console.log 'XXX calling setScale in parentSize watcher'
					return unless newVal?
					queueRescale scope.scale
				, true)

				# scope.$watch 'elementWidth', (newVal, oldVal) ->
