Tom MacWright

tom@macwright.com

Big 2

12345678910050100msbig 2big 1

I created the Big presentation system in 2011 and commemorated 1.0 in late

  1. The last time I made a Big presentation, my coworker AJ Ashton correctly pointed out that slide transitions were slow. I took a closer look and found a decent optimization that yields a 4x performance increase in most cases, and am releasing it as big 2. If you use Big, your presentations will now run faster! Here’s the link to the code and Big’s website.

If you’re interested in the optimization…

Big’s strategy is to format every slide in a presentation so that the text is as big as it can be. It uses JavaScript to accomplish this task: if Big were to ban text wrapping, it might be possible to implement it in pure CSS, but given the unpredictable behavior of whitespace, JS is required.

This is the resize method from Big 1, with comments:

function resize() {
  // e is the current slide: big.current is the slide number, s is
  // the list of slides
  var w = window.innerWidth, h = window.innerHeight, e = s[big.current];

  // initially set the slide's font size to the current page height.
  // in some rare cases that'll be the size it ends up being, but usually
  // it'll need to be reduced to accomodate for more text or higher line-height
  e.style.fontSize = h + 'px';

  // reduce the font size in 2px increments until the window stops overflowing
  for (i = h - 2; i > 0 && (e.offsetWidth > w || e.offsetHeight > h); i -= 2) {
    e.style.fontSize = i + 'px';
  }

  // center the text vertically
  e.style.marginTop = (h - e.offsetHeight) / 2 + 'px';
}

This is an expensive operation: you’re forcing a re-layout on each loop iteration, asking the browser to decide whether text is still overflowing or not. So in cases where the text starts out at 200px and ends up at 100px, you’re triggering 50 reflows. That’s slow.

function resize() {
  var w = window.innerWidth, h = window.innerHeight, e = s[big.current];
  e.style.fontSize = h + 'px';
  function pass(cinch, start) {
    for (var i = start; i > 0 && (e.offsetWidth > w || e.offsetHeight > h); i -= cinch) {
      e.style.fontSize = i + 'px';
    }
    return i + cinch;
  }
  pass(2, pass(5, pass(10, h - 2)));
  e.style.marginTop = (h - e.offsetHeight) / 2 + 'px';
}

This is the method from Big 2. You can see that it’s the same fundamental technique, but it cheats: instead of 2px hops, it starts with 10px hops, then 5px, then 2px. When it detects that the page is no longer overflowing, it backs up to the increment before. This is essentially a mini search algorithm, except trying to find the cusp between a full webpage and an overflow.

Exercise for the reader: with this optimization, big.js is getting a little bulky: it’s now 67 lines long. And the new algorithm could still be faster for big slides: should it be a proper binary search? I’d love to see if anyone has ideas for how to make Big tinier or faster!