diff --git a/src/containers/blocks.jsx b/src/containers/blocks.jsx
index d27e91668c10580cc8a407b89e66902857b94e36..9bf3aafb8e35a68438c72316741b999d20e91065 100644
--- a/src/containers/blocks.jsx
+++ b/src/containers/blocks.jsx
@@ -6,6 +6,15 @@ const VM = require('scratch-vm');
 
 const BlocksComponent = require('../components/blocks/blocks.jsx');
 
+const addFunctionListener = (object, property, callback) => {
+    const oldFn = object[property];
+    object[property] = function () {
+        const result = oldFn.apply(this, arguments);
+        callback.apply(this, result);
+        return result;
+    };
+};
+
 class Blocks extends React.Component {
     constructor (props) {
         super(props);
@@ -19,14 +28,24 @@ class Blocks extends React.Component {
             'onBlockGlowOff',
             'onVisualReport',
             'onWorkspaceUpdate',
+            'onWorkspaceMetricsChange',
             'setBlocks'
         ]);
+        this.state = {workspaceMetrics: {}};
     }
     componentDidMount () {
         const workspaceConfig = defaultsDeep({}, Blocks.defaultOptions, this.props.options);
         this.workspace = this.ScratchBlocks.inject(this.blocks, workspaceConfig);
+
+        // @todo change this when blockly supports UI events
+        addFunctionListener(this.workspace, 'translate', this.onWorkspaceMetricsChange);
+        addFunctionListener(this.workspace, 'zoom', this.onWorkspaceMetricsChange);
+
         this.attachVM();
     }
+    shouldComponentUpdate () {
+        return false;
+    }
     componentWillUnmount () {
         this.detachVM();
         this.workspace.dispose();
@@ -52,6 +71,19 @@ class Blocks extends React.Component {
         this.props.vm.off('VISUAL_REPORT', this.onVisualReport);
         this.props.vm.off('workspaceUpdate', this.onWorkspaceUpdate);
     }
+    onWorkspaceMetricsChange () {
+        const target = this.props.vm.editingTarget;
+        if (target && target.id) {
+            const workspaceMetrics = Object.assign({}, this.state.workspaceMetrics, {
+                [target.id]: {
+                    scrollX: this.workspace.scrollX,
+                    scrollY: this.workspace.scrollY,
+                    scale: this.workspace.scale
+                }
+            });
+            this.setState({workspaceMetrics});
+        }
+    }
     onScriptGlowOn (data) {
         this.workspace.glowStack(data.id, true);
     }
@@ -68,12 +100,25 @@ class Blocks extends React.Component {
         this.workspace.reportValue(data.id, data.value);
     }
     onWorkspaceUpdate (data) {
+        if (this.props.vm.editingTarget && !this.state.workspaceMetrics[this.props.vm.editingTarget.id]) {
+            this.onWorkspaceMetricsChange();
+        }
+
         this.ScratchBlocks.Events.disable();
         this.workspace.clear();
+
         const dom = this.ScratchBlocks.Xml.textToDom(data.xml);
         this.ScratchBlocks.Xml.domToWorkspace(dom, this.workspace);
         this.ScratchBlocks.Events.enable();
         this.workspace.toolbox_.refreshSelection();
+
+        if (this.props.vm.editingTarget && this.state.workspaceMetrics[this.props.vm.editingTarget.id]) {
+            const {scrollX, scrollY, scale} = this.state.workspaceMetrics[this.props.vm.editingTarget.id];
+            this.workspace.scrollX = scrollX;
+            this.workspace.scrollY = scrollY;
+            this.workspace.scale = scale;
+            this.workspace.resize();
+        }
     }
     setBlocks (blocks) {
         this.blocks = blocks;