{"id":296,"date":"2013-10-22T10:02:20","date_gmt":"2013-10-22T10:02:20","guid":{"rendered":"https:\/\/gosqeng.test\/?p=296"},"modified":"2019-11-28T12:26:36","modified_gmt":"2019-11-28T12:26:36","slug":"gosquared-static-website","status":"publish","type":"post","link":"https:\/\/www.gosquared.com\/blog\/gosquared-static-website","title":{"rendered":"How we made the GoSquared site 4x faster"},"content":{"rendered":"<p><img decoding=\"async\" src=\"\/\/static.gosquared.com\/images\/liquidicity\/13_10_22_staticsite_01.png\" alt=\"Making the GoSquared site 4x faster \u2013 the new static website\"\/><\/p>\n<p>It\u2019s a well known fact that a static website will usually be faster than having everything running through a server-side language, like PHP or Ruby. Until a few weeks ago, the majority of the GoSquared site was still being generated by PHP code. Some of this code was <a href=\"https:\/\/www.gosquared.com\/blog\/start-up-story\" title=\"GoSquared is 7 years old\" target=\"_blank\" rel=\"noopener noreferrer\">as old as GoSquared itself<\/a> and most of it had become obsolete, unnecessarily slowing down the site.<\/p>\n<p>We recently replaced all this with a brand new static site.<\/p>\n<h2>Why?<\/h2>\n<p>Building your website using PHP encourages you to put a lot of logic and functionality within an HTML page, rather than thinking through exactly why that functionality is needed and how to implement it properly.<\/p>\n<p>We&#8217;re also huge <a href=\"http:\/\/nodejs.org\/\" title=\"Node - GoSquared loves Node\" target=\"_blank\" rel=\"noopener noreferrer\">Node.js<\/a> fans at GoSquared, and we wanted to have all of the account logic and administration in a Node.js application, which you&#8217;ll be able to read more about in future posts.<\/p>\n<h3>Maintainability<\/h3>\n<p>In HTML, CSS and JavaScript, we follow the concept of <code>Separation of Concerns<\/code> (keep all files separate and detached) to improve the maintainability of code \u2013 there shouldn&#8217;t be any inline CSS in your HTML. But we did have a huge amount of inline PHP, which is potentially even worse than any of the others.<\/p>\n<h3>Speed<\/h3>\n<p>Static HTML files are a lot faster than dynamic pages. Since release, we&#8217;ve seen a very noticeable decrease in page load times. We were also able to minify and compress all of the assets that make up those pages. View the source if you want to see \u2013 HTML is <strong>20% smaller<\/strong>, <strong>CSS 17% smaller<\/strong> and <strong>JavaScript a massive 40% smaller<\/strong>. This has a huge impact, especially for our mobile users.<\/p>\n<p>PHP can also be slow, and we knew we could speed things up by writing all admin functions in Node.js and making as much as possible asynchronous and parallel, while removing all PHP from the pages so there will be no server processing before page load.<\/p>\n<h3>Uptime, costs and scalability<\/h3>\n<p><a href=\"http:\/\/aws.amazon.com\/s3\/\" title=\"Amazon S3 in use at GoSquared\" target=\"_blank\" rel=\"noopener noreferrer\">S3<\/a> has an availability of ~99.99% and can handle any amount of traffic, so unless we make a serious mistake, the site should never go down due to high traffic. Having a few static files on S3 is a lot cheaper than running a small cluster of PHP servers, and much easier to manage.<\/p>\n<p>We do still route all traffic through our <a href=\"http:\/\/nginx.com\/\" title=\"Nginx in use at GoSquared\" target=\"_blank\" rel=\"noopener noreferrer\">nginx<\/a> cluster, but that scales incredibly well. See <a href=\"https:\/\/www.gosquared.com\/blog\/optimising-nginx-node-js-and-networking-for-heavy-workloads\" target=\"_blank\" rel=\"noopener noreferrer\">our post on scaling nginx with Node.js<\/a>.<\/p>\n<h2>How?<\/h2>\n<h3>Serenity<\/h3>\n<p><a href=\"http:\/\/simontabor.com\/labs\/serenity\" target=\"_blank\" rel=\"noopener noreferrer\">Serenity<\/a> is a static site generation framework written in Node.js (<a href=\"https:\/\/github.com\/simontabor\/serenity\" target=\"_blank\" rel=\"noopener noreferrer\">open source<\/a> and available on <a href=\"https:\/\/npmjs.org\/package\/serenity\" target=\"_blank\" rel=\"noopener noreferrer\">NPM<\/a>). I wrote Serenity as there was a lack of tools for developers who like to use EJS and JSON (rather than liquid and YAML). It&#8217;s basically Jekyll for JavaScripters.<\/p>\n<p>It allows easy asset management, compression and is optimised for CDNs by providing asset path helpers which add a hash to the asset name so long cache TTLs can be used.<\/p>\n<p>PHP <code>include footer.php<\/code> was replaced with <code>&lt;% include footer %&gt;<\/code> and there were the additional added benefits of layouts, templates, inline assets and much more.<\/p>\n<p>We used layouts and includes extensively to provide a consistent site look and feel across all of the pages. One update to the signup form include will update every form on the entire site and regenerate the HTML accordingly.<\/p>\n<h3>Node.js<\/h3>\n<p>Node.js is fast, we already know that. It&#8217;s even faster if the functionality is planned and code is written to play to the strong points.<\/p>\n<p>Account actions, such as logging in or signing up, are <strong>4x faster than before<\/strong>. We were able to utilise the asynchronous nature of Node.js (and keep it tidy by using <code><a href=\"https:\/\/npmjs.org\/package\/async\" target=\"_blank\" rel=\"noopener noreferrer\">async<\/a><\/code>) and therefore were able to fire off multiple concurrent MySQL queries (using <code><a href=\"https:\/\/npmjs.org\/package\/mysql\" target=\"_blank\" rel=\"noopener noreferrer\">node-mysql<\/a><\/code>&#8216;s connection pooling). Again, more on this later.<\/p>\n<h3>AJAX<\/h3>\n<p>The use of AJAX for logins and signups has made a significant difference too. There&#8217;s no longer a page reload before being told that you&#8217;ve mistyped your password.<\/p>\n<h2>Conclusions<\/h2>\n<p>We&#8217;ve really seen the benefits of converting our public site to be completely static. It&#8217;s faster, and our users&#8217; experience is ultimately more important than the underlying code, so it&#8217;s a success already. On top of that, we&#8217;ve managed to build a maintainable system which we can update and improve long into the future.<\/p>\n<p>What are your thoughts? Let us know <a href=\"https:\/\/twitter.com\/gosquared\" title=\"GoSquared on Twitter\" target=\"_blank\" rel=\"noopener noreferrer\">@GoSquared<\/a> on Twitter.<\/p>\n","protected":false},"excerpt":{"rendered":"<p><img decoding=\"async\" src=\"\/\/static.gosquared.com\/images\/liquidicity\/13_10_22_staticsite_01.png\" alt=\"Making the GoSquared site 4x faster \u2013 the new static website\"\/><\/p>\n<p>It\u2019s a well known fact that a static website will usually be faster than having everything running through a server-side language, like PHP or Ruby. Until a few weeks ago, the majority of the GoSquared site was still being generated by PHP code. Some of this code was <a href=\"https:\/\/www.gosquared.com\/blog\/start-up-story\" title=\"GoSquared is 7 years old\" target=\"_blank\" rel=\"noopener noreferrer\">as old as GoSquared itself<\/a> and most of it had become obsolete, unnecessarily slowing down the site.<\/p>\n<p>We recently replaced all this with a brand new static site.<\/p>\n","protected":false},"author":10,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1452],"tags":[832],"class_list":["post-296","post","type-post","status-publish","format-standard","hentry","category-engineering","tag-speed"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v18.6 (Yoast SEO v19.0) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>How we made the GoSquared site 4x faster - GoSquared Blog<\/title>\n<meta name=\"description\" content=\"We&#039;ve made the GoSquared website 4x faster by converting it to a static website. Here&#039;s how we were able to do it without making a mess.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.gosquared.com\/blog\/gosquared-static-website\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How we made the GoSquared site 4x faster\" \/>\n<meta property=\"og:description\" content=\"We&#039;ve made the GoSquared website 4x faster by converting it to a static website. Here&#039;s how we were able to do it without making a mess.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.gosquared.com\/blog\/gosquared-static-website\" \/>\n<meta property=\"og:site_name\" content=\"GoSquared Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/GoSquared\" \/>\n<meta property=\"article:published_time\" content=\"2013-10-22T10:02:20+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-11-28T12:26:36+00:00\" \/>\n<meta property=\"og:image\" content=\"\/\/static.gosquared.com\/images\/liquidicity\/13_10_22_staticsite_01.png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@simon_tabor\" \/>\n<meta name=\"twitter:site\" content=\"@GoSquared\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Simon Tabor\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/#organization\",\"name\":\"GoSquared\",\"url\":\"https:\/\/www.gosquared.com\/blog\/\",\"sameAs\":[\"https:\/\/instagram.com\/gosquaredteam\",\"https:\/\/www.linkedin.com\/company\/go-squared-ltd.\",\"https:\/\/www.facebook.com\/GoSquared\",\"https:\/\/twitter.com\/GoSquared\"],\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.gosquared.com\/blog\/wp-content\/uploads\/2015\/07\/gosquared.png\",\"contentUrl\":\"https:\/\/www.gosquared.com\/blog\/wp-content\/uploads\/2015\/07\/gosquared.png\",\"width\":1270,\"height\":250,\"caption\":\"GoSquared\"},\"image\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/#website\",\"url\":\"https:\/\/www.gosquared.com\/blog\/\",\"name\":\"GoSquared Blog\",\"description\":\"Turn visitors into customers.\",\"publisher\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.gosquared.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/gosquared-static-website#webpage\",\"url\":\"https:\/\/www.gosquared.com\/blog\/gosquared-static-website\",\"name\":\"How we made the GoSquared site 4x faster - GoSquared Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/#website\"},\"datePublished\":\"2013-10-22T10:02:20+00:00\",\"dateModified\":\"2019-11-28T12:26:36+00:00\",\"description\":\"We've made the GoSquared website 4x faster by converting it to a static website. Here's how we were able to do it without making a mess.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/gosquared-static-website#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.gosquared.com\/blog\/gosquared-static-website\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/gosquared-static-website#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.gosquared.com\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How we made the GoSquared site 4x faster\"}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/gosquared-static-website#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/gosquared-static-website#webpage\"},\"author\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/71fad71f60ad33cf9356687b37aed3d0\"},\"headline\":\"How we made the GoSquared site 4x faster\",\"datePublished\":\"2013-10-22T10:02:20+00:00\",\"dateModified\":\"2019-11-28T12:26:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/gosquared-static-website#webpage\"},\"wordCount\":715,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/#organization\"},\"keywords\":[\"Speed\"],\"articleSection\":[\"Engineering\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.gosquared.com\/blog\/gosquared-static-website#respond\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/71fad71f60ad33cf9356687b37aed3d0\",\"name\":\"Simon Tabor\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/dc920e48608646bda51d2e6e2595e8ad926cff52eba534c1d25fb1618f15b59f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/dc920e48608646bda51d2e6e2595e8ad926cff52eba534c1d25fb1618f15b59f?s=96&d=mm&r=g\",\"caption\":\"Simon Tabor\"},\"description\":\"Lead developer at GoSquared for integrations, partnerships and the API. Works on pretty much everything.\",\"sameAs\":[\"http:\/\/simontabor.com\",\"https:\/\/twitter.com\/simon_tabor\"],\"url\":\"https:\/\/www.gosquared.com\/blog\/author\/simontabor\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How we made the GoSquared site 4x faster - GoSquared Blog","description":"We've made the GoSquared website 4x faster by converting it to a static website. Here's how we were able to do it without making a mess.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.gosquared.com\/blog\/gosquared-static-website","og_locale":"en_US","og_type":"article","og_title":"How we made the GoSquared site 4x faster","og_description":"We've made the GoSquared website 4x faster by converting it to a static website. Here's how we were able to do it without making a mess.","og_url":"https:\/\/www.gosquared.com\/blog\/gosquared-static-website","og_site_name":"GoSquared Blog","article_publisher":"https:\/\/www.facebook.com\/GoSquared","article_published_time":"2013-10-22T10:02:20+00:00","article_modified_time":"2019-11-28T12:26:36+00:00","og_image":[{"url":"\/\/static.gosquared.com\/images\/liquidicity\/13_10_22_staticsite_01.png"}],"twitter_card":"summary_large_image","twitter_creator":"@simon_tabor","twitter_site":"@GoSquared","twitter_misc":{"Written by":"Simon Tabor","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Organization","@id":"https:\/\/www.gosquared.com\/blog\/#organization","name":"GoSquared","url":"https:\/\/www.gosquared.com\/blog\/","sameAs":["https:\/\/instagram.com\/gosquaredteam","https:\/\/www.linkedin.com\/company\/go-squared-ltd.","https:\/\/www.facebook.com\/GoSquared","https:\/\/twitter.com\/GoSquared"],"logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.gosquared.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.gosquared.com\/blog\/wp-content\/uploads\/2015\/07\/gosquared.png","contentUrl":"https:\/\/www.gosquared.com\/blog\/wp-content\/uploads\/2015\/07\/gosquared.png","width":1270,"height":250,"caption":"GoSquared"},"image":{"@id":"https:\/\/www.gosquared.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"WebSite","@id":"https:\/\/www.gosquared.com\/blog\/#website","url":"https:\/\/www.gosquared.com\/blog\/","name":"GoSquared Blog","description":"Turn visitors into customers.","publisher":{"@id":"https:\/\/www.gosquared.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.gosquared.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.gosquared.com\/blog\/gosquared-static-website#webpage","url":"https:\/\/www.gosquared.com\/blog\/gosquared-static-website","name":"How we made the GoSquared site 4x faster - GoSquared Blog","isPartOf":{"@id":"https:\/\/www.gosquared.com\/blog\/#website"},"datePublished":"2013-10-22T10:02:20+00:00","dateModified":"2019-11-28T12:26:36+00:00","description":"We've made the GoSquared website 4x faster by converting it to a static website. Here's how we were able to do it without making a mess.","breadcrumb":{"@id":"https:\/\/www.gosquared.com\/blog\/gosquared-static-website#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.gosquared.com\/blog\/gosquared-static-website"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.gosquared.com\/blog\/gosquared-static-website#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.gosquared.com\/blog"},{"@type":"ListItem","position":2,"name":"How we made the GoSquared site 4x faster"}]},{"@type":"Article","@id":"https:\/\/www.gosquared.com\/blog\/gosquared-static-website#article","isPartOf":{"@id":"https:\/\/www.gosquared.com\/blog\/gosquared-static-website#webpage"},"author":{"@id":"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/71fad71f60ad33cf9356687b37aed3d0"},"headline":"How we made the GoSquared site 4x faster","datePublished":"2013-10-22T10:02:20+00:00","dateModified":"2019-11-28T12:26:36+00:00","mainEntityOfPage":{"@id":"https:\/\/www.gosquared.com\/blog\/gosquared-static-website#webpage"},"wordCount":715,"commentCount":0,"publisher":{"@id":"https:\/\/www.gosquared.com\/blog\/#organization"},"keywords":["Speed"],"articleSection":["Engineering"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.gosquared.com\/blog\/gosquared-static-website#respond"]}]},{"@type":"Person","@id":"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/71fad71f60ad33cf9356687b37aed3d0","name":"Simon Tabor","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/dc920e48608646bda51d2e6e2595e8ad926cff52eba534c1d25fb1618f15b59f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/dc920e48608646bda51d2e6e2595e8ad926cff52eba534c1d25fb1618f15b59f?s=96&d=mm&r=g","caption":"Simon Tabor"},"description":"Lead developer at GoSquared for integrations, partnerships and the API. Works on pretty much everything.","sameAs":["http:\/\/simontabor.com","https:\/\/twitter.com\/simon_tabor"],"url":"https:\/\/www.gosquared.com\/blog\/author\/simontabor"}]}},"wps_subtitle":"Fast analytics needs a fast marketing site","_links":{"self":[{"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/posts\/296","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/comments?post=296"}],"version-history":[{"count":0,"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/posts\/296\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/media?parent=296"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/categories?post=296"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/tags?post=296"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}