The Many Kinds of SPOF
If there is one good thing about disasters it is that they tend to raise awareness and increase preparedness. For example, if I hear about a house fire, I always go and check the batteries in my smoke detectors. If a bad storm hits somewhere, I always go and test the flashlights in the house to make sure they are working properly. We should use disasters as an opportunity to check if we are vulnerable and plan how we would respond.
Over the weekend, CloudFlare had a router configuration problem. Many websites use CloudFlare to proxy all of their web traffic to optimize content on the fly. Accelerator solutions like CloudFlare can only work by requiring that all your visitors are accessing to your website via CloudFlare, this creates a giant single point of failure. When CloudFlare failed, 785,000 sites disappearing off the Internet and could not be accessed.
This event provides a perfect opportunity to review your web application for points of failure. In front-end web development, there are several area’s that are single points of failure you need to be away of. In this post, I focus exclusively on single points of failure (SPOF) facing front-end developers. Specifically:
- Third Party Content
- Content CDNs
I will leave IT operational points of failure such as web servers and databases for later.
Third Party Content
As we all know loading third party content can be the source of many performance problems. However loading badly behaving third party content can also be a source of failure for your website. Consider code like this:
<html> <head> <script src="//example.com/analytics.js"></script> </head> <body> Important Content. </body> </html>
What happens if example.com is having problems? Or is loading slowly? What if the connection hangs? Or the connection is made over SSL and the SSL negotiation has problems? Or any number of other problems? All your isers will stare at a blank white screen, and the browser will not download anything else, while it awaits downloading that analytics package.
<iframes> to delay their impact. Fonts and CSS are a little more complex and SPOF is an evolving subject still receiving a lot of research. Be sure to check out the work of Steve Souders as well as tools like SPOFCheck to learn more solutions.
But if you must…
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script> <script>window.jQuery || document.write('<script src="js/libs/jquery-1.5.1.min.js">\x3C/script>')</script>
<script> block checks to see if certain global variables loaded by the library are present. Should the library fail to load, these checks fail, and the code writes out another
<script> tag which points to a locally hosted copy. This thread on Stack Overflow provides additional details.
<img src="/images/logo.png" width="200" height="50" alt="Zoompf logo" />
and instead do:
<% =Splat.Image("/images/logo.png", "Zoompf logo"); %>
This function actually writes out the
<img> tag. Moving the creation of the tag into code provides a lot of benefits:
- Automatically add file versioning into the URL for the resource to enable far future caching.
- Automatically minify relevant content.
- Automatically add different subdomains to do domain sharding where needed.
- For images, I can check the image’s actual width/height and insert those attributes into the resulting tag.
Another benefit of using wrapper functions is the control this provides over CDNs. By CDNs, I mean companies like Akamai or CacheFly which improve website performance by serving content from nearby systems to reduce latency. CDNs will use special host names to download content and resolves those DNS names to be servers that are physically near your visitor.
But what if your CDN is experiencing problems? Or your CFO forgot to pay your CDN bill? Suddenly the host names that those resources are served from are not resolving or not properly responding with your content? What are you to do?
By using wrapper functions, you can quickly work around the failure. Your
Splat.CSS() functions can simply write out URLs that point to your host system instead of the CDN. As soon as CDN problems develop, a flag in a config file on your production website could tell those
Splat.* functions to stop using CDN urls. You can respond to the failure instantly, without waiting for DNS records to populate. This allows you to have the benefits of a CDN without the bottlenecks.
In short, wrapper functions give you an easy injection point to rapidly change how your site references content and work around failures.
Unfortunately cloud accelerators like CloudFlare require that your website’s traffic go through them. Typically your DNS settings have been changed so that, from the Internets perspective, you no longer control
www.site.com, the accelerator does. These solutions are often described as a “CDN” but that’s really not the case. The wrapper functions solution discussed above only works because the requests for HTML pages are still coming directly to your website. You are simply linking to urls in your HTML and you can decide where those links go (to a CDN, to local resources, etc).
With a cloud accelerator, you don’t get that chance. No visitors are getting your HTML, so there is nothing to work around. Additionally, changing your DNS settings to point
www.site.com back to your website really won’t solve the problem since DNS changes can take hours or even days to propagate.
To avoid a cloud accelerator as a single point of failure which cannot be worked around, consider not using these services. After all, you can locally install free and open source software on your web server to apply the same “on-the-fly” optimizations as an accelerator. Apache’s
mod_pagespeed from Google, and nginx’s
ngx_pagespeed are two such examples. Many hosting providers (such as Dreamhost) offer these optimization modules pre-installed. You can use scripts like SiteCrunch can optimize all your images. This becomes even more powerful as a reoccurring task or as part of your build and deploy process. Content Management Systems like WordPress, Dupral, and TYPO3 all have a rich ecosystem of free plug-ins which can automatically optimize your website.
In short, there are a lot of options to automatically optimize content. Dodging the responsibility to improve your website’s performance by funneling all your traffic through a third party is a drastic and often unnecessary step.
All of these failure points were added to the front-end to help web performance or add additional functionality. It is important to review whether you are actually getting any performance benefit for the added risk. It is also important to have in place a plan to resolve these issues, such as using wrapper functions to bypass the troubled area.