Skip to content

Posts from the ‘server’ Category

20
Dec

How To: Create your own Content Distribution Network

There are many Content Distribution Networks (CDN) aka Content Delivery Networks out there so why create your own? I for one argue that most CDNs out there don’t host enough code.

Here’s a list that google supports:

Chrome Frame
Dojo
Ext Core
jQuery
jQuery UI
MooTools
Prototype
script.aculo.us
SWFObject
Yahoo! User Interface Library (YUI)
WebFont Loader

This may seem as a long list, but what if you use jQuery plugins like jQuery validate or Fancybox often?

Why not create your own CDN system to host the code you use the most (You can even choose to use googleapis for all the libraries that are available and use your own CDN for the ones that are not). Personally, I prefer that option.
Another benefit of hosting your own CDN is that if you create web applications using a in-house made CMS you can also host its icon-sets and other frequently accessed static images.

The reason’s to use a CDN are simple and straight-forward:

Using a CDN will save you bandwich
Using a CDN will greatly increase your scripts load speed

So how do you create your own CDN?

#1 Setup the domain

If it is possible create a new domain name and disable the use of cookies. Why? RavelRumba explain it in this post. If you can not afford, or do not want to pay for a new domain you can consider creating a subdomain and then making sure cookies are only saved on the www.* domain.

#2 Figure out a filetree structure

Your filetree is very important when setting up your CDN. Yes, you can simply put every file you need in the root directory of the webserver but this is clumbersome and after some time will become confusing.
Google uses the following syntax:

http://ajax.googleapis.com/ajax/libs/library/version/filename
or
http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js

You can also use this syntax or use a more simplified version. Which I personally prefer since the code you should host on your CDN often does not come with that many versions.

http://yourwebsite.com/library/filename

http://yourwebsite.com/library/plugins/pluginname/filename

http://yourwebsite.com/plugins/pluginname/filename

http://yourwebsite.com/images/imagename

I then use the library folder to host specific libraries (and their specific plugins), the plugins folder to host plugins (such as modernizr) and the image folder to host my frequently used images.

#3 Making it perform

As said before, you should disable cookies on the domain of your choice.

Because you are using a CDN you can use a custom .htaccess file to optimise the content distrubution. Set far-future (the content is static anyway) expire headers and deflate any content delivered.

.htaccess example (mostly stripped from the –awesome- html5boilerplate created by the, maybe even more awesome Paul Irish

#Set proper content-types for your files
# Proper svg serving.
AddType     image/svg+xml              svg svgz
AddEncoding gzip                       svgz           

# webfonts
AddType application/vnd.ms-fontobject  eot
AddType font/truetype                  ttf
AddType font/opentype                  otf
AddType font/woff                      woff          

# assorted types
AddType image/vnd.microsoft.icon       ico
AddType image/webp                     webp
AddType text/cache-manifest            manifest
AddType text/x-component               htc
AddType application/x-chrome-extension crx

# gzip compression.
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/plain text/css application/json
  AddOutputFilterByType DEFLATE text/javascript application/javascript application/x-javascript
  AddOutputFilterByType DEFLATE text/xml application/xml text/x-component
  <FilesMatch "\.(ttf|otf|eot|svg)$" >
    SetOutputFilter DEFLATE
  </FilesMatch>
</IfModule>

<IfModule mod_expires.c>
  Header set Cache-Control "public"
  ExpiresActive on

# Perhaps better to whitelist expires rules? Perhaps.
  ExpiresDefault                          "access plus 1 month"

# cache.manifest needs re-requests in FF 3.6 (thx Remy ~Introducing HTML5)
  ExpiresByType text/cache-manifest       "access plus 0 seconds"

# favicon (cannot be renamed)
  ExpiresByType image/vnd.microsoft.icon  "access plus 1 week" 

# media: images, video, audio
  ExpiresByType image/gif                 "access plus 1 month"
  ExpiresByType image/png                 "access plus 1 month"
  ExpiresByType image/jpg                 "access plus 1 month"
  ExpiresByType image/jpeg                "access plus 1 month"
  ExpiresByType video/ogg                 "access plus 1 month"
  ExpiresByType audio/ogg                 "access plus 1 month"
  ExpiresByType video/mp4                 "access plus 1 month"
  ExpiresByType video/webm                "access plus 1 month"

# webfonts
  ExpiresByType font/truetype             "access plus 1 month"
  ExpiresByType font/opentype             "access plus 1 month"
  ExpiresByType font/woff                 "access plus 1 month"
  ExpiresByType image/svg+xml             "access plus 1 month"
  ExpiresByType application/vnd.ms-fontobject "access plus 1 month"

# css and javascript
  ExpiresByType text/css                  "access plus 1 week"
  ExpiresByType application/javascript    "access plus 1 week"
  ExpiresByType text/javascript           "access plus 1 week"
</IfModule>

# Since we're sending far-future expires, we don't need ETags for
# static content.
FileETag None

# use utf-8 encoding for anything served text/plain or text/html
AddDefaultCharset utf-8

# force utf-8 for a number of file formats
AddCharset utf-8 .html .css .js .xml .json .rss

#4 All done

It’s that simple to create a very basic CDN. Obviously there are other more advanced topics we could discuss about how to optimize the distribution of content, but this is in essence a CDN that does what it promises.