How to write a polyfill

Last week we made the CSS Regions Polyfill public. I thought it would make sense to share the experience of creating this JavaScript library as this was my first Polyfill. Thanks to the process we used I think it went pretty well.

Planning the work

Before writing a single line of code I’ve spent a lot of time reading the spec over and over again making sure that I had a good understanding of what this CSS proposal was all about. I also started to look at a bunch of examples so I could visualize what you can do with CSS Regions.

To be honest, after all the reading I was really overwhelmed. I realized that this was going to be really tricky as this feature is complex.

Fortunately, I wasn’t alone. Catalin Grigoroscuta and Alan Stearns helped me to distill a list of examples that were using CSS Regions.  Catalin and Alan did a great job selecting examples that were among the less complex and most relevant to what people would want to get out of CSS Regions. As you know, when you have a really complex problem to solve, often the best strategy is to break that problem into a number of small problems and solve the smaller problems one by one.

We started with only four or five examples. The first one was really simple; the rest were more and more complex. Looking at the list I was confident that it is could be done and done fast.

Once we had a baseline for what the MVP (minimal viable product :D) of our polyfill should be, I started to work. We deliberately avoided setting the matrix of supported browsers and browser versions beforehand. It was quite obvious that this polyfill would be quite heavy on the CPU so we needed all the help we could get from modern browsers in order to get decent performance for most common use cases.

Executing the plan

If you look at the CSS Regions spec through the eyes of a polyfill maestro you find two big problems to solve: parsing the CSS to find the DOM elements that are part of a region chain definition and writing the algorithm that “flows” the content between each region’s DOM elements.

Again my task was easier because my colleague, Razvan, had already put together a CSS parser for CSS Regions. While this parser wasn’t perfect (it didn’t support external style sheets for example) it was a great boost as it allowed me to focus exclusively on the flowing algorithm. And to make things even easier, the first example I started to support was Chris Coyier’s demo – this example flows only four pictures between a maximum number of four regions.

By the end of the day I had the first example supported so it was time to focus on the project infrastructure for a bit. We decided to use GitHub for this project. So once I created the project structure I created a new repo and uploaded the code. GitHub not only gave us the versioning support you need for any project but it gave the rest of the infrastructure with minimal pain: a Wiki, a place to track issues/bugs, a page for the project, and so forth.

After this first milestone was completed, it was only a matter of supporting the next example from the list. And with each new supported example the polyfill had more and more features supported from the spec: support for flowing Text Nodes and Images, basic support for CSS OM, support for external style sheets, and support for more browsers.

Setting up the project for supporting external contributors

For a while I was the only one coding. Then Razvan joined me as we needed a better CSS parser (supporting external style sheets, fixing some bugs, and so forth). This was when we decided that we needed a build system in place so if we could keep the whole project manageable as more people joined the project.

So Razvan took the lead here and set up a build process (using Grunt) that builds (and minifies) theJS file of the polyfill from four different JS files (each one holding a specific functionality of the project). He also created the first unit tests for the project using Qunit and and Testem. We added tests for the CSS parser, for the flowing algorithm, and so forth. This gave us a lot of confidence when we needed to change different parts of the code. And it provided us with the ability to accept code from external contributors.

Conclusions

Both Razvan and I had a number of different tasks to handle on top of this project. For example, I was travelling to more than a dozen conferences around the world while working on this project. This means I was on and off the project many times during a week as I was taking on more pressing things (preparing a session for the next conference, for example or traveling to and back from that conference). I think that splitting the problem to solve a number of relatively simpler problems helped us a lot with our busy schedule.

Also by using a lean approach by deliberately deferring everything that wasn’t mandatory for that particular project stage helped us to maintain a high development speed. And in my experience, good progress is one thing that can give wings to any developer.

Finally, I want to thank Vincent Hardy for giving me the opportunity to work on this project. I had lot of fun and learned new things while doing it.

Note: If you don’t know what a Polyfill is, check Remy Sharp’s post on this topic.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>