
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Wed, 15 Apr 2026 00:20:18 GMT</lastBuildDate>
        <item>
            <title><![CDATA[Improve your page experience with AMP and Cloudflare Workers Unbound]]></title>
            <link>https://blog.cloudflare.com/amp-optimizer-on-cloudflare-workers/</link>
            <pubDate>Wed, 14 Apr 2021 13:01:00 GMT</pubDate>
            <description><![CDATA[ Google’s new page experience measurements are going to be included in their search ranking in May 2021. Learn more about how to improve your page experience with AMP and Cloudflare Workers. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>In this blog post we’re going to look at how you can optimize the page experience of your AMP pages by running AMP Optimizer in a Cloudflare Worker.</p>
    <div>
      <h2>Towards a better user experience on the web</h2>
      <a href="#towards-a-better-user-experience-on-the-web">
        
      </a>
    </div>
    <p>A great user experience on the web means more than just having a website that loads fast (although that continues to be a critical part of the user experience). There are many factors that contributing to a great experience, such as:</p><ul><li><p>Loading speed</p></li><li><p>Responsiveness</p></li><li><p>Content stability</p></li></ul><p>Traditionally, these have been hard to measure, but with <a href="https://web.dev/vitals">Core Web Vitals</a> we now have a new way to measure user experience on the web. The key is: Core Web Vitals are based on <a href="https://web.dev/vitals-measurement-getting-started/">real world user data</a>. To score well on Core Web Vitals you need to make sure that your website performs well - for all your users around the world.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/WMhd5DGEooz8bD2EGDdCV/904a09ca0ccf595b9504aff7e6686de6/image1-16.png" />
            
            </figure><p><a href="https://lh5.googleusercontent.com/HlrpevA1hZKx35h2SQdwOBdCO4FOC0YOqie9eMTiGDZx5MdSVTxY2VwPwdL58Pi68cuuG0ooeRTs3RJQEfU5woNRpgq1ZLV4SrWkzHIOH4kTnLS32i62Qf7UibEcz2xm8Gb4nT_e">Image URL</a></p><p>This becomes even more important soon, as <a href="https://www.cloudflare.com/learning/performance/what-are-core-web-vitals/">Core Web Vitals</a> are also going to be a signal in the upcoming <a href="https://developers.google.com/search/docs/guides/page-experience">page experience ranking update in Google Search</a>. You can find more details in the <a href="https://support.google.com/webmasters/thread/104436075?hl=en">page experience FAQ</a>.</p>
    <div>
      <h2>How to achieve a great page experience with AMP</h2>
      <a href="#how-to-achieve-a-great-page-experience-with-amp">
        
      </a>
    </div>
    <p><a href="https://amp.dev">AMP</a> is an <a href="https://github.com/ampproject/amphtml">open source</a> web components framework that has been <a href="https://blog.amp.dev/2020/05/06/amp-web-vitals-a-better-web-together/">developed with page experience in mind</a>. AMP ensures a good page experience by providing guardrails that help avoid common performance pitfalls. For example, AMP features a static layout system, which <a href="https://blog.amp.dev/2020/04/16/cumulative-layout-shift-in-amp/">avoids content shifts by design</a>.</p><p>However, AMP pages can still fail Core Web Vitals. The reason for this is clear: some performance best practices required for performing well on Core Web Vitals can’t be implemented at client-side. For example, image optimization, fast server-response times and effective font-loading are all critical for a good user experience, but need to be done on the server. Even AMP documents themselves can be further optimized. For example, <a href="https://amp.dev/documentation/guides-and-tutorials/optimize-and-measure/amp-optimizer-guide/explainer/?format=websites#server-side-rendering-amp-layouts">AMP’s layout system can be pre-rendered at build or serving time</a> which greatly <a href="https://blog.amp.dev/2018/10/08/how-to-make-amp-even-faster/">improves page load times</a> while still ensuring that there are no content jumps.</p><p>The good news is, if an AMP page is surfaced in Google Search or Bing, it’ll be served from an AMP Cache which performs all these optimizations for you. But when someone visits your AMP page directly, for example through a link shared on social media, they won’t get the same experience. In order to ensure that you are getting great Core Web Vitals scores for all your users, it is very important to optimize your AMP pages on your origin as well!</p><p>To help with this, the AMP team has created <a href="https://amp.dev/documentation/guides-and-tutorials/optimize-and-measure/amp-optimizer-guide/?format=websites">AMP Optimizers</a>, which will automatically perform common performance best practices for you. Using AMP Optimizers combined with Cloudflare Workers makes it super easy to serve optimized AMP pages on your own origin.</p>
    <div>
      <h2>Introducing AMP Optimizer for Cloudflare Workers</h2>
      <a href="#introducing-amp-optimizer-for-cloudflare-workers">
        
      </a>
    </div>
    <p>We are happy to announce a new AMP Optimizer integration for Cloudflare Workers. So far, there are two AMP Optimizer versions available: one for NodeJS and one for PHP. Both take an AMP HTML document as input and turn it into an optimized AMP HTML document. Depending on when your pages are created, one of these needs to be run either as part of your build system or in on your backend as part of your rendering pipeline. However, integrating an AMP Optimizer is not always straightforward, for example if you’re not using PHP or NodeJS in your backend or when you don’t control the hosting environment.</p><p>With the Cloudflare Worker integration for AMP Optimizer you can seamlessly optimize all your AMP pages. You can find installation instructions on the <a href="https://github.com/ampproject/cloudflare-amp-optimizer">Github repository</a>.</p>
    <div>
      <h2>Looking under the hood</h2>
      <a href="#looking-under-the-hood">
        
      </a>
    </div>
    <p>Let’s dive into how the Cloudflare Worker works, so that we can get a better understanding of where it optimises things.</p>
    <div>
      <h3>Request Flow</h3>
      <a href="#request-flow">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6xCiShc9Elek69vK23ut4U/1e17a5d32c23a47e722b1d7ada2a8c49/image5-5.png" />
            
            </figure><p>Whenever a request comes in for an HTML file (1), the Worker will first check in the global cache if an optimised version has already been generated (2). If that is not the case (3), the Worker will request the version of the file from your origin (4)(5), optimize the document if it is using AMP (6), and return that to the user (7). Only after the response has been fully streamed to the user will we start saving the generated version in the cache (8).</p><p>For subsequent requests, in a Worker anywhere else in the world, the result will be retrieved from the global KV cache, cached locally in that data center and returned straight away.</p>
    <div>
      <h3>Automatic preloading</h3>
      <a href="#automatic-preloading">
        
      </a>
    </div>
    <p>Because the AMP Optimizer parses the HTML document, it will discover what other resources are used, and will add preload tags for external resources such as fonts and hero images.</p>
    <div>
      <h3>Responsive images out of the box</h3>
      <a href="#responsive-images-out-of-the-box">
        
      </a>
    </div>
    <p>Images are often the biggest contributors to the total download size of a web page. Customers on the Business or Enterprise plans can automatically make use of the Cloudflare Image Optimization functionality. For those customers, the AMP Optimizer can automatically generate <a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images">image source sets</a> with links for the <a href="https://developers.cloudflare.com/images/">Cloudflare Image Optimizer</a>.</p><p>Image sourcesets give the browser different options to pick the most appropriate image size for that particular browser viewport. This can greatly reduce the size of the image downloads for, say, a low end mobile phone, which needs much smaller images than a 4K desktop monitor.</p>
    <div>
      <h2>Peace of mind with Cloudflare Workers Unbound</h2>
      <a href="#peace-of-mind-with-cloudflare-workers-unbound">
        
      </a>
    </div>
    <p>While most of the requests will be handled very quickly, even the ones that need optimising, the optimisation of large files can take more than 50ms of CPU time. Which is why Workers Unbound is a perfect match for the AMP Optimizer Worker.</p><p>Workers Unbound allows Workers to execute for up to 30 seconds, so that even if it does take a bit longer than 50ms to optimize a document, your users will never see any errors.</p>
    <div>
      <h2>What are the performance gains?</h2>
      <a href="#what-are-the-performance-gains">
        
      </a>
    </div>
    <p>Web performance is much more complex than any synthetic test can prove, so you should absolutely do your own performance testing on your own sites. But here is an example of a regular AMP page with and without the Cloudflare Worker AMP Optimizer in front of it. This is tested on a simulated Moto G4 on a fast 3G network.</p><div></div>
<p></p><p>Here is the full <a href="https://www.webpagetest.org/video/compare.php?tests=210414_AiDcZY_f5be5cec9691704310f8659401bf27df,210414_BiDcZ1_f16da211a5c7f589237b5c2b0e72634d">WegPageTest data</a> if you want to explore this example further.</p><p>There is also an <a href="https://github.com/ampproject/amp-toolbox/blob/main/packages/cloudflare-optimizer-scripts/benchmark/index.js">example benchmark script</a> you can adapt if you want to run performance tests on your own site.</p>
    <div>
      <h2>Summary</h2>
      <a href="#summary">
        
      </a>
    </div>
    <p>Cloudflare Workers offer a simple way to prepare your AMP pages for Google’s upcoming page experience launch. They offer a seamless integration that doesn’t require any changes in your CMS or server. Even better — with the new Cloudflare Workers Unbound, it becomes possible to perform even more advanced optimizations. Check out the <a href="https://github.com/ampproject/cloudflare-amp-optimizer">cloudflare-amp-optimizer</a> repository for more details on how to get started.</p> ]]></content:encoded>
            <category><![CDATA[Developer Week]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[AMP]]></category>
            <category><![CDATA[Cloudflare Workers]]></category>
            <category><![CDATA[Workers Unbound]]></category>
            <category><![CDATA[Performance]]></category>
            <guid isPermaLink="false">3XzoZwY99Dv8W1PqZBOsgp</guid>
            <dc:creator>Erwin van der Koogh</dc:creator>
            <dc:creator>Sebastian Benz</dc:creator>
            <dc:creator>Jake Fried</dc:creator>
        </item>
        <item>
            <title><![CDATA[Announcing AMP Real URL]]></title>
            <link>https://blog.cloudflare.com/announcing-amp-real-url/</link>
            <pubDate>Wed, 17 Apr 2019 00:45:00 GMT</pubDate>
            <description><![CDATA[ The promise of the AMP (Accelerated Mobile Pages) project was that it would make the web, and, in particular, the mobile web, much more pleasant to surf. The AMP HTML framework was designed to make web pages load quickly. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>The promise of the AMP (<a href="https://amp.dev/">Accelerated Mobile Pages</a>) project was that it would make the web, and, in particular, the mobile web, much more pleasant to surf. The AMP HTML framework was designed to make web pages load quickly, and not distract the user with extraneous content that took them away from focusing on the web page’s content.</p><p>It was particularly aimed at publishers (such as news organizations) that wanted to provide the best, fastest web experience for readers catching up on news stories and in depth articles while on the move. It later became valuable for any site which values their mobile performance including <a href="https://www.cloudflare.com/ecommerce/">e-commerce stores</a>, job boards, and media sites.</p><p>As well as the AMP HTML framework, AMP also made use of caches that store copies of AMP content close to end users so that they load as quickly as possible. Although this cache make loading web pages much, much faster they introduce a problem: An AMP page served from Google’s cache has a URL starting with <code>https://google.com/amp/</code>. This can be incredibly confusing for end users.</p><p>Users have become used to looking at the navigation bar in a web browser to see what web site they are visiting. The AMP cache breaks that experience. For example, here’s a news story from the BBC website viewed through Google’s AMP cache:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2o0JtbNro3j4HPq5ybHOSm/7e34a2a8525c63b9640de68e5b51504e/before.png" />
            
            </figure><p>Notice how the browser says the page is from google.com. That’s because of the AMP cache. This made the page load very quickly, but can be confusing. To help “fix” that problem Google shows that actual site at the top of the AMP page. There you can see that it was bbc.co.uk. Clicking on bbc.co.uk brings you to the same page served by the BBC’s web servers with bbc.co.uk in the web browser’s navigation bar:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1kHf6MYqZVKYyxYjlG5agU/81e875d1d0bc1f087705f8d3529de322/after.png" />
            
            </figure><p>But the problems with the AMP cache approach are deeper than just some confusion on the part of the user. By serving the page from Google’s cache there’s no way for the reader to check the authenticity of the page; when it’s served directly from, say, the BBC the user has the assurance of the domain name, a green lock indicating that the <a href="https://www.cloudflare.com/application-services/products/ssl/">SSL certificate </a>is valid and can even click on the lock to get details of the certificate.</p><p>Last November we announced a technical solution to these problems that would allow AMP pages to be served from a cache while retaining the original page URL and all its benefits. The in depth <a href="/real-urls-for-amp-cached-content-using-cloudflare-workers/">technical blog post</a> by Gabbi Fisher and Avery Harnish gives the full details. The solution makes use of <a href="https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html">Web Packaging</a> (which incorporates some clever use of cryptography) to allow the cache (run by Google, Cloudflare or others) to keep a copy of an AMP page and serve it quickly to the end user, but to also contain cryptographic proof of where the page originally came from.</p><p>In cooperation with a browser that understands Web Packaging this means that a page can be stored in an AMP cache and served quickly from it while showing the original site URL in the browser’s navigation bar. A major win all round!</p><p>We’re calling this “AMP Real URL” and it’s free to all of our customers starting today.</p>
    <div>
      <h3>How It Works</h3>
      <a href="#how-it-works">
        
      </a>
    </div>
    <p>Google’s AMP Crawler downloads the content of your website and stores it in the AMP Cache many times a day. If your site has AMP Real URL enabled Cloudflare will digitally sign the content we provide to that crawler, cryptographically proving it was generated by you. That signature is all a modern browser (currently just Chrome on Android) needs to show the correct URL in the address bar when a visitor arrives to your AMP content from Google’s search results.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4NWtcshqb2GvakMNINyonx/c086f872937ee33d96eda3b76199bee0/image-5.png" />
            
            </figure><p>Gone is the hated grey bar, all your visitors see is your proper URL:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/657yHd3WoERfitovjFBtzB/42aeccb882f07474ccce42073a0d9a76/image-6.png" />
            
            </figure><p>Importantly your site is still being served from Google’s AMP cache just as before; all of this comes without any cost to your SEO or <a href="https://www.cloudflare.com/solutions/ecommerce/optimization/">web performance</a>.</p><p>Since our original announcement we’ve had a chance to engage with dozens of members of the publishing and e-commerce community and would like to share what we’ve learned.</p>
    <div>
      <h3>State of AMP</h3>
      <a href="#state-of-amp">
        
      </a>
    </div>
    <p>The Google-initiated AMP Project drives a huge percentage of mobile traffic and has greatly improved the experience of browsing the Internet on a phone. Many of the sites we have spoken to get as much as 50% of their web traffic through AMP, and the speed benefit it provides directly translates to better conversion rates.</p><p>AMP Real URL provides some serious benefits to sites which use AMP:</p><ul><li><p><b>Brand Protection:</b> Web users have been trained that the URL in the address bar has significance. Having google.com at the top of a page of content hurts the publisher’s ability to maintain a unique presence on the Internet.</p></li><li><p><b>Easier Analytics:</b> AMP Real URL greatly simplifies web analytics for its users by allowing all visitors, AMP or otherwise, to coexist on the same tracking domain.</p></li><li><p><b>Increased Screen Space:</b> Historically when AMP was used room would be taken for a “grey bar” at the top of your site to show the real URL. With AMP Real URL that’s simply not necessary.</p></li><li><p><b>Reduced Bounce Rate:</b> We believe website visitors are less likely to bounce back to Google or another site when the publisher’s actual domain is in the address bar, but we will gather more data about this as AMP Real URL is rolled out.</p></li><li><p><b>Content Signing:</b> By relying on cryptographic techniques, AMP Real URL ensures that the content delivered to visitors has not been manipulated protecting the sites and brands it is used on. It’s now not possible for any external party to add, remove, or modify the content of a site.</p></li></ul><p>We also spoke to Internet users of AMP, and there certainly are frustrations. There are some users who struggle with its complexity, or sites simply fail to load for them. Others are annoyed and confused with the “grey bar” at the top of the page and the gymnastics it requires to get a page’s original URL. Finally, there are folks who would like to ensure that Google is not modifying the content of pages as they travel through the AMP cache.</p><p>AMP Real URL happily fixes all of these issues. It ensures that sites are <a href="/real-urls-for-amp-cached-content-using-cloudflare-workers/">cryptographically signed</a> which protects them from being modified by Google or anyone else, even when physically delivered from a domain you do not control. If the site is changed in any way the browser ensures the site’s real URL will no longer appear. It also greatly simplifies AMP, fixing many of the reliability issues people experience: AMP Real URL-powered links aren’t opened using the complex iframe mechanics used by AMP traditionally, instead they are loaded as any other website (Google uses <a href="https://css-tricks.com/prefetching-preloading-prebrowsing/">rel=”prefetch”</a> to get much of the same performance benefit). Finally, the “grey bar” is unnecessary, as the correct URL is right in the address bar at the top of the page, and copying the URL of a site to save or share works just as it does for non-AMP websites.</p><p>We are also taking this opportunity to sunset the other AMP products and experiments we have built over the years like <a href="/amp-validator-api/">Ampersand</a> and <a href="/firebolt/">Firebolt</a>. Those products were innovative but we have learned that publishers value AMP products which pair well with Google’s search results, not which live outside it. Users of those older products were informed several weeks ago that they will be gradually shut down to focus our attention on AMP Real URL.</p>
    <div>
      <h3>On Your Site</h3>
      <a href="#on-your-site">
        
      </a>
    </div>
    <p>Google is rolling out support for AMP Real URL (referred to as <a href="https://www.google.com/url?q=https://developers.google.com/web/updates/2018/11/signed-exchanges&amp;sa=D&amp;ust=1555447300613000">Signed Exchanges</a> outside Cloudflare) today, beginning with the primary Google search results. Over time, the hope is they will expand it to other areas of the search results page including the “Top Stories” news area at the top of the page. This makes AMP Real URL most valuable today for sites which get most of their AMP traffic from the primary search results like e-commerce, job boards, and ad-supported sites. News publishers can and should enable AMP Real URL, but the benefit they experience now will be from search results which live outside the “Top Stories” box. AMP Real URL is only supported in the Chrome browser at this time, but we are optimistic it will be supported more widely as its benefit to Internet users becomes clear.</p><p>After speaking with publishers and with Internet users, we have decided not to charge for AMP Real URL. This is not because our customers haven’t been excited or willing to pay for it, AMP makes up a huge component of many site’s traffic. Our motivation is the same as for offering CDN or SSL services to millions of customers free of charge, we are here to help build a better Internet and improving AMP is a huge step in that direction. We believe AMP Real URL is a technology which will fundamentally change the mobile web for the better and should be adopted by every AMP-supporting site. We do have another motive: we are hoping that this will motivate potential customers who value AMP to choose Cloudflare.</p><p>Beginning today you will find a new section on the Speed tab of your Cloudflare dashboard:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1NZ2d1MfNd5NB1fnBQrLpV/695455dfbfa2f939142ae736371707f8/image-7.png" />
            
            </figure><p>We will be rolling out support for AMP Real URL in stages over the next few weeks. Enable it now and we will notify you when it is activated on your domain. If you are an interested enterprise customer please reach out so we can expedite your activation.</p><p>We'll leave you with some perspectives from the early users of AMP Real URL:</p><p><i>"The performance benefits of AMP deliver value to our business and we are excited to see how AMP Real URL is able to take that even further"</i></p><p></p><p>— <b>Solomon Moskalenko</b>, Director of Interactive, US Xpress Trucking, The Johnson Group</p><p><i>"AMP is a crucial part of helping our business to grow and reach consumers everywhere. With AMP Real URL, we now have more control over our brand and can run analytics on our business site."</i></p><p></p><p>— <b>Sumantro Da</b>, Sr Director, Product Innovations &amp; Growth Brands GM, 1-800-FLOWERS.COM</p><p><i>“AMP has played a key role in helping us to more effectively reach our audience and develop our online community, we’re keen to use AMP Real URL to better manage our online presence and keep our users engaged on the site.”</i></p><p></p><p>— <b>Andrew Warner</b>, CTO of Genius</p> ]]></content:encoded>
            <category><![CDATA[AMP]]></category>
            <category><![CDATA[Mobile]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Speed & Reliability]]></category>
            <guid isPermaLink="false">65aoSL3O5kD0Mch4Hel7x0</guid>
            <dc:creator>Zack Bloom</dc:creator>
            <dc:creator>John Graham-Cumming</dc:creator>
        </item>
        <item>
            <title><![CDATA[Real URLs for AMP Cached Content Using Cloudflare Workers]]></title>
            <link>https://blog.cloudflare.com/real-urls-for-amp-cached-content-using-cloudflare-workers/</link>
            <pubDate>Tue, 13 Nov 2018 19:33:00 GMT</pubDate>
            <description><![CDATA[ As Cloudflare Workers matures, we continue to push ourselves to develop and deploy important features using them. Today, we’re excited to announce support for HTTP signed exchanges, generated by Cloudflare Workers! ]]></description>
            <content:encoded><![CDATA[ 
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5zK61KytdjS5NqmHTcWfrX/25a160e62d1bf1058ef6b61558fe9f60/amp-share-copy_4x.png" />
            
            </figure><p>Today, we’re excited to announce our solution for arguably the biggest issue affecting Accelerated Mobile Pages (AMP): the inability to use real origin URLs when serving AMP-cached content. To allow AMP caches to serve content under its origin URL, we implemented HTTP signed exchanges, which extend authenticity and integrity to content cached and served on behalf of a publisher. This logic lives on <a href="https://www.cloudflare.com/products/cloudflare-workers/">Cloudflare Workers</a>, meaning that adding HTTP signed exchanges to your content is just a simple Workers application away. Publishers on Cloudflare can now take advantage of AMP performance and have AMP caches serve content with their origin URLs. We're thrilled to use Workers as a core component of this solution.</p><p>HTTP signed exchanges are a crucial component of the emerging Web Packaging standard, a set of protocols used to package websites for distribution through optimized delivery systems like Google AMP. This announcement comes just in time for Chrome Dev Summit 2018, where our colleague Rustam Lalkaka spoke about our efforts to advance the Web Packaging standard.</p>
    <div>
      <h3>What is Web Packaging and Why Does it Matter?</h3>
      <a href="#what-is-web-packaging-and-why-does-it-matter">
        
      </a>
    </div>
    <p>You may already see the need for Web Packaging on a daily basis. On your smartphone, perhaps you’ve searched for Christmas greens, visited 1-800-Flowers directly from Google, and have been surprised to see content served under the URL <a href="https://google.com/amp/1800flowers.com/blog/flower-facts/types-of-christmas-greens/amp">https://google.com/amp/1800flowers.com/blog/flower-facts/types-of-christmas-greens/amp</a>. This is an instance of AMP in action, where Google serves cached content so your desired web page loads faster.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6kgYK09foa4H185JC2AaO4/26c0a7ef1039fd33516c1653bb7d2f70/ezgif-noAMP.gif" />
            
            </figure><p>Visiting 1-800 Flowers through AMP without HTTP signed exchange</p><p>Google cannot serve cached content under publisher URLs for clear security reasons. To securely present content from a URL, a <a href="https://www.cloudflare.com/application-services/products/ssl/">TLS certificate</a> for its domain is required. Google cannot provide 1-800-Flowers’ certificate on the vendor’s behalf, because it does not have the corresponding private key. Additionally, Google cannot, and should not be able to, sign content using the private key that corresponds to 1-800-Flowers’ certificate.</p><p>The inability to use original content URLs with AMP posed some serious issues. First, the google.com/amp URL prefix can strip URLs of their meaning. To the frustration of publishers, their content is no longer directly attributed to them by a URL (let alone a certificate). The publisher can no longer prove the integrity and authenticity of content served on their behalf.</p><p>Second, for web browsers the lack of a publisher’s URL can call the integrity and authenticity of a cached webpage into question. Namely, there’s no clear way to prove that this response is a cached version of an actual page published by 1-800-Flowers. Additionally, cookies are managed by third-party providers like Google instead of the publisher.</p><p>Enter Web Packaging, a <a href="https://github.com/WICG/webpackage">collection of specifications</a> for “packaging” website content with information like certificates and their validity. The <a href="https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html">HTTP signed exchanges specification</a> allows third-party caches to cache and service HTTPS requests with proof of integrity and authenticity.</p>
    <div>
      <h3>HTTP Signed Exchanges: Extending Trust with Cryptography</h3>
      <a href="#http-signed-exchanges-extending-trust-with-cryptography">
        
      </a>
    </div>
    <p>In the pre-AMP days, people expected to find a webpage’s content at one definitive URL. The publisher, who owns the domain of the definitive URL, would present a visitor with a certificate that corresponds to this domain and contains a public key.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6GeUoh4OBPc3gUuywTcGAE/651a5a6638d6eef794fc9bf6462983db/step-one_4x.png" />
            
            </figure><p>The publisher would use the corresponding private key to sign a cryptographic handshake, which is used to derive shared symmetric keys that are used to encrypt the content and protect its integrity.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/39tMMzRKPaWwXidW4fxyDw/edaf20ec675376ec08c0a9069a794d02/step-2_4x.png" />
            
            </figure><p>The visitor would then receive content encrypted and signed by the shared key.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2rOJWcnNjs0ps5CFQIDvZI/60fb1846557c2f9587e4d555ce03151a/step-3_4x.png" />
            
            </figure><p>The visitor’s browser then uses the shared key to verify the response’s signature and, in turn, the authenticity and integrity of the content received.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/17OtcMYs9DYkDblDZVcQj5/54cda01c719370ebf2546ca0d3652f2d/step-4_4x.png" />
            
            </figure><p>With services like AMP, however, online content may correspond to more than one URL. This introduces a problem: while only one domain actually corresponds to the webpage’s publisher, multiple domains can be responsible for serving a webpage. If a publisher allows AMP services to cache and serve their webpages, they must be able to sign their content even when AMP caches serve it for them. Only then can AMP-cached content prove its legitimacy.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/70Tx1Lvaj6AIDzjWUJPuXi/c1d9d474af8f2e1bb50aa0a6a145a9c5/step-4-copy-4_4x.png" />
            
            </figure><p>HTTP signed exchanges directly address the problem of extending publisher signatures to services like AMP. This <a href="https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html">IETF draft</a> specifies how publishers may sign an HTTP request/response pair (an exchange). With a signed exchange, the publisher can assure the integrity and authenticity of a response to a specific request even before the client makes the request. Given a signed exchange, the publisher authorizes intermediates (like Google’s AMP Cache) to forward the exchanges; the intermediate responds to a given request with the corresponding response in the signed HTTP request/response pair. A browser can then verify the exchange signature to assert the intermediate response’s integrity and authenticity.</p><p>This is like handing out an answer key to a quiz signed by the instructor. Having a signed answer sheet is just as good as getting the answer from the teacher in real time.</p>
    <div>
      <h3>The Technical Details</h3>
      <a href="#the-technical-details">
        
      </a>
    </div>
    <p>An HTTP signed exchange is generated by the following steps.First, the publisher uses <a href="https://tools.ietf.org/id/draft-thomson-http-mice-03.txt">MICE</a> (Merkle Integrity Content Encoding) to provide a concise proof of integrity for the response included in the exchange. To start, the response is split into blocks of some record size bits long. Take, for example, a message ABCD, which is divided into record-size blocks A, B, C, and D. The first step to constructing a proof of integrity is to take the last block, D, and compute the following:</p>
            <pre><code>proof(D) = SHA-256(D || 0x0)</code></pre>
            <p>This produces proof(D). Then, all consequent proof values for blocks are computed as follows:</p>
            <pre><code>proof(C) = SHA-256(C || proof(D) || 0x1)
proof(B) = SHA-256(B || proof(C) || 0x1)
proof(A) = SHA-256(A || proof(B) || 0x1)</code></pre>
            <p>The generation of these proofs build the following tree:</p>
            <pre><code>      proof(A)
         /\
        /  \
       /    \
      A    proof(B)
            /\
           /  \
          /    \
         B    proof(C)
                /\
               /  \
              /    \
             C    proof(D)
                    |
                    |
                    D</code></pre>
            <p>As such, proof(A) is a 256-bit digest that a person who receives the real response should be able to recompute for themselves. If a recipient can recompute a tree head value identical to proof(A), they can verify the integrity of the response they received. In fact, this digest plays a similar role to the tree head of a <a href="/introducing-certificate-transparency-and-nimbus/">Merkle Tree</a>, which is recomputed and compared to the presented tree head to verify the membership of a particular node. The MICE-generated digest is stored in the Digest header of the response.</p><p>Next, the publisher serializes the headers and payloads of a request/response pair into <a href="https://tools.ietf.org/html/rfc7049">CBOR</a> (Concise Binary Object Representation). CBOR’s key-value storage is structurally similar to JSON, but creates smaller message sizes.</p><p>Finally, the publisher signs the CBOR-encoded request/response pair using the private key associated with the publisher’s certificate. This becomes the value of the sig parameter in the HTTP signed exchange.</p><p>The final HTTP signed exchange appears like the following:</p>
            <pre><code>sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;  
integrity="digest/mi-sha256";  
validity-url="https://example.com/resource.validity.1511128380";  
cert-url="https://example.com/oldcerts";  
cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;  
date=1511128380; expires=1511733180</code></pre>
            <p>Services like AMP can send signed exchanges by using a new HTTP response format that includes the signature above in addition to the original response.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/30wTgi8lZo4TnZN0nsg73U/6de57d124bdd34b656633929962221b0/step-4-copy-3_4x.png" />
            
            </figure><p>When this signature is included in an AMP-cached response, a browser can verify the legitimacy of this response. First, the browser confirms that the certificate provided in cert-url corresponds to the request’s domain and is still valid. It next uses the certificate’s public key, as well as the headers and body values of request/response pair, to check the authenticity of the signature, sig. The browser then checks the integrity of the response using the given integrity algorithm, digest/mi-sha256 (aka MICE), and the contents of the Digest header. Now the browser can confirm that a response provided by a third party has the integrity and authenticity of the content’s original publisher.</p><p>After all this behind-the-scenes work, the browser can now present the original URL of the content instead of one prefixed by google.com/amp. Yippee to solving one of AMP’s most substantial pain points!</p>
    <div>
      <h3>Generating HTTP Signed Exchanges with Workers</h3>
      <a href="#generating-http-signed-exchanges-with-workers">
        
      </a>
    </div>
    <p>From the overview above, the process of generating an HTTP signed exchange is clearly involved. What if there were a way to automate the generation of HTTP signed exchanges and have services like AMP automatically pick them up? With Cloudflare Workers… we found a way you could have your HTTP origin exchange cake and eat it too!</p><p>We have already implemented HTTP signed exchanges for one of our customers, <a href="https://www.1800flowers.com/">1-800-Flowers</a>. Code deployed in a Cloudflare Worker is responsible for fetching and generating information necessary to create this HTTP signed exchange.</p><p>This Worker works with Google AMP’s automatic caching. When Google’s search crawler crawls a site, it will ask for a signed exchange from the same URL if it initially responds with Vary: AMP-Cache-Transform. Our HTTP signed exchange Worker checks if we can generate a signed exchange and if the current document is valid AMP. If it is, that Vary header is returned. After Google’s crawler sees this Vary header in the response, it will send another request with the following two headers:</p>
            <pre><code>AMP-Cache-Transform: google
Accept: application/signed-exchange;v=b2</code></pre>
            <p>When our implementation sees these header values, it will attempt to generate and return an HTTP response with Content-Type: application/signed-exchange;v=b2.</p><p>Now that Google has cached this page with the signed exchange produced by our Worker, the requested page will appear with the publisher’s URL instead of Google’s AMP Cache URL. Success!</p><p>If you’d like to see HTTP signed exchanges in action on 1-800-Flowers, follow these steps:</p><ol><li><p>Install/open Chrome Beta for Android. (It should be version 71+).</p></li><li><p>Go to <a href="https://goo.gl/webpackagedemo">goo.gl/webpackagedemo</a>.</p></li><li><p>Search for “Christmas greens.”</p></li><li><p>Click on the 1-800-Flowers link -- it should be about 3 spots down with the AMP icon next to it. Along the way to getting there you should see a blue box that says "Results with the AMP icon use web packaging technology." If you see a different message, double check that you are using the correct Chrome Beta.An example of AMP in action for 1-800-Flowers:</p></li></ol>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5j6PfikkSSKXgrgSRmvYFh/9af3b955be231c64435517d2466af692/ezgif-w-amp.gif" />
            
            </figure><p>Visiting 1-800 Flowers through AMP with HTTP signed exchange</p>
    <div>
      <h3>The Future: Deploying HTTP Signed Exchanges as a Worker App</h3>
      <a href="#the-future-deploying-http-signed-exchanges-as-a-worker-app">
        
      </a>
    </div>
    <p>Phew. There’s clearly a lot of infrastructure for publishers to build for distributing AMP content. Thankfully Cloudflare has <a href="https://www.cloudflare.com/network/">one of the largest networks in the world</a>, and we now have the ability to execute JavaScript at the edge with <a href="https://www.cloudflare.com/network/">Cloudflare Workers</a>. We have developed a prototype Worker that generates these exchanges, on the fly, for any domain. If you’d like to start experimenting with signed exchanges, <a href="https://www.cloudflare.com/website-optimization/ampersand/">we’d love to talk</a>!</p><p>Soon, we will release this as a Cloudflare Worker application to our AMP customers. We’re excited to bring a better AMP experience to internet users and advance the Web Packaging standard. Stay tuned!</p>
    <div>
      <h3>The Big Picture</h3>
      <a href="#the-big-picture">
        
      </a>
    </div>
    <p>Web Packaging is not simply a technology that helps fix the URL for AMP pages, it’s a fundamental shift in the way that publishing works online. For the entire history of the web up until this point, publishers have relied on transport layer security (TLS) to ensure that the content that they send to readers is authentic. TLS is great for protecting communication from attackers but it does not provide any public verifiability. This means that if a website serves a specific piece of content to a specific user, that user has no way of proving that to the outside world. This is problematic when it comes to efforts to archive the web.</p><p>Services like the Internet Archive crawl websites and keep a copy of what the website returns, but who’s to say they haven’t modified it? And who’s to say that the site didn’t serve a different version of the site to the crawler than it did to a set of readers? Web Packaging fixes this issue by allowing sites to digitally sign the actual content, not just the cryptographic keys used to transport data. This subtle change enables a profoundly new ability that we never knew we needed: the ability to record and archive content on the Internet in a trustworthy way. This ability is something that is lacking in the field of online publishing. If Web Packaging takes off as a general technology, it could be the first step in creating a trusted digital record for future generations to look back on.</p><p>Excited about the future of Web Packaging and AMP? Check out <a href="https://www.cloudflare.com/website-optimization/ampersand/">Cloudflare Ampersand</a> to see how we're implementing this future.</p> ]]></content:encoded>
            <category><![CDATA[Serverless]]></category>
            <category><![CDATA[Cloudflare Workers]]></category>
            <category><![CDATA[JavaScript]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[AMP]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[HTTPS]]></category>
            <category><![CDATA[Mobile]]></category>
            <category><![CDATA[Programming]]></category>
            <category><![CDATA[Developer Platform]]></category>
            <guid isPermaLink="false">2vBadQs4BUhz2xKzJQ5Bll</guid>
            <dc:creator>Gabbi Fisher</dc:creator>
            <dc:creator>Avery Harnish</dc:creator>
        </item>
        <item>
            <title><![CDATA[An AMP validator you can cURL]]></title>
            <link>https://blog.cloudflare.com/amp-validator-api/</link>
            <pubDate>Wed, 08 Mar 2017 14:01:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare has been a long time supporter of AMP, an open-source markup language 1.5 billion web pages are using to accelerate their mobile web performance. Cloudflare runs Ampersand. ]]></description>
            <content:encoded><![CDATA[ <p>NOTE: <i>This feature is no longer available. Please see the </i><a href="/announcing-amp-real-url/"><i>AMP Real URL post</i></a><i>.</i> </p><hr /><p>Cloudflare has been a long time supporter of <a href="https://www.ampproject.org/">AMP</a>, an open-source markup language 1.5 billion web pages are using to accelerate their mobile web performance. Cloudflare runs <a href="https://www.cloudflare.com/website-optimization/ampersand/">Ampersand</a>, the only alternative to Google’s AMP cache, and earlier this year we launched <a href="/accelerated-mobile/">Accelerated Mobile Links</a>, a way for sites on Cloudflare to open external links on their site in AMP format, as well as <a href="https://www.cloudflare.com/website-optimization/firebolt/">Firebolt</a>, leveraging AMP to speed up ad performance.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3AA1JRxaaIaO9Ld8I39pXi/d415dd595275e382469b7503be68790d/icon_mobile-interface-1.png" />
            
            </figure><p>One of the biggest challenges developers face in converting their web pages to AMP is testing their AMP pages for valid AMP syntax before deploying. It's not enough to make the templates work at dev time, you also need to validate individual pages before they’re published.</p><p>Imagine, for example, a publishing company where content creators who are unfamiliar with AMP are modifying pages. Because the AMP markup language is so strict, one person adding an interactive element to a page can all of a sudden break the AMP formatting and stop the page from validating.</p><p>We wanted to make it as easy as possible to move webpages and sites to AMP so we built an AMP linter API for developers to check that their AMP pages are formatted correctly, even before they are deployed.</p><p>To check if a webpage’s AMP markup is correct, just send the AMP page to the endpoint <code>URL Removed</code> like this:</p>
            <pre><code>curl URL REMOVED/amp.usatoday.com/story/82055560/
{
  "source": "http://amp.usatoday.com/story/82055560/", 
  "valid": true, 
  "version": "1488238516283"
}</code></pre>
            <p>The API has options to send just the markup content, or point the linter to the live site. To send a file, add the <code>--data-binary</code> flag:</p>
            <pre><code>curl -X POST --data-binary @amp_page.html -H 'Content-Type: text/html; charset=UTF-8' URL REMOVED</code></pre>
            <p>If you send an AMP page with invalid AMP syntax, the message returned will tell you exactly what breaks your AMP page, and will point you to the specific place in the AMP reference where you can see the implementation guide for the broken element.</p>
            <pre><code>curl -X POST --data-binary @invalid_amp.html -H 'Content-Type: text/html; charset=UTF-8' URL REMOVED
{
  "errors": [
    {
      "code": "MANDATORY_TAG_MISSING", 
      "col": 7, 
      "error": "The mandatory tag 'link rel=canonical' is missing or incorrect.", 
      "help": "https://www.ampproject.org/docs/reference/spec.html#required-markup", 
      "line": 13
    }
  ], 
  "source": "POST", 
  "valid": false, 
  "version": "1485227592804"
}

</code></pre>
            <p>Here’s a reference in python, and if you want to send html directly instead of a live webpage, replace line two with <code>r = requests.post([URL Removed], data=html)</code></p>
            <pre><code>import requests

u = 'www.bbc.co.uk/news/amp/39192025'
r = requests.get('URL REMOVED' + u)
validation = r.json()
if validation['valid']:
  print u, 'is valid'
else:
  print u, 'failed!'
  for e in validation['errors']: 
    print e</code></pre>
            <p>Let us know what you think - you can send us feedback at <a href="#">amp-publisher@cloudflare.com</a>. Whether you embed this tool into your build and continuous integration processes, or into your CMS workflows, we’re excited to hear how you use it.</p><p>We protect <a href="https://www.cloudflare.com/network-services/">entire corporate networks</a>, help customers build <a href="https://workers.cloudflare.com/">Internet-scale applications efficiently</a>, accelerate any <a href="https://www.cloudflare.com/performance/accelerate-internet-applications/">website or Internet application</a>, <a href="https://www.cloudflare.com/ddos/">ward off DDoS attacks</a>, keep <a href="https://www.cloudflare.com/application-security/">hackers at bay</a>, and can help you on <a href="https://www.cloudflare.com/products/zero-trust/">your journey to Zero Trust</a>.</p><p>Visit <a href="https://one.one.one.one/">1.1.1.1</a> from any device to get started with our free app that makes your Internet faster and safer.</p><p>To learn more about our mission to help build a better Internet, <a href="https://www.cloudflare.com/learning/what-is-cloudflare/">start here</a>. If you're looking for a new career direction, check out <a href="http://www.cloudflare.com/careers">our open positions</a>.</p> ]]></content:encoded>
            <category><![CDATA[AMP]]></category>
            <category><![CDATA[Cache]]></category>
            <guid isPermaLink="false">7oJ1e03JkUiJLidnpslltc</guid>
            <dc:creator>Dani Grant</dc:creator>
        </item>
        <item>
            <title><![CDATA[Firebolt: the fastest, safest ads on the web]]></title>
            <link>https://blog.cloudflare.com/firebolt/</link>
            <pubDate>Mon, 30 Jan 2017 19:46:19 GMT</pubDate>
            <description><![CDATA[ Cloudflare’s mission is to help build a better Internet. That means a faster, more secure, open Internet world-wide. We have millions of customers using our services like free SSL, an advanced WAF. ]]></description>
            <content:encoded><![CDATA[ <p>Cloudflare’s mission is to help build a better Internet. That means a faster, more secure, open Internet world-wide. We have millions of customers using our services like <a href="https://www.cloudflare.com/application-services/products/ssl/">free SSL</a>, an advanced <a href="https://www.cloudflare.com/waf/">WAF</a>, the latest <a href="/a-very-webp-new-year-from-cloudflare/">compression</a> and the most up to date <a href="https://www.cloudflare.com/security/">security</a> to ensure that their web sites, mobile apps and APIs are secure and fast.</p><p>One vital area of web technology has lagged behind in terms of speed and security: online ads. And consumers have been turning to ad blocking technology to secure and speed up their own web browsing. </p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4sU8gDStetbUmC87cHg7V2/d69b2e495d829f05040c1762739ec15e/image00-1.png" />
            
            </figure><p>Today, Cloudflare is introducing a new product to make web ads secure, fast and safe. That product is <i>Firebolt</i>.</p>
    <div>
      <h3>Firebolt</h3>
      <a href="#firebolt">
        
      </a>
    </div>
    <p>With Firebolt, ad networks can instantly speed up and secure their ads, resulting in happy consumers and better conversion rates.</p><p>Firebolt delivers: </p>
    <div>
      <h4>Lightning fast ad delivery</h4>
      <a href="#lightning-fast-ad-delivery">
        
      </a>
    </div>
    <p>Cloudflare's global network of 102 data centers in 50 countries, combined with routing and performance technologies, makes the delivery of online ads to any device up to five times faster.</p>
    <div>
      <h4>Free, simple SSL</h4>
      <a href="#free-simple-ssl">
        
      </a>
    </div>
    <p>Adding SSL to ad serving has been challenging for some ad networks. Cloudflare has years of experience providing <a href="https://www.cloudflare.com/application-services/products/ssl/">free, one click SSL</a> for our customers. Firebolt ads are automatically available over SSL with <a href="https://www.cloudflare.com/application-services/solutions/certificate-lifecycle-management/">no complex process of getting and maintaining SSL certificates</a>.</p>
    <div>
      <h4>Firebolt includes AMP for Ads</h4>
      <a href="#firebolt-includes-amp-for-ads">
        
      </a>
    </div>
    <p>Firebolt enables any independent ad network to leverage the new AMP ad format easily. This makes it possible for ads to appear in AMP content served by Google and an increasing number of sites. Firebolt is the only independent way to serve the <a href="https://www.cloudflare.com/website-optimization/firebolt/">newly announced AMP for Ads</a> outside of Google’s advertising network.</p>
    <div>
      <h4>Cryptographically signed ads</h4>
      <a href="#cryptographically-signed-ads">
        
      </a>
    </div>
    <p>All ad content delivered by Firebolt for AMP for Ads is cryptographically signed to ensure that it meets the required format and security standards. Signed ads reduce the risk of malware and increase confidence in ads for consumers.</p>
    <div>
      <h4>The most advanced browser security</h4>
      <a href="#the-most-advanced-browser-security">
        
      </a>
    </div>
    <p>Firebolt ads take advantage of web browser security features including CORS, X-Content-Type-Options and Strict-Transport-Security to ensure the integrity of ads delivered to browsers.</p>
    <div>
      <h3>A faster, safer Internet for everyone</h3>
      <a href="#a-faster-safer-internet-for-everyone">
        
      </a>
    </div>
    <p>Firebolt takes us one step closer to making the Internet a better place by benefitting everyone in the ad ecosystem, including the consumer.</p><p>During a recent test, ad platform TripleLift used Cloudflare's Firebolt to serve AMP ads on Time Inc.'s properties. Ads loaded <b>six times faster</b> and Time Inc. saw <b>13 percent more revenue</b> relative to traditional ads. “<i>Cloudflare was easy to set up, and we saw an impressive difference in the speed of ad delivery with Firebolt's support for AMP for Ads</i>," said Shaun Zacharia, co-founder and President of TripleLift. "<i>AMP Ads loaded six times faster and were three times lighter than comparable standard ads.</i>"</p><p>If you are an ad network or publisher, please reach out to <a href="#">firebolt@cloudflare.com</a> to learn more about Firebolt and how Cloudflare can help you monetize the Internet content we all rely on.</p> ]]></content:encoded>
            <category><![CDATA[Advertising]]></category>
            <category><![CDATA[Speed & Reliability]]></category>
            <category><![CDATA[AMP]]></category>
            <category><![CDATA[SSL]]></category>
            <category><![CDATA[Security]]></category>
            <guid isPermaLink="false">4IP5JTJN5gmrdshxjVlRLe</guid>
            <dc:creator>Dane Knecht</dc:creator>
        </item>
        <item>
            <title><![CDATA[Introducing Accelerated Mobile Links: Making the Mobile Web App-Quick]]></title>
            <link>https://blog.cloudflare.com/accelerated-mobile/</link>
            <pubDate>Thu, 12 Jan 2017 06:00:00 GMT</pubDate>
            <description><![CDATA[ We've predicted that more than half of the traffic to Cloudflare's network will come from mobile devices. Even if they are formatted to be displayed on a small screen, the mobile web is built on traditional web protocols and technologies that were designed for desktop. ]]></description>
            <content:encoded><![CDATA[ <p>In 2017, we've predicted that more than half of the traffic to Cloudflare's network will come from mobile devices. Even if they are formatted to be displayed on a small screen, the mobile web is built on traditional web protocols and technologies that were designed for desktop CPUs, network connections, and displays. As a result, browsing the mobile web feels sluggish compared with using native mobile apps.</p><p>In October 2015, the team at Google announced <a href="http://ampproject.org">Accelerated Mobile Pages (AMP)</a>, a new, open technology to make the mobile web as fast as native apps. Since then, a large number of publishers have adopted AMP. Today, 600 million pages across 700,000 different domains are available in the AMP format.</p><p>The majority of traffic to this AMP content comes from people running searches on Google.com. If a visitor finds content through some source other than a Google search, even if the content can be served from AMP, it typically won't be. As a result, the mobile web continues to be slower than it needs to be.</p>
    <div>
      <h4>Making the Mobile Web App-Quick</h4>
      <a href="#making-the-mobile-web-app-quick">
        
      </a>
    </div>
    <p>Cloudflare's <a href="https://www.cloudflare.com/website-optimization/accelerated-mobile-links/">Accelerated Mobile Links</a> helps solve this problem, making content, regardless of how it's discovered, app-quick. Once enabled, Accelerated Mobile Links automatically identifies links on a Cloudflare customer's site to content with an <a href="https://www.cloudflare.com/website-optimization/accelerated-mobile-links/">AMP</a> version available. If a link is clicked from a mobile device, the AMP content will be loaded nearly instantly.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5ieCvJzcYWwJ2YOKbUrKFZ/b68843dc767ab04a1d6e1d5ccb08b44f/amp-configuration-1.png" />
            
            </figure><p>To see how it works, try viewing this post from your mobile device and clicking any of these links:</p><ul><li><p><b>TechCrunch:</b> <a href="https://techcrunch.com/2017/01/11/cloudflare-explains-how-fbi-gag-order-impacted-business/">Cloudflare explains how FBI gag order impacted business</a></p></li><li><p><b>ZDNet:</b> <a href="http://www.zdnet.com/article/cloudflare-offers-http2-server-push-to-boost-internet-speeds/">CloudFlare figured out how to make the Web one second faster</a></p></li><li><p><b>The Register:</b> <a href="http://www.theregister.co.uk/2016/06/21/cloudflare_apologizes_for_telia_screwing_you_over/">CloudFlare apologizes for Telia screwing you over</a></p></li><li><p><b>AMP 8 Ball:</b> <a href="https://amp8ball.com/">Ask The Amp Magic 8-Ball A Yes Or No Question.</a></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4LVE0NPtwr0c0kluYKwhAR/506cdb4a92c3c32b632e5cfdfc03d429/AML_animated_demo.gif" />
            
            </figure></li></ul>
    <div>
      <h4>Increasing User Engagement</h4>
      <a href="#increasing-user-engagement">
        
      </a>
    </div>
    <p>One of the benefits of Accelerated Mobile Links is that AMP content is loaded in a viewer directly on the site that linked to the content. As a result, when a reader is done consuming the AMP content closing the viewer returns them to the original source of the link. In that way, every Cloudflare customers' site can be more like a native mobile app, with the corresponding increase in user engagement.</p><p>For large publishers that want an even more branded experience, Cloudflare will offer the ability to customize the domain of the viewer to match the publisher's domain. This, for the first time, provides a seamless experience where AMP content can be consumed without having to send visitors to a Google owned domain. If you're a large publisher interested in customizing the Accelerated Mobile Links viewer, you can contact <a href="#">Cloudflare's team</a>.</p>
    <div>
      <h4>Innovating on AMP</h4>
      <a href="#innovating-on-amp">
        
      </a>
    </div>
    <p>While Google was the initial champion of AMP, the technologies involved are <a href="https://github.com/ampproject/amphtml">open</a>. We worked closely with the Google team in developing Cloudflare's Accelerated Mobile Links as well as our own AMP cache. Malte Ubl, the technical lead for the AMP Project at Google said of our collaboration:</p><p><i>"Working with Cloudflare on its AMP caching solution was as seamless as open-source development can be. Cloudflare has become a regular contributor on the project and made the code base better for all users of AMP. It is always a big step for a software project to go from supporting specific caches to many, and it is awesome to see Cloudflare’s elegant solution for this."</i></p><p>Cloudflare now powers the only <a href="https://github.com/ampproject/amphtml/blob/master/spec/amp-cache-guidelines.md">compliant</a> non-Google AMP cache with all the same performance and security benefits as Google.</p><p>In the spirit of open source, we're working to help develop updates to the project to address some of publishers' and end users' concerns. Specifically, here are some features we're developing to address concerns that have been expressed about AMP:</p><ul><li><p>Easier ways to share AMP content using publisher's original domains</p></li><li><p>Automatically redirecting desktop visitors from the AMP version back to the original version of the content</p></li><li><p>A way for end users who would prefer not to be redirected to the AMP version of content to opt out</p></li><li><p>The ability for publishers to brand the AMP viewer and serve it from their own domain</p></li></ul><p>Cloudflare is committed to the AMP project. Accelerated Mobile Links is the first AMP feature we're releasing, but we'll be doing more over the months to come. As of today, Accelerated Mobile Links is available to all Cloudflare customers for free. You can enable it in your <a href="https://www.cloudflare.com/a/performance/">Cloudflare Performance dashboard</a>. Stay tuned for more AMP features that will continue to increase the speed of the mobile web.</p> ]]></content:encoded>
            <category><![CDATA[Mobile]]></category>
            <category><![CDATA[Google]]></category>
            <category><![CDATA[AMP]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Speed & Reliability]]></category>
            <category><![CDATA[Optimization]]></category>
            <guid isPermaLink="false">7ztp6Ye5JzaL00PeVFH5va</guid>
            <dc:creator>Matthew Prince</dc:creator>
        </item>
        <item>
            <title><![CDATA[Generating Documentation for TypeScript Projects]]></title>
            <link>https://blog.cloudflare.com/generating-documentation-for-typescript-projects/</link>
            <pubDate>Sat, 12 Nov 2016 13:00:00 GMT</pubDate>
            <description><![CDATA[ Traditionally, JavaScript docs use code comments. This post explores generating documentation directly from TypeScript source code, a more efficient alternative. ]]></description>
            <content:encoded><![CDATA[ <p>Documentation for JavaScript projects has traditionally been generated via annotations inserted as code comments. While this gets the job done, it seems far from ideal. In this post, I’ll explore how to use TypeScript to generate documentation from source code alone.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3w7jaH3B0aNtw8NPhF6CPm/8af4c055c48aa7b1a2ffcdaf341117bf/511102367_1ce398ad1d_o.png" />
          </figure><p><a href="https://creativecommons.org/licenses/by-sa/2.0/"><sub>CC BY-SA 2.0</sub></a><sub> </sub><a href="https://www.flickr.com/photos/davidjoyner/511102367/in/photolist-MawVM-7zyucG-7aZ4QT-6GBfU4-aFrGn6-unAh43-axBGXx-ciiroq-92cKAD-iER1r2-5bRGPh-92fVBf-92fQBm-iER1Gc-2JMg5k-8rfzDR-iERFKo-jL2WXi-iEU2RU-jL4n6N-nqbf3-iER2q6-6H9k7G-dgnntH-eMMtEx-hHiLuM-9Sx4wb-9pCef2-9RLkVe-iEU1Nb-jL27Jr-ai89xS-dWQYFd-dyZqij-7cnSxN-8dyQSg-6yATnF-3om4q-nMWdCg-2KEjsj-eoQ3Lw-eoQfdN-9snnkJ-abB6Hb-2KEvib-eoQcXG-iEU2xh-9Hz7sB-5VhaNf-2KzRJp"><sub>image</sub></a><sub> by </sub><a href="https://www.flickr.com/photos/davidjoyner/"><sub>David Joyner</sub></a></p><p><a href="https://www.typescriptlang.org/">TypeScript</a> is JavaScript with optional types. Here’s a simple example:</p>
            <pre><code>// Sends some data to some analytics endpoint
function sendAnalyticsJS(data) {
  if (typeof data.type !== 'string') {
    throw new Error('The `type` property is required')
  }

  navigator.sendBeacon('/beacon', JSON.stringify(data))
}


// Results in run-time error
//    The `type` property is required
sendAnalyticsJS({ foo: 'bar' })</code></pre>
            <p>The JavaScript code will result in a run-time error. This is fine if the developer catches it early, but it would be better if the developer were warned as the bug was introduced. Here’s the same code written using TypeScript:</p>
            <pre><code>// Describe the shape of the data parameter
interface IAnalyticsData {
  // Type is required
  type: string
  // All other fields are fair game
  [propName: string]: string
}


// We don’t particularly need the data.type check here since
// the compiler will stamp out the majority of those cases.
function sendAnalytics(data: IAnalyticsData) {
  if (typeof data.type !== 'string') {
    throw new Error('The `type` property is required')
  }

  navigator.sendBeacon('/beacon', JSON.stringify(data))
}


// Results in compile-time error:
//   Argument of type '{ foo: string; }' is not assignable to
//   parameter of type 'IAnalyticsData'.
//   Property 'type' is missing in type '{ foo: string; }'.
sendAnalytics({ foo: 'bar' })</code></pre>
            <p>These annotations are all optional and the more you add, the more the compiler can help you. Compiling the TypeScript version results in code equivalent to the first example. The only difference is that the developer is warned about an error while writing the code.</p><p>With TypeScript, JavaScript developers are given powerful tools that aid the development of applications, large and small. Anders Hejlsberg, lead architect of C# and core dev for TypeScript, describes the language as, “JavaScript that scales.”</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3jIOfMZV8iXfXxcMK7BE3k/d6a0cd9a3506b97173a9eb5c45dd3844/code-peek.gif" />
          </figure><p>Using TypeScript means you can:</p><ul><li><p>Interactively explore library interfaces from your text editor</p></li><li><p>Enjoy useful auto-completion</p></li><li><p>Use good <a href="https://www.cloudflare.com/learning/cloud/how-to-refactor-applications/">refactoring</a> tools</p></li><li><p>Navigate your codebase via the ontology that describes it (by that, I mean jumping to class and interface definitions, modules, etc. from individual instances/references)</p></li><li><p>And most importantly to this post, generate documentation that’s tightly coupled to your codebase.</p></li></ul>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4o7pH1ZjdsErMByLoT0rIo/20a9cdb37bb362904cef82980d290fb1/amp-viewer-docs-2.png" />
          </figure><p><sub><i>The screenshot above is of the generated documentation from a TypeScript project at Cloudflare.</i></sub></p>
    <div>
      <h3>Why not JSDoc?</h3>
      <a href="#why-not-jsdoc">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6gM4NbM9ekay7QlBVJrifP/f6bb60a9c6d50eb2ade0172d616832c1/jsdoc-example-1.png" />
          </figure><p>The amount of work required to annotate source code with JSDoc comments is comparable to adopting TypeScript annotations. However, JSDoc comments are not tightly coupled to the codebase, so when the code changes, an independent change of the JSDoc comment is also required. Contrast to TypeScript where the structure is gleaned directly from the source. Here’s a side-by-side comparison between JSDoc and TypeScript:</p>
            <pre><code>/**
 * A class representing a point
 * @class  Point
 */
class Point {
  /**
   * Create a point.
   * @param {number} x - The x value.
   * @param {number} y - The y value.
   */
  constructor(x, y) {
    /**
     * The x coordinate
     * @name  Point#x
     * @type {number}
     */
    this.x = x
    /**
     * The y coordinate
     * @name  Point#y
     * @type {number}
     */
    this.y = y
  }


  /**
   * Get the x value.
   * @return {number} The x value.
   */
  getX() {
    return this.x
  }


  /**
   * Get the y value.
   * @return {number} The y value.
   */
  getY() {
    return this.y
  }


  /**
   * Convert a string containing two comma-separated numbers into a point.
   * @param {string} str - The string containing two comma-separated numbers.
   * @return {Point} A Point object.
   */
  static fromString(str) {
    const args = str.split(',').map(arg =&gt; +arg)
    return new Point(args[0], args[1])
  }
}</code></pre>
            <p><b>TypeScript</b></p>
            <pre><code>/** Class representing a point. */
class Point {
  /** The x coordinate */
  public x: number
  /** The x coordinate */
  public y: number


  /**
   * Create a point.
   * @param x - The x value.
   * @param y - The y value.
   */
  constructor(x: number, y: number) {
    this.x = x
    this.y = y
  }


  /**
   * Get the x value.
   */
  getX() {
    return this.x
  }


  /**
   * Get the y value.
   */
  getY() {
    return this.y
  }

  /**
   * Convert a string containing two comma-separated numbers into a point.
   * @param str - The string containing two comma-separated numbers.
   */
  static fromString(str: string): Point {
    const args = str.split(',').map(arg =&gt; +arg)
    return new Point(args[0], args[1])
  }
}</code></pre>
            <p>The above code sample was taken from the <a href="http://usejsdoc.org/howto-es2015-classes.html#documenting-a-simple-class">JSDoc documentation</a> and adapted for use with TypeScript.</p><p>The annotations for TypeScript are much more compact, they’re syntax-highlighted, and most importantly, if something is wrong, the compiler lets us know. Long-form descriptions of things are still made in comments, but the type information has been moved into language semantics.</p><p>The downside to adopting TypeScript is the large amount of work required to fit the build tools into your current processes. However, we won’t focus on the nitty-gritty details of build tools since the ecosystem is rapidly changing.</p>
    <div>
      <h3>Using TypeDoc</h3>
      <a href="#using-typedoc">
        
      </a>
    </div>
    <p>At Cloudflare, we use a tool called <a href="http://typedoc.org/">TypeDoc</a> to help build documentation. It’s set up such that documentation-generation is on watch and will re-build on codebase changes. Anybody hacking on the project will always have up-to-date docs at localhost:3000/docs.</p><p>If you’re using TypeScript 2.x, use the following command to install TypeDoc for your project:</p>
            <pre><code>npm install --save-dev https://github.com/DatenMetzgerX/typedoc/tarball/typescript-2-build</code></pre>
            <p>Otherwise, for prior versions of TypeScript, you can install straight from </p>
            <pre><code>npm install --save-dev typedoc</code></pre>
            <p>From within your project directory, run the following command:</p>
            <pre><code># Change the --out flag to wherever you’d like the output to be stored
./node_modules/.bin/typedoc --out dist/docs --mode modules .</code></pre>
            <p>You should see a bunch of HTML documents generated. One for each class and module.</p>
            <pre><code>dist/docs
├── assets
│   ├── css
│   │   ├── main.css
│   │   └── main.css.map
│   ├── images
│   │   ├── icons.png
│   │   ├── icons@2x.png
│   │   ├── widgets.png
│   │   └── widgets@2x.png
│   └── js
│       ├── main.js
│       └── search.js
├── classes
│   ├── _src_my_class.html
│   └── ...
├── globals.html
├── index.html
├── interfaces
│   ├── _src.my_interface.html
└── modules
    ├── _src_my_module_.html
    └── ...</code></pre>
            <p>I wanted to build something akin to <a href="https://lodash.com/docs">Lodash’s documentation</a> (a beautiful single page API reference with examples and links to source code). Luckily, you can use TypeDoc’s --json flag to produce a set of useful descriptions of your codebase in JSON format.</p>
            <pre><code>./node_modules/.bin/typedoc --json dist/docs.json --mode modules</code></pre>
            <p><i>Note: In order to use the --json flag, you’ll need to setup a proper </i><a href="https://www.typescriptlang.org/docs/handbook/tsconfig-json.html"><i>tsconfig.json</i></a><i> for your TypeScript project.</i></p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3xn0KEhoWHUw1oYZNtv7yX/d7107a0ca746db90d9fe50a8aa6e5e51/ts-docs-post-screen-1.png" />
          </figure><p>With this high-level, structured description of our code base, we can render any HTML we’d like with a few scripts and a templating language like <a href="http://handlebarsjs.com/">Handlebars</a>. Here’s a simple script to render a list of code base modules:</p>
            <pre><code>const fs = require('fs')
const hbs = require('handlebars')
const project = require('./dist/docs.json')


// The HTML template to use for our simple docs
const tmpl = `
&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;My Project Documentation&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1&gt;Modules&lt;/h1&gt;
    &lt;ul&gt;
    {{#each project.children}}
      &lt;li&gt;{{this.name}}&lt;/li&gt;
    {{/each}}
    &lt;/ul&gt;
  &lt;/body&gt;
&lt;/html&gt;
`


// Compile the template with handlebars using our project
// object as context key
const result = hbs.compile(tmpl)({ project })


fs.writeFileSync('dist/docs.html', result)</code></pre>
            <p>While this means that there is a lot of work up front to create a template that suits the needs of this particular code base, I hope to use the same infrastructure for TypeScript projects at Cloudflare moving forward.</p>
    <div>
      <h3>More Than API Reference</h3>
      <a href="#more-than-api-reference">
        
      </a>
    </div>
    <p>TypeDoc gets us halfway there. It provides a structured and automated way to create reference material that is always in sync with our codebase; but we can do more than reference material. Suppose you’re writing a getting-started.md file. You might say something like this:</p>
            <pre><code>To get started, call the `viewer.init()` method.</code></pre>
            <p>Since we’re using TypeDoc and Handlebars, we can assume we have all the information necessary to actually link to the source code. That might look something like this:</p>
            <pre><code>{{!-- Pull the AMPViewer class into scope --}}
{{#Class "AMPViewer"}}
{{!-- Pull the init member from AMPViewer into scope --}}
{{#Member "init"}}
{{!-- Link viewer.init(...) to its location in the source code --}}
{{!-- Also, if the function signature of the .init() method ever changes, --}}
{{!-- it will be reflected here --}}
To get started, call the
`viewer.[init({{&gt; signature signature=signatures.0}})]({{getSourceURL this.sources.0}})`
{{/Member}}
{{/Class}}</code></pre>
            <p>While the above looks arcane, it’s just Markdown and Handlebars. The template contains a block helper called Class that will pull the AMPViewer class object into the current scope. Then using the AMPViewer class, we pull the init member into the current scope. We use the {{&gt; signature}} partial to pretty-print the function’s signature and the getSourceUrl helper to link to this method in the source code.</p><p>If the source code changes, our docs update too.</p>
    <div>
      <h3>Open Source and Beyond</h3>
      <a href="#open-source-and-beyond">
        
      </a>
    </div>
    <p>Over next couple of months, we’ll be open sourcing the tools we’ve created to generate our documentation. We’ll also open source the theme shown in this post so you can generate docs without worrying about the styling. We hope to create a rich TypeScript ecosystem and to have fantastic documentation for all of our projects.</p><p>If you’re thinking of generating documentation by annotating your source, use TypeScript instead and enjoy the benefits.</p> ]]></content:encoded>
            <category><![CDATA[JavaScript]]></category>
            <category><![CDATA[AMP]]></category>
            <category><![CDATA[Open Source]]></category>
            <category><![CDATA[Programming]]></category>
            <guid isPermaLink="false">5ff63m4WxGcMQJHDnKARpr</guid>
            <dc:creator>John Fawcett</dc:creator>
        </item>
    </channel>
</rss>