Emerge

How to use Emerge to make your website load nicely

Most web pages don’t load pleasantly. Loading takes time, images and other elements appear in a random order. Content jumps when new elements load above it. Some things are unreadable before a font or a background is loaded. We are used to this.

Desktop apps are different: an app’s user interface would appear only after it’s loaded. The apps that are slow to load show splash screens.

The desktop approach looks more polished. But on the web, we can start reading and even using a page before it’s fully loaded.

How can we take the best of the two worlds? We can gradually show a page, but make sure it looks fine at every step of this progressive loading. And we’ll try to minimise the jumping. I call this “coordinated loading”.

Emerge is a JavaScript library that I’ve created to help add coordinated loading to your website. Normally you would need to manually write a lot of code to do this. But with Emerge, you just specify the desired behaviour with HTML attributes. Let’s see how you can use it on your website.

Prepare: provide boxes for images and other external objects

Before we even start using Emerge, let’s fix one thing. Consider this code:

<img src="some.jpg" />
<p>Text</p>

Before the browser has loaded the image, it has no idea how much space to provide for it. So it first just shows the text as if there was no image. When it starts loading the image and figures out its size, the layout changes for the image to fit. So the text jumps down.

To avoid the jumping, specify all images sizes:

<img src="image.png" width="200" height="300" />
<p>Text</p>

Here’s how you can do this with PHP (5.4 or later):

<img src="image.png" <?= getimagesize ('image.png')['attribute'] ?> />
<p>Text</p>

But what if you want an image to be flexible, i.e. occupy 100% of the container width?

<img src="photo.jpg" width="100%" />

In this case, to avoid the jumping, you’ll need a container with fixed proportions. Let’s say you have a 3:2 photo. Here’s a way to do it:

<div style="position: relative; padding-bottom: 66.67%">
<img style="position: absolute" src="photo.jpg" width="100%" />
</div>

Paddings’ percentages are always percentages of width, even for vertical padding. So the div will have 3:2 proportions even before the photo is loaded. PHP code:

<?php $size = getimagesize ('photo.jpg'); ?>
<div style="position: relative; padding-bottom:
	<?=round (100*$size['height']/$size['weight'], 2) ?>%">
<img style="position: absolute" src="photo.jpg" width="100%" />
</div>

The same can be done with videos.

Figure out which elements of the page make no sense unless they are fully loaded

OK, appearing images will no longer cause jumping. That’s a win already.

But with the Emerge script added to your page, you can do more. Use class “emerge” in an image to make it fade in (“emerge”) when loaded:

<img … class="emerge" />

What if your image has a caption which makes no sense unless the image is loaded? Actually, you can wrap elements in divs with class “emerge”:

<div class="emerge">
  <!-- Text, images and what not -->
</div>

You can put multiple images and videos into such div. The div will emerge only after all images and videos inside it are loaded.

Add a loading spinner for large elements

Some of your emerge elements may be quite large and take considerable time to load. The user may be confused by a large empty space on a page. So you can ask Emerge to display a loading indicator while such elements load:

<div class="emerge" data-spin="true">
  <!-- Show spinner while this is loading -->
</div>

Emerge has a built-in spinner with variable size, color and spin direction. If you want a custom spinner, Emerge supports them too. The documentation explains spinners in detail.

Make sure things appear in order

It may happen that an element which is lower on a page loads and emerges before the one which is above it. This may look strange and you may want to make sure the element load in a particular order.

Here is the easiest way to make an emerge element wait for the previous one to load:

<div class="emerge">
  <!-- Some content -->
</div>
<div class="emerge" data-continue="true">
  <!-- This will wait for the previous element to emerge first -->
</div>

The attribute data-continue means that even when this element’s images and videos are ready, it would emerge only after the previous one. You can chain many elements this way. If document order is not what you want, there is also a way to make one element wait for a particular other element by its id.

Select effect that make your site look best

By default, elements emerge by just fading in. But this is also adjustable.

Here are some examples of what you can do. You can make an element slide horizontally or vertically while it emerges:

<div class="emerge" data-effect="slide" data-up="20px">
  <!-- Stuff that will slide up 20px while emerging -->
</div>

Use data-down, data-left or data-right to change this. You can combine a horisontal and vertical parameters for diagonal motion.

Or you can make an element zoom-in:

<div class="emerge" data-effect="zoom">
  <!-- This will zoom in while emerging -->
</div>

Tune the original size with data-scale=“0.8” (or another value).

You can control an animation duration with data-duration (in ms).

There are other effects, which you can read about in the documentation. You can also provide an exact CSS for initial and final animation states.

Experiment and have fun

Since Emerge does not require you to write JavaScript, it’s very easy to experiment with. Find the way for your website to load in the best possible way.

But make sure you use the effects to improve the way your site loads, not make it too flashy and distracting. Don’t wrap the whole page into an emerging div: the user won’t see anything before everything is loaded, and your website will feel very slow.

The idea is to find elements that make sense only as a group, and make such groups appear in a single fade-in animation when ready. And then coordinate the order and motion for these groups.

May 14   Emerge

Emerge 1.3 with video support and replay control

In 2013, I released Emerge, a page load coordinator:

Normally, when a complex web page is loading, elements appear in random order, causing unpleasant flashing. To replace it with nice and coordinated animations, programming is required. Emerge.js simplifies the task by removing the need to write any JavaScript code. The framework uses a declarative approach, where you specify the desired behaviour for each element and do not think about the implementation.

See also the introductory blog post.

Version 1.3 adds support for video tags and an easy-to-use replay control useful for debugging.

Update for free

If you’ve bought Emerge, you get the updates for free. Just re-download using the same link you got when you bought the script. Or drop me a line if you have any questions.

2016   Emerge   release

Emerge.js with a new spinner and scrolling support

In 2013, I’ve released Emerge.js, a framework for coordinated page loading:

Normally, when a complex web page is loading, images appear in random order, causing unpleasant flashing. To replace it with nice and coordinated animations, programming is required. Emerge.js simplifies the task by removing the need to write any JavaScript code. The framework uses a declarative approach, where you specify a desired behaviour for each element and do not think about the implementation.

See also the introductory blog post. I’ve since updated it with new features.

Spinner stuff

In version 1.1 I’ve added a built-in loading spinner. Emerge.js no longer requires spin.js for that. But you can use a custom spinner, including spin.js, if you like.

As before, to display a spinner while an element loads, use data-spin="true". Use the new attributes data-spin-size, data-spin-color, data-spin-direction to control the appearance of the spinner (see documentation on the Emerge.js’s page).

To use another indicator (i.e. one of the nice ones by Sam Herbert) just wrap it into a named div and tell Emerge.js to use the contents of the div as an indicator:

<div id="cool-spinner" style="display: none">
  <svg> ... </svg>
</div>

<div class="emerge" data-spin-element="cool-spinner">
  <!-- while this loads, the cool spinner will be displayed -->
</div>

To use spin.js, make it run inside your div and align as necessary:

<script src="/path/to/spin.js"></script>

  ...

<div id="spinjs-spinner" style="display: none">
  <div style="position: absolute; left: 50%; top: 50%; margin: -8px"></div>
</div>

<script>
  var spinner = new Spinner ({
    lines: 12,
    length: 4,
    width: 2,
    radius: 8,
    corners: 0,
    rotate: 0,
    color: 'rgba(96, 96, 96, .75)',
    hwaccel: true
  })
  spinner.spin ($ ('#spinjs-spinner div')[0])
</script>

  ...

<div class="emerge" data-spin-element="spinjs-spinner">
  <!-- while this loads, spin.js will be displayed -->
</div>

Scrolling stuff

In Version 1.2 with the new data-expose attribute you can make an element emerge only when the user scrolls enough for it to get into view.

<div class="emerge" data-expose="true">
  <!-- this will emerge only when within view -->
</div>

Of course you can combine it with other attributes and effects. This div will emerge with a zoom effect in a quarter second after the users scrolls enough for it to become visible:

<div class="emerge" data-effect="zoom" data-hold="250" data-expose="true">
  <!-- this will emerge quickly after getting into view -->
</div>

For an example, see my Projects page. The data-hold value varies slightly between elements there to add a nice randomness effect.

Update for free

If you’ve bought Emerge.js, you get the updates for free. Drop me a line if you have any questions.

2015   Emerge   projects   web

A proposal for custom website loaders: loading.html

In a browser, when you enter a website address and press Enter, the first thing you see is white screen — no matter how fast your internet connection is. When you launch an app on an iPhone, you see the app immediately — no matter how old your phone is and how slow the app is. The trick is that every iPhone app includes a screenshot of its own initial state. Usually it is the app’s first screen without any content.

The browsers could copy the iPhone’s behavior to improve the perceived speed of the web. In addition to the real page, a web server could serve an HTML file with a temporary content to show while the real page is loading. We’ll call it loading.html, but it could be anything pointed to by a link tag.

When the user goes to a site for the first time, the browser loads it in a regular manner. But if it figures out loading.html is available, it downloads the file and saves it locally. When the site is open again, the browser renders loading.html immediately and then replaces it with the real content when it becomes available.

This is not caching: browser shows loading.html while, not instead of loading the real page. And it will reload this file when it changes, like any other resource.

The difference between nothing and something is huge: immediate feedback, even approximate, is one of the main things that make user interface great. Enter:

A proposal for custom site loaders: loading.html

The following aspects of loading.html should be considered:

  • External resources. It seems sensible to disallow usage of any external resources for the file. They defeat the purpose of the file: the browser should not spend any time loading images or fonts for this temporary screen (which, hopefully, will be visible for only a second). The browser could cache those, but this may become a debugging nightmare. Embed all the styles, scripts and images — or make do without them.
  • File size. Since a browser should store this file for every site you’ve visited, the file should be small. Also, its loading should not tax the visitors who open your site only once.
  • Interaction and continuity. Interaction with a page that can vanish and get replaced with another one any moment seems strange. At first I though that it should be completely prohibited: no links, no listening to JavaScript events. But then I thought, what if I put a site’s menu in loading.html? If a user clicks a link, the browser could switch to loading it (it, by the way, could have its own loading.html, see also Scope). But badly implemented this could be frustrating. Say, a user is typing a search query into an input of loading.html when it gets replaced with a real page. The browser must make sure the typed letters are not dropped and the caret position is maintained.
  • Progress information. It would make sense for loading.html to want to display a spinner or a progress bar itself instead of relying on the browser. For this to work, the progress information should be available to it. A way to implement this would be with an event sent to the page, i.e. onLoadingProgress (in which case disallowing all events is not an option).
  • Location. From the point of view of the scripts on the loading.html page, its location should probably be the same as for the real page it’s temporarily replacing (even though in reality, obviously, loading.html was loaded from another URL).
  • Cookies and localStorage. These should probably be available to loading.html as for the real page also. A use case would be showing the name of the signed-in user right on the loading.html page.
  • Scope. A loading.html page might want to specify the scope of real pages it works as a loader to: only the one it is linked to, a range of pages, all pages on the given domain name.
  • Expiry. A loading.html page might want to specify its expiry date.
  • The switch. When should loading.html be replaced by the real page? Waiting for the full page to load is surely not optimal. Perhaps, a browser should use the same heuristics it uses now to start displaying a page when following a link. But I would consider giving a loading.html-aware pages some additional control over it.

I don’t have experience with Offline Web Applications APIs, but going by the description, I assume at least some of the described behavior could be implemented with them. It would, however, be too complicated for anyone to bother.

This feature will probably be abused by some designers to show splash screens and ads. That’s not a problem. On the iPhone, some apps also show splash screens, and though this sucks, in no way is it a reason to remove the feature (actually, if we remove every feature that has a capacity of being abused, we’ll remain with nothing).

I’ve long been concerned with how web pages look and behave during loading, as you may have guessed looking at Emerge.js (just updated, by the way). There is a lot we can do as front-end developers. But to make things significantly better, help from the browser vendors would be required.

2014   browsers   Emerge   web

Emerge.js, a framework for coordinated page loading

When a web page is loading, images appear in random order, causing unpleasant flashing. Good web developers have learned to deal with the issue by coordinating things with Javascript.

An example would be Apple’s Mac page, where an animated spinner is displayed on top for a couple of seconds, and when the menu items are ready, they appear with a nice animation.

Since coordinating the load process requires tedious programming, it is not what many people choose to do. There are tools which simplify the task to some extent, however the very necessity of programming is a dead end for most people.

Emerge.js changes this.

Emerge.js is a framework for coordinated page loading. It simplifies the task by removing the need to write any Javascript code. The framework uses a declarative approach, where you specify a desired behavior for each element and do not think about the implementation. To make an HTML element wait for its content to load before emerging, use:

class="emerge"

Elements of class emerge fade in after all the contained images are loaded (this includes CSS images). To display an animated spinner while loading, use:

data-spin="true"

The framework lets you coordinate the order and timing and use different animation effects as you see fit, for instance:

data-effect="slide"
data-await="other-element-id"

Check out the product page for detailed description.

2013   Emerge   projects