Simulating a slow network with a component

Build a component that uses the localStorage API to adjust Mirage's response time during development.

Summary

It can be useful to simulate a slow network while developing Ember apps, so we can see what they look like if our users experience a spotty connection.

When using Mirage, you can adjust the server's response time for all requests using server.timing:

// mirage/config.js
export default function() {
  this.timing = 5000;
}

You could make this a bit easier by making the server instance available globally, so you can change things in the console:

// mirage/config.js
export default function() {
  window.server = this;
}

Now in the console during development, we can type server.timing = 2000 to change our server speed.

One problem with this is that because Mirage's state is all client-side, we can never see what the initial page load looks like on a slow network, since any changes we make in the console are lost when the browser reloads.

Let's use localStorage to persist our changes across page reloads. If we read from localStorage in Mirage's config:

this.timing = window.localStorage.getItem('timing') || 200;

Then we can set this timing value to anything we want, and Mirage will read from it on initialization. That means we can open the console and write

localStorage.setItem('timing', 6000);

reload the page, and see our app render on a slow network.

But we can do better than that! Opening the console and writing that code every time is a hassle, and we are UI developers after all. Let's make a UI component that's bound to this localStorage property.

import Component from '@ember/component';
import { computed } from '@ember/object';

export default Component.extend({
  timing: computed({
    get() {
      return window.localStorage.getItem('timing');
    },

    set(key, value) {
      window.localStorage.setItem('timing', value);
      window.server.timing = +value;

      return value;
    }
  }),

  actions: {
    updateTiming(event) {
      this.set('timing', event.target.value);
    }
  }
});
<div class='
  absolute pin-r pin-b w-2/5
  bg-white p-3 mr-4 mb-4
  border-blue border-2 shadow
'>

  <h2 class="m-0 p-0 mb-3">Speed control</h2>

  <div class="flex items-center">
    <input type="range"
      min="0"
      max="10000"
      step="100"
      value={{timing}}
      oninput={{action "updateTiming"}}
      class="w-4/5">

    <div class="ml-auto">
      {{timing}} ms
    </div>
  </div>

</div>

Now we can render {{speed-control}} in our Application template, drag the slider, and control the speed of our Mirage server. Neat!

👋 Hey there, Ember dev!

We hope you enjoyed this free video 🙂

If you like it and want to keep learning with us, we've written a free 6-lesson email course about the fundamental patterns of modern component design in Ember.

To get the first lesson now, enter your best email address below:

You can also check out more details about the course by clicking here.

Questions?

Send us a tweet:

Or ask us in Inside EmberMap, our private Slack workspace for subscribers.