<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Web performance</title>
    <description>Dries Buytaert on Web performance.</description>
    <link>https://dri.es/tag/performance</link>
    <atom:link href="https://dri.es/tag/performance/rss.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>The little HTTP Header Analyzer that could</title>
      <link>https://dri.es/the-little-http-header-analyzer-that-could</link>
      <guid>https://dri.es/the-little-http-header-analyzer-that-could</guid>
      <pubDate>Thu, 01 Feb 2024 08:49:25 -0500</pubDate>
      <description>&lt;p&gt;HTTP headers play a crucial part in making your website fast and secure. For that reason, I often inspect HTTP headers to troubleshoot caching problems or review security settings.&lt;/p&gt;
&lt;p&gt;The complexity of the &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc9110.html&quot;&gt;HTTP standard&lt;/a&gt; and the challenge to remember all the best practices led me to develop an &lt;a href=&quot;https://headers.dev/analyze&quot;&gt;HTTP Header Analyzer&lt;/a&gt; four years ago.&lt;/p&gt;
&lt;p&gt;It is pretty simple: enter a URL, and the tool will analyze the headers sent by your web application. It then explains these headers, provides a score, and suggests possible improvements.&lt;/p&gt;
&lt;p&gt;For a demonstration, click 1. As the URL suggests, it will analyze the HTTP headers of &lt;a href=&quot;https://www.reddit.com/&quot;&gt;Reddit.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I began this as a weekend project in the early days of COVID, seeing it as just another addition to my toolkit. At the time, I simply added it to my &lt;a href=&quot;https://dri.es/projects&quot;&gt;projects page&lt;/a&gt; but never announced or mentioned it on my blog.&lt;/p&gt;
&lt;p&gt;So why write about it now? Because I happened to check my log files and, lo and behold, the little scanner that could clocked in more than 5 million scans, averaging over 3,500 scans a day.&lt;/p&gt;
&lt;p&gt;So four years and five million scans later, I&#039;m finally announcing it to the world!&lt;/p&gt;
&lt;p&gt;If you haven&#039;t tried my HTTP header analyzer, &lt;a href=&quot;https://headers.dev/analyze&quot;&gt;check it out&lt;/a&gt;. It&#039;s free, easy to use, requires no sign-up, and is built to help improve your website&#039;s performance and security.&lt;/p&gt;
&lt;p&gt;The crawler works with all websites, but naturally, I added some special checks for &lt;a href=&quot;https://www.drupal.org&quot;&gt;Drupal&lt;/a&gt; sites.&lt;/p&gt;
&lt;p&gt;I don&#039;t have any major plans for the crawler. At some point, I&#039;d like to move it to its own domain, as it feels a bit out of place as part of my personal website. But for now, that isn&#039;t a priority.&lt;/p&gt;
&lt;p&gt;For the time being, I&#039;m open to any feedback or suggestions and will commit to making any necessary corrections or improvements.&lt;/p&gt;
&lt;p&gt;It&#039;s rewarding to know that this tool has made thousands of websites faster and safer! It&#039;s also a great reminder to share your work, even in the simplest way – you never know the impact it could have.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>The Watchmaker&#039;s Approach to Web Development</title>
      <link>https://dri.es/the-watchmaker-approach-to-web-development</link>
      <guid>https://dri.es/the-watchmaker-approach-to-web-development</guid>
      <pubDate>Wed, 03 Jan 2024 04:03:55 -0500</pubDate>
      <description>&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://dri.es/files/cache/blog/watchmaker-web-development-1280w.jpg&quot; alt=&quot;A skilled craftsperson works on the intricate mechanism of a droplet-shaped vintage watch.&quot; width=&quot;1280&quot; height=&quot;854&quot; /&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Since 1999, I&#039;ve been consistently working on this website, making it one of my longest-standing projects. Even after all these years, the satisfaction of working on my website remains strong. Remarkable, indeed.&lt;/p&gt;
&lt;p&gt;During rare moments of calm – be it a slow holiday afternoon, a long flight home, or the early morning stillness – I&#039;m often drawn to &lt;a href=&quot;https://dri.es/tag/my-site&quot;&gt;tinkering with my website&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When working on my website, I often make small tweaks and improvements. Much like a watchmaker meticulously fine-tuning the gears of an antique clock, I pay close attention to details.&lt;/p&gt;
&lt;p&gt;This holiday, I improved the &lt;a href=&quot;https://web.dev/articles/browser-level-image-lazy-loading&quot;&gt;lazy loading of images&lt;/a&gt; in &lt;a href=&quot;https://dri.es/blog&quot;&gt;my blog posts&lt;/a&gt;, leading to a perfect &lt;a href=&quot;https://pagespeed.web.dev/&quot;&gt;Lighthouse score&lt;/a&gt;. A perfect score isn&#039;t necessary, but it shows the effort and care I put into my website.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://dri.es/files/cache/blog/perfect-lighthouse-score-2024-1280w.png&quot; alt=&quot;A screenshot of dri.es&amp;amp;#039; Lighthouse scores showing 100% scores in performance, accessibility, best practices, and SEO.&quot; width=&quot;1280&quot; height=&quot;754&quot; /&gt;
&lt;figcaption&gt;&lt;em&gt;Screenshot of Lighthouse scores via &lt;a href=&quot;https://pagespeed.web.dev/&quot;&gt;https://pagespeed.web.dev/&lt;/a&gt;.&lt;/em&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;I also &lt;a href=&quot;https://validator.w3.org/feed/&quot;&gt;validated my RSS feeds&lt;/a&gt;, uncovering a few opportunities for improvement. Like a good Belgian school boy, I promptly implemented these improvements, added new &lt;a href=&quot;https://dri.es/phpunit-tests-for-drupal&quot;&gt;PHPUnit tests&lt;/a&gt; &lt;em&gt;and&lt;/em&gt; integrated these into &lt;a href=&quot;https://dri.es/my-drupal-deployment-workflow&quot;&gt;my CI/CD pipeline&lt;/a&gt;. Some might consider this overkill for a personal site, but for me, it&#039;s about mastering the craft, adhering to high standards, and building something that is durable.&lt;/p&gt;
&lt;p&gt;Last year, I added 135 &lt;a href=&quot;https://dri.es/photos&quot;&gt;new photos&lt;/a&gt; to my website, a way for me to document my adventures and family moments. As the year drew to a close, I made sure all new photos have descriptive alt-texts, ensuring they&#039;re accessible to all. Writing alt-texts can be tedious, yet it&#039;s these small but important details that give me satisfaction.&lt;/p&gt;
&lt;p&gt;Just like the watchmaker working on an antique watch, it&#039;s not just about keeping time better; it&#039;s about cherishing the process and craft. There is something uniquely calming about slowly iterating on the details of a website. I call it the &lt;em&gt;The Watchmaker&#039;s Approach to Web Development&lt;/em&gt;, where the process holds as much value as the result.&lt;/p&gt;
&lt;p&gt;I&#039;m thankful for my website as it provides me a space where I can create, share, and unwind. Why share all this? Perhaps to encourage more people to dive into the world of website creation and maintenance.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Why content management systems can outperform static site generators</title>
      <link>https://dri.es/why-content-management-systems-can-outperform-static-site-generators</link>
      <guid>https://dri.es/why-content-management-systems-can-outperform-static-site-generators</guid>
      <pubDate>Mon, 20 Mar 2023 14:24:38 -0400</pubDate>
      <description>&lt;p&gt;One or two times a month I get the following question: &lt;q&gt;Why don&#039;t you just use a Static Site Generator (SSG) for your blog?&lt;/q&gt;&lt;/p&gt;
&lt;p&gt;Well, I&#039;m not gonna lie, being the founder and project lead of Drupal definitely plays a role in why I use Drupal for my website. Me not using Drupal would be like Coca-Cola&#039;s CEO drinking Pepsi, a baker settling for supermarket bread, or a cabinet builder furnishing their home entirely with IKEA. People would be confused.&lt;/p&gt;
&lt;p&gt;Of course, if I wanted to use a static site, I could. Drupal is frequently used as the content repository for &lt;a href=&quot;https://www.drupal.org/project/gatsby&quot;&gt;Gatsby.js&lt;/a&gt;, &lt;a href=&quot;https://next-drupal.org/&quot;&gt;Next.js&lt;/a&gt;, and many other frameworks.&lt;/p&gt;
&lt;p&gt;The main reason I don&#039;t use a SSG is that I don&#039;t love their publishing workflow. It&#039;s slow. With Drupal, I can make edits, hit save, and immediately see the result. With a static site generator it becomes more complex. I have to commit Markdown to Git, rebuild my site, and push updates to a web server. I simply prefer the user-friendly authoring of Drupal.&lt;/p&gt;
&lt;div class=&quot;large&quot;&gt;
  &lt;figure&gt;&lt;img src=&quot;https://dri.es/files/images/blog/static-site-generators-are-fast-marketing.png&quot; alt=&quot;A collage of screenshots displaying the websites of various static site generators, with prominent text emphasizing phrases such as &amp;amp;#039;fast page loads&amp;amp;#039;, &amp;amp;#039;peak performance&amp;amp;#039;, unparalleled speed&amp;amp;#039;, &amp;amp;#039;full speed&amp;amp;#039;, and more.&quot; width=&quot;1920&quot; height=&quot;1080&quot; /&gt;
&lt;figcaption&gt;&lt;em&gt;A collage of screenshots featuring different static site generators&#039; websites, emphasizing their marketing messaging on performance.&lt;/em&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;/div&gt;
&lt;p&gt;Proponents of static sites will be quick to point out that static sites are &amp;quot;much faster&amp;quot;. Personally, I find that misleading. My Drupal-powered site, &lt;a href=&quot;https://dri.es/&quot;&gt;https://dri.es/&lt;/a&gt;, is faster than most static sites, including the official websites of leading static site generators.&lt;/p&gt;
&lt;table&gt;
  &lt;tr&gt;
  &lt;th&gt;Technology&lt;/th&gt;
  &lt;th&gt;URL tested&lt;/th&gt;
  &lt;th&gt;Page load time&lt;/th&gt;
&lt;/tr&gt;
  &lt;tr&gt;
  &lt;td&gt;Drupal&lt;/td&gt;
  &lt;td&gt;
   &lt;a href=&quot;https://dri.es/&quot;&gt;https://dri.es/&lt;/a&gt;
 &lt;/td&gt;
  &lt;td&gt;0.3 seconds&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
  &lt;td&gt;Gatsby.js&lt;/td&gt;
  &lt;td&gt;
   &lt;a href=&quot;https://www.gatsbyjs.com/&quot;&gt;https://www.gatsbyjs.com/&lt;/a&gt;
 &lt;/td&gt;
  &lt;td&gt;2.8 seconds&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
  &lt;td&gt;Next.js&lt;/td&gt;
  &lt;td&gt;
   &lt;a href=&quot;https://nextjs.org/&quot;&gt;https://nextjs.org/&lt;/a&gt;
 &lt;/td&gt;
  &lt;td&gt;1.8 seconds&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
  &lt;td&gt;Jekyll&lt;/td&gt;
  &lt;td&gt;
   &lt;a href=&quot;https://jekyllrb.com/&quot;&gt;https://jekyllrb.com/&lt;/a&gt;
 &lt;/td&gt;
  &lt;td&gt;0.8 seconds&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
  &lt;td&gt;Elevently&lt;/td&gt;
  &lt;td&gt;
   &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;https://www.11ty.dev/&lt;/a&gt;
 &lt;/td&gt;
  &lt;td&gt;0.5 seconds&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
  &lt;td&gt;Docusaurus&lt;/td&gt;
  &lt;td&gt;
   &lt;a href=&quot;https://docusaurus.io/&quot;&gt;https://docusaurus.io/&lt;/a&gt;
 &lt;/td&gt;
  &lt;td&gt;1.8 seconds&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
  &lt;td&gt;Svelte Kit&lt;/td&gt;
  &lt;td&gt;
   &lt;a href=&quot;https://kit.svelte.dev/&quot;&gt;https://kit.svelte.dev/&lt;/a&gt;
 &lt;/td&gt;
  &lt;td&gt;1.1 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;In practice, most sites serve their content from a cache. As a result, we&#039;re mainly measuring (1) the caching mechanism, (2) last mile network performance and (3) client-side rendering. Of these three, client-side rendering impacts performance the most.&lt;/p&gt;
&lt;p&gt;My site is the fastest because its HTML/CSS/JavaScript is the simplest and fastest to render. I don&#039;t use external web fonts, track visitors, or use a lot of JavaScript. Drupal also optimizes performance with lazy loading of images, CSS/JavaScript aggregation, and more.&lt;/p&gt;
&lt;p&gt;In other words, the performance of a website depends more on the HTML, CSS, JavaScript code and assets (images, video, fonts) than the underlying technology used.&lt;/p&gt;
&lt;p&gt;The way an asset is cached can also affect its performance. Using a reverse proxy cache, such as Varnish, is faster than caching through the filesystem. And using a global CDN yields even faster results. A CMS that uses a CDN for caching can provide better performance than a SSG that only stores assets on a filesystem.&lt;/p&gt;
&lt;p&gt;To be clear, I&#039;m not against SSGs. I can understand the use cases for them, and there are plenty of situations where they are a great choice.&lt;/p&gt;
&lt;p&gt;In general, I believe that any asset that can be a static asset, should be a static asset. But I also believe that any dynamically generated asset that is cached effectively has become a static asset. A page that is created dynamically by a CMS and is cached efficiently is a static asset. Both a CMS and a SSG can generate static assets.&lt;/p&gt;
&lt;p&gt;In short, I simply prefer the authoring experience of a CMS, and I keep my site fast by keeping the generated HTML code lightweight and well-cached.&lt;/p&gt;
&lt;p&gt;What really tips the scale for me is that I enjoy having a server-side requests handler. Now, I know that this might sound like the nerdiest closing statement ever, but trust me: server-side request handlers bring the fun. Over the years they have enabled me to do &lt;a href=&quot;https://dri.es/posting-my-phone-battery-status-to-my-site&quot;&gt;fun and interesting things on my websites&lt;/a&gt;. I&#039;m not stopping the fun anytime soon!&lt;/p&gt;
</description>
    </item>
    <item>
      <title>How to remove YouTube tracking</title>
      <link>https://dri.es/how-to-remove-youtube-tracking</link>
      <guid>https://dri.es/how-to-remove-youtube-tracking</guid>
      <pubDate>Tue, 26 Mar 2019 15:14:45 -0400</pubDate>
      <description>&lt;p&gt;I don&#039;t use Google Analytics or any other web analytics service on &lt;a href=&quot;https://dri.es&quot;&gt;dri.es&lt;/a&gt;. Why not? Because I don&#039;t desire to know how many people visit my site, where they come from, or what operating system they use.&lt;/p&gt;
&lt;p&gt;Because I don&#039;t have a compelling reason to track my site&#039;s visitors, I don&#039;t have to bother anyone with a &amp;quot;cookies consent&amp;quot; popup either. That is a nice bonus because the web is littered with those already. I like that &lt;a href=&quot;https://dri.es&quot;&gt;dri.es&lt;/a&gt; is clutter-free.&lt;/p&gt;
&lt;p&gt;This was all well and good until a couple of weeks ago, when I learned that when I embed a YouTube video in my blog posts, Google sends an &lt;a href=&quot;https://en.wikipedia.org/wiki/HTTP_cookie&quot;&gt;HTTP cookie&lt;/a&gt; to track my site&#039;s visitors. Be damned!&lt;/p&gt;
&lt;p&gt;After some research, I discovered that YouTube offers a &lt;em&gt;privacy-enhanced way of embedding videos&lt;/em&gt;. Instead of linking to &lt;code&gt;youtube.com&lt;/code&gt;, link to &lt;code&gt;youtube-nocookie.com&lt;/code&gt;, and no data-collecting HTTP cookie will be sent. This is Google&#039;s way of providing GDPR-compliant YouTube videos.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;iframe width=&amp;quot;640&amp;quot; height=&amp;quot;360&amp;quot; src=&amp;quot;https://www.youtube-nocookie.com/embed/video-id&amp;quot; frameborder=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;/iframe&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So I went ahead and updated all blog posts on &lt;a href=&quot;https://dri.es&quot;&gt;dri.es&lt;/a&gt; to use &lt;code&gt;youtube-nocookie.com&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In addition to improving privacy, this change also makes my site faster. I used &lt;a href=&quot;https://webpagetest.org&quot;&gt;https://webpagetest.org&lt;/a&gt; to benchmark &lt;a href=&quot;https://dri.es/jsonapi-lands-in-drupal-core&quot;&gt;a recent blog post with a YouTube video&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Before:&lt;/p&gt;
&lt;div class=&quot;large&quot;&gt;
  &lt;figure&gt;&lt;img src=&quot;https://dri.es/files/images/blog/webpagetest-youtube-embed-2019-before.png&quot; alt=&quot;A waterfall diagram that shows requests and load times before replacing youtube.com with youtube-nocookie.com&quot; width=&quot;1025&quot; height=&quot;471&quot; /&gt;
&lt;figcaption&gt;&lt;em&gt;When embedding a video using &lt;code&gt;youtube.com&lt;/code&gt;, Google uses DoubleClick to track your users (yellow bar).  A total of 22 files were loaded, and the total time to load the page was 4.4 seconds (vertical blue line).  YouTube makes your pages slow, as the vast majority of requests and load time is spent on loading the YouTube video.&lt;/em&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;/div&gt;
&lt;p&gt;After:&lt;/p&gt;
&lt;div class=&quot;large&quot;&gt;
  &lt;figure&gt;&lt;img src=&quot;https://dri.es/files/images/blog/webpagetest-youtube-embed-2019-after.png&quot; alt=&quot;A waterfall diagram that shows requests and load times after replacing youtube.com with youtube-nocookie.com&quot; width=&quot;1024&quot; height=&quot;403&quot; /&gt;
&lt;figcaption&gt;&lt;em&gt;When using &lt;code&gt;youtube-nocookie.com&lt;/code&gt;, Google no longer uses DoubleClick to track your users.  No HTTP cookie was sent, &quot;only&quot; 18 files were loaded, and the total page load time was significantly faster at 2.9 seconds (vertical blue line).  Most of the load time is still the result of embedding a single YouTube video.&lt;/em&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;/div&gt;
</description>
    </item>
    <item>
      <title>Optimizing site performance by &quot;lazy loading&quot; images</title>
      <link>https://dri.es/optimizing-site-performance-by-lazy-loading-images</link>
      <guid>https://dri.es/optimizing-site-performance-by-lazy-loading-images</guid>
      <pubDate>Thu, 21 Feb 2019 03:48:30 -0500</pubDate>
      <description>&lt;p&gt;Recently, I&#039;ve been spending some time making performance improvements to my site. In my previous blog post on this topic, I described my progress &lt;a href=&quot;https://dri.es/optimizing-site-performance-by-reducing-javascript-and-css&quot;&gt;optimizing the JavaScript and CSS usage on my site&lt;/a&gt;, and concluded that image optimization was the next step.&lt;/p&gt;
&lt;p&gt;Last summer I published &lt;a href=&quot;https://dri.es/our-vacation-at-acadia-national-park&quot;&gt;a blog post about my vacation in Acadia National Park&lt;/a&gt;. Included in that post are 13 photos with a combined size of about 4 MB.&lt;/p&gt;
&lt;p&gt;When I benchmarked that post with &lt;a href=&quot;https://webpagetest.org&quot;&gt;WebPageTest&lt;/a&gt;, it showed that it took 7.275 seconds (blue vertical line) to render the page.&lt;/p&gt;
&lt;p&gt;The graph shows that the browser downloaded all 13 images to render the page. Why would a browser download all images if most of them are below the fold and not shown until a user starts scrolling? It makes very little sense.&lt;/p&gt;
&lt;p&gt;As you can see from the graph, downloading all 13 images take a very long time (purple horizontal bars). No matter how much you &lt;a href=&quot;https://dri.es/optimizing-site-performance-by-reducing-javascript-and-css&quot;&gt;optimize your CSS and JavaScript&lt;/a&gt;, this particular blog post would have remained slow until you optimize how images are loaded.&lt;/p&gt;
&lt;div class=&quot;large&quot;&gt;
  &lt;figure&gt;&lt;img src=&quot;https://dri.es/files/images/blog/webpagetest-images-february-2019-before.png&quot; alt=&quot;A webpage performance test waterfall chart showing loading times for various images, scripts, and resources before full interactivity.&quot; width=&quot;1024&quot; height=&quot;403&quot; /&gt;
&lt;/figure&gt;

&lt;/div&gt;
&lt;p&gt;&amp;quot;Lazy loading&amp;quot; images is one solution to this problem. Lazy loading means that the images aren&#039;t loaded until the user scrolls and the images come into the browser&#039;s viewport.&lt;/p&gt;
&lt;p&gt;You might have seen lazy loading in action on websites like Facebook, Pinterest or Medium. It usually goes like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You visit a page as you normally would, scrolling through the content.&lt;/li&gt;
&lt;li&gt;Instead of the actual image, you see a blurry placeholder image.&lt;/li&gt;
&lt;li&gt;Then, the placeholder image gets swapped out with the final image as quickly as possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://dri.es/files/images/blog/lazy-loading-images-animation.gif&quot; alt=&quot;An animated GIF of a user scrolling a webpage and a placeholder images being replaced by the final image&quot; width=&quot;1000&quot; height=&quot;542&quot; /&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;To support lazy loading images on my blog I do three things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Automatically generate lightweight yet useful placeholder images.&lt;/li&gt;
&lt;li&gt;Embed the placeholder images directly in the HTML to speed up performance.&lt;/li&gt;
&lt;li&gt;Replace the placeholder images with the real images when they become visible.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Generating lightweight placeholder images&lt;/h3&gt;
&lt;p&gt;To generate lightweight placeholder images, I implemented &lt;a href=&quot;https://code.fb.com/android/the-technology-behind-preview-photos/&quot;&gt;a technique used by Facebook&lt;/a&gt;: create a tiny image that is a downscaled version of the original image, strip out the image&#039;s metadata to optimize its size, and let the browser scale the image back up.&lt;/p&gt;
&lt;p&gt;To create lightweight placeholder images, I resized the original images to be 5 pixels wide. Because I have &lt;a href=&quot;https://dri.es/responsive-images-for-dri-es&quot;&gt;about 10,000 images on my blog&lt;/a&gt;, my &lt;a href=&quot;https://www.drupal.org&quot;&gt;Drupal&lt;/a&gt;-based site automates this for me, but here is how you create one from the command line using &lt;a href=&quot;https://www.imagemagick.org/&quot;&gt;ImageMagick&lt;/a&gt;&#039;s &lt;code&gt;convert&lt;/code&gt; tool:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;$ convert -resize 5x -strip original.jpg placeholder.jpg
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-resize 5x&lt;/code&gt; resizes the image to be 5 pixels wide while maintaining its aspect ratio.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-strip&lt;/code&gt; removes all comments and redundant headers in the image. This helps make the image&#039;s file size as small as possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The resulting placeholder images are tiny – often shy of 400 bytes.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://dri.es/files/cache/blog/lazy-loading-images-original-1-1280w.jpg&quot; alt=&quot;Large metal pots with wooden lids in which lobsters are boiled&quot; width=&quot;1280&quot; height=&quot;852&quot; /&gt;
&lt;figcaption&gt;&lt;em&gt;The original image that we need to generate a placeholder for.&lt;/em&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;&lt;img src=&quot;https://dri.es/files/images/blog/lazy-loading-images-placeholder-1.jpg&quot; alt=&quot;An example placeholder image shows brown and black tones&quot; width=&quot;638&quot; height=&quot;382&quot; /&gt;
&lt;figcaption&gt;&lt;em&gt;The generated placeholder, scaled up by a browser from a tiny image that is 5 pixels wide. The size of this placeholder image is only 395 bytes.&lt;/em&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Here is another example to illustrate how the colors in the placeholders nicely match the original image:&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://dri.es/files/cache/blog/lazy-loading-images-original-2-1280w.jpg&quot; alt=&quot;A sunrise with beautiful reds and black silhouettes&quot; width=&quot;1280&quot; height=&quot;852&quot; /&gt;
&lt;/figure&gt;

&lt;figure&gt;&lt;img src=&quot;https://dri.es/files/images/blog/lazy-loading-images-placeholder-2.jpg&quot; alt=&quot;An example placeholder image that shows red and black tones&quot; width=&quot;637&quot; height=&quot;382&quot; /&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Even though the placeholder image should only be shown for a fraction of a second, making them relevant is a nice touch as they suggest what is coming. It&#039;s also an &lt;em&gt;important&lt;/em&gt; touch, as &lt;a href=&quot;https://dri.es/faster-is-better&quot;&gt;users are very impatient with load times on the web&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Embedding placeholder images directly in HTML&lt;/h3&gt;
&lt;p&gt;One not-so-well-known feature of the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; element is that you can embed an image directly into the HTML document using &lt;a href=&quot;https://tools.ietf.org/html/rfc2397&quot;&gt;the data URL scheme&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;img src=&amp;quot;data:image/jpg;base64,/9j/4AAQSkZJRgABAQEA8ADwAAD/2wB
  DAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAQECAQEB
  AgICAgICAgICAQICAgICAgICAgL/2wBDAQEBAQEBAQEBAQECAQEBAgICAgICA
  gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgL/wA
  ARCAADAAUDAREAAhEBAxEB/8QAFAABAAAAAAAAAAAAAAAAAAAACf/EAB8QAAM
  AAQMFAAAAAAAAAAAAAAECAwcEBQYACAkTMf/EABUBAQEAAAAAAAAAAAAAAAAA
  AAIG/8QAJBEAAQIFAgcAAAAAAAAAAAAAAQURAAIDBDEGFBIVQUVRcYH/2gAMA
  wEAAhEDEQA/AAeyb5HO8o8lSLZd01Jz2nbKoK4yxDVvZqYl7uaV4CWdmZQSSS
  ST86FJBsafEJK15KD05ioNk4G6Yeg0V9bVCmZpXt08sB2hJ8DJ2Tn7H/2Q==&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Data URLs are composed of four parts: the &lt;code&gt;data:&lt;/code&gt; prefix, a &lt;a href=&quot;https://en.wikipedia.org/wiki/Media_type&quot;&gt;media type&lt;/a&gt; indicating the type of data (&lt;code&gt;image/jpg&lt;/code&gt;), an optional &lt;code&gt;base64&lt;/code&gt; token to indicate that the data is base64 encoded, and the base64 encoded image data itself.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;data:[&amp;lt;media type&amp;gt;][;base64],&amp;lt;data&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To base64 encode an image from the command line, use:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;$ base64 placeholder.jpg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To base64 encode an image in PHP, use:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$data =  base64_encode(file_get_contents(&#039;placeholder.jpg&#039;));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What is the advantage of embedding a base64 encoded image using a data URL? It eliminates HTTP requests as the browser doesn&#039;t have to set up new HTTP connections to download the images. Fewer HTTP requests usually means faster page load times.&lt;/p&gt;
&lt;h3&gt;Replacing placeholder images with real images&lt;/h3&gt;
&lt;p&gt;Next, I used JavaScript&#039;s &lt;code&gt;IntersectionObserver&lt;/code&gt; to replace the placeholder image with the actual image when it comes into the browser&#039;s viewport. I followed &lt;a href=&quot;https://jeremy.codes/&quot;&gt;Jeremy Wagner&lt;/a&gt;&#039;s approach shared on &lt;a href=&quot;https://developers.google.com/web/fundamentals/performance/lazy-loading-guidance/images-and-video/&quot;&gt;Google Web Fundamentals Guide on lazy loading images&lt;/a&gt; – with some adjustments.&lt;/p&gt;
&lt;p&gt;It starts with the following HTML markup:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;img class=&amp;quot;lazy&amp;quot; src=&amp;quot;placeholder.jpg&amp;quot; data-src=&amp;quot;original.jpg&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The three relevant pieces are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;class=&amp;quot;lazy&amp;quot;&lt;/code&gt; attribute, which is what you&#039;ll select the element with in JavaScript.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;src&lt;/code&gt; attribute, which references the placeholder image that will appear when the page first loads. Instead of linking to &lt;code&gt;placeholder.jpg&lt;/code&gt; I embed the image data using the data URL technique explained above.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;data-src&lt;/code&gt; attribute, which contains the URL to the original image that will replace the placeholder when it comes in focus.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next, we use JavaScript&#039;s &lt;code&gt;IntersectionObserver&lt;/code&gt; to replace the placeholder images with the actual images:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;document.addEventListener(&#039;DOMContentLoaded&#039;, function() {
  var lazyImages = [].slice.call(document.querySelectorAll(&#039;img.lazy&#039;));

  if (&#039;IntersectionObserver&#039; in window) {
    let lazyImageObserver = new IntersectionObserver(
      function(entries, observer) {
        entries.forEach(function(entry) {
          if (entry.isIntersecting) {
            let lazyImage = entry.target;
            lazyImage.src = lazyImage.dataset.src;
            lazyImageObserver.unobserve(lazyImage);
          }
        });
    });

    lazyImages.forEach(function(lazyImage) {
      lazyImageObserver.observe(lazyImage);
    });
  }
  else {
    // For browsers that don&#039;t support IntersectionObserver yet,
    // load all the images now:
    lazyImages.forEach(function(lazyImage) {
      lazyImage.src = lazyImage.dataset.src;
    });
  }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This JavaScript code queries the DOM for all &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; elements with the &lt;code&gt;lazy&lt;/code&gt; class. The &lt;code&gt;IntersectionObserver&lt;/code&gt; is used to replace the placeholder image with the original image when the &lt;code&gt;img.lazy&lt;/code&gt; elements enter the viewport. When &lt;code&gt;IntersectionObserver&lt;/code&gt; is not supported, the images are replaced on the &lt;code&gt;DOMContentLoaded&lt;/code&gt; event.&lt;/p&gt;
&lt;p&gt;By default, the &lt;code&gt;IntersectionObserver&lt;/code&gt;&#039;s callback is triggered the moment a single pixel of the image enters the browser&#039;s viewport. However, using the &lt;code&gt;rootMargin&lt;/code&gt; property, you can trigger the image swap before the image enters the viewport. This reduces or eliminates the &lt;em&gt;visual&lt;/em&gt; or &lt;em&gt;perceived lag time&lt;/em&gt; when swapping a placeholder image for the actual image.&lt;/p&gt;
&lt;p&gt;I implemented that on my site as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const config = {
    // If the image gets within 250px of the browser&#039;s viewport, 
    // start the download:
    rootMargin: &#039;250px 0px&#039;,
  };

let lazyImageObserver = new IntersectionObserver(..., config);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Lazy loading images drastically improves performance&lt;/h3&gt;
&lt;p&gt;After making these changes to my site, I did a new &lt;a href=&quot;https://webpagetest.org&quot;&gt;https://webpagetest.org&lt;/a&gt; benchmark run:&lt;/p&gt;
&lt;div class=&quot;large&quot;&gt;
  &lt;figure&gt;&lt;img src=&quot;https://dri.es/files/images/blog/webpagetest-images-february-2019-after.png&quot; alt=&quot;A diagram that shows page load times for dri.es before making performance improvements&quot; width=&quot;1024&quot; height=&quot;216&quot; /&gt;
&lt;/figure&gt;

&lt;/div&gt;
&lt;p&gt;You can clearly see that the page became a lot faster to render:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The document is complete after 0.35 seconds (blue vertical line) instead of the original 7.275 seconds.&lt;/li&gt;
&lt;li&gt;No images are loaded before the document is complete, compared to 13 images being loaded before.&lt;/li&gt;
&lt;li&gt;After the document is complete, one image (purple horizontal bar) is downloaded. This is triggered by the JavaScript code as the result of one image being above the fold.&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=&quot;pullquote&quot;&gt;Lazy loading images improves web page performance by reducing the number of HTTP requests, and consequently reduces the amount of data that needs to be downloaded to render the initial page.&lt;/p&gt;
&lt;h3&gt;Is base64 encoding images bad for SEO?&lt;/h3&gt;
&lt;p&gt;Faster sites have a SEO advantage as &lt;a href=&quot;https://webmasters.googleblog.com/2018/01/using-page-speed-in-mobile-search.html&quot;&gt;page speed is a ranking factor for search engines&lt;/a&gt;. But, lazy loading might also be bad for SEO, as search engines have to be able to discover the original images.&lt;/p&gt;
&lt;p&gt;To find out, I headed to &lt;a href=&quot;https://search.google.com/search-console&quot;&gt;Google Search Console&lt;/a&gt;. Google Search Console has a &amp;quot;URL inspection&amp;quot; feature that allows you to look at a webpage through the eyes of Googlebot.&lt;/p&gt;
&lt;p&gt;I tested it out &lt;a href=&quot;https://dri.es/our-vacation-at-acadia-national-park&quot;&gt;with my Acadia National Park&lt;/a&gt; blog post. As you can see in the screenshot, the first photo in the blog post was not loaded. Googlebot doesn&#039;t seem to support data URLs for images.&lt;/p&gt;
&lt;div class=&quot;large&quot;&gt;
  &lt;figure&gt;&lt;img src=&quot;https://dri.es/files/images/blog/google-search-console-live-preview.jpg&quot; alt=&quot;A screenshot that shows Googlebot doesn&amp;amp;#039;t render placeholder images that are embedded using data URLs&quot; width=&quot;1024&quot; height=&quot;665&quot; /&gt;
&lt;/figure&gt;

&lt;/div&gt;
&lt;h3&gt;Is &lt;code&gt;IntersectionObserver&lt;/code&gt; bad for SEO?&lt;/h3&gt;
&lt;p&gt;The fact that Googlebot doesn&#039;t appear to support data URLs does not have to be a problem. The real question is whether Googlebot will scroll the page, execute the JavaScript, replace the placeholders with the actual images, and index those. If it does, it doesn&#039;t matter that Googlebot doesn&#039;t understand data URLs.&lt;/p&gt;
&lt;p&gt;To find out, I decided to conduct an experiment. For the experiment, I published a blog post about &lt;a href=&quot;https://dri.es/two-internet-entrepreneurs-walk-into-an-old-publishing-house&quot;&gt;Matt Mullenweg and me visiting a museum together&lt;/a&gt;. The images in that blog post are lazy loaded and can only be discovered by Google if its crawler executes the JavaScript and scrolls the page. If those images show up in Google&#039;s index, we know there is no SEO impact.&lt;/p&gt;
&lt;p&gt;I only posted that blog post yesterday. I&#039;m not sure how long it takes for Google to make new posts and images available in its index, but &lt;a href=&quot;https://www.google.com/search?q=matt+mullenweg+dries+buytaert+plantin+moretus&quot;&gt;I&#039;ll keep an eye out for it&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If the images don&#039;t show up in Google&#039;s index, lazy loading might impact your SEO. My solution would be to selectively disable lazy loading for the most important images only. (Note: even if Google finds the images, there is no guarantee that it will decide to index them – short blog posts and images are often excluded from Google&#039;s index.)&lt;/p&gt;
&lt;h3&gt;Conclusions&lt;/h3&gt;
&lt;p&gt;Lazy loading images improves web page performance by reducing the number of HTTP requests and data needed to render the initial page.&lt;/p&gt;
&lt;p&gt;Ideally, over time, browsers will support lazy loading images natively, and some of the SEO challenges will no longer be an issue. Until then, consider adding support for lazy loading yourself. For my own site, it took about 40 lines of JavaScript code and 20 lines of additional PHP/Drupal code.&lt;/p&gt;
&lt;p&gt;I hope that by sharing my experience, more people are &lt;a href=&quot;https://dri.es/taking-control-of-my-data-and-social-media&quot;&gt;encouraged to run their own sites&lt;/a&gt; and to optimize their sites&#039; performance.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Optimizing site performance by reducing JavaScript and CSS</title>
      <link>https://dri.es/optimizing-site-performance-by-reducing-javascript-and-css</link>
      <guid>https://dri.es/optimizing-site-performance-by-reducing-javascript-and-css</guid>
      <pubDate>Wed, 13 Feb 2019 21:04:05 -0500</pubDate>
      <description>&lt;p&gt;I&#039;ve been thinking about the performance of my site and how it affects the user experience. There are real, &lt;a href=&quot;https://timkadlec.com/remembers/2019-01-09-the-ethics-of-performance/&quot;&gt;ethical concerns&lt;/a&gt; to poor web performance. These include accessibility, inclusion, waste and environmental concerns.&lt;/p&gt;
&lt;p&gt;A faster site is more accessible, and therefore more inclusive for people visiting from a mobile device, or from &lt;a href=&quot;https://whatdoesmysitecost.com&quot;&gt;areas in the world with slow or expensive internet&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For those reasons, I decided to see if I could improve the performance of my site. I used the excellent &lt;a href=&quot;https://webpagetest.org&quot;&gt;https://webpagetest.org&lt;/a&gt; to benchmark a simple blog post &lt;a href=&quot;https://dri.es/relentlessly-eliminating-barriers-to-growth&quot;&gt;https://dri.es/relentlessly-eliminating-barriers-to-growth&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;large&quot;&gt;
  &lt;figure&gt;&lt;img src=&quot;https://dri.es/files/images/blog/webpagetest-no-images-february-2019-before.png&quot; alt=&quot;A waterfall diagram that shows requests and load times before making performance improvements&quot; width=&quot;1024&quot; height=&quot;165&quot; /&gt;
&lt;/figure&gt;

&lt;/div&gt;
&lt;p&gt;The image above shows that it took a browser 0.722 seconds to download and render the page (see blue vertical line):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first 210 milliseconds are used to set up the connection, which includes the DNS lookup, TCP handshake and the SSL negotiation.&lt;/li&gt;
&lt;li&gt;The next 260 milliseconds (from 0.21 seconds to 0.47 seconds) are spent downloading the rendered HTML file, two CSS files and one JavaScript file.&lt;/li&gt;
&lt;li&gt;After everything is downloaded, the final 330 milliseconds (from 0.475 seconds to 0.8 seconds) are used to layout the page and execute the JavaScript code.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By most standards, 0.722 seconds is pretty fast. In fact, according to &lt;a href=&quot;https://httparchive.org/&quot;&gt;HTTP Archive&lt;/a&gt;, it takes more than 2.4 seconds to download and render the average web page on a laptop or desktop computer.&lt;/p&gt;
&lt;p&gt;Regardless, I noticed that the length of the horizontal green bars and the horizontal yellow bar was relatively long compared to that of the blue bar. In other words, a lot of time is spent downloading JavaScript (yellow horizontal bar) and CSS (two green horizontal bars) instead of the HTML, including the actual content of the blog post (blue bar).&lt;/p&gt;
&lt;p&gt;To fix, I did two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Use vanilla JavaScript&lt;/strong&gt;. I replaced my jQuery-based JavaScript with vanilla JavaScript. Without impacting the functionality of my site, the amount of JavaScript went from almost 45 KB to 699 bytes, good for a savings of over 6,000 percent.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conditionally include CSS&lt;/strong&gt;. For example, I use &lt;a href=&quot;https://prismjs.com/&quot;&gt;Prism.js&lt;/a&gt; for &lt;a href=&quot;https://dri.es/how-to-use-drupal-8-off-canvas-dialog-in-your-modules&quot;&gt;syntax highlighting code snippets in blog posts&lt;/a&gt;. &lt;code&gt;prism.css&lt;/code&gt; was downloaded for every page request, even when there were no code snippets to highlight. Using Drupal&#039;s render system, it&#039;s easy to conditionally include CSS. By taking advantage of that, I was able to reduce the amount of CSS downloaded by 47 percent – from 4.7 KB to 2.5 KB.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;According to the January 1st, 2019 run of &lt;a href=&quot;https://httparchive.org/&quot;&gt;HTTP Archive&lt;/a&gt;, the median page requires 396 KB of JavaScript and 60 KB of CSS. I&#039;m proud that my site is well under these medians.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
  &lt;tr&gt;
  &lt;th&gt;File type&lt;/th&gt;
  &lt;th&gt;Dri.es before&lt;/th&gt;
  &lt;th&gt;Dri.es after&lt;/th&gt;
  &lt;th&gt;World-wide median&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
  &lt;tbody&gt;
  &lt;tr&gt;
  &lt;td&gt;JavaScript&lt;/td&gt;
  &lt;td&gt;45 KB&lt;/td&gt;
  &lt;td&gt;669 bytes&lt;/td&gt;
  &lt;td&gt;396 KB&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;
  &lt;td&gt;CSS&lt;/td&gt;
  &lt;td&gt;4.7 KB&lt;/td&gt;
  &lt;td&gt;2.5 KB&lt;/td&gt;
  &lt;td&gt;60 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Because the new JavaScript and CSS files are significantly smaller, it takes the browser less time to download, parse and render them. As a result, the same blog post is now available in 0.465 seconds instead of 0.722 seconds, or 35% faster.&lt;/p&gt;
&lt;p&gt;After a new &lt;a href=&quot;https://webpagetest.org&quot;&gt;https://webpagetest.org&lt;/a&gt; test run, you can clearly see that the bars for the CSS and JavaScript files became visually shorter:&lt;/p&gt;
&lt;div class=&quot;large&quot;&gt;
  &lt;figure&gt;&lt;img src=&quot;https://dri.es/files/images/blog/webpagetest-no-images-february-2019-after.png&quot; alt=&quot;A waterfall diagram that shows requests and load times after making performance improvements&quot; width=&quot;1024&quot; height=&quot;165&quot; /&gt;
&lt;/figure&gt;

&lt;/div&gt;
&lt;p&gt;To optimize the user experience of my site, I want it to be fast. I hope that others will see that bloated websites can come at a great cost, and will consider using tools like &lt;a href=&quot;https://webpagetest.org&quot;&gt;https://webpagetest.org&lt;/a&gt; to make their sites more performant.&lt;/p&gt;
&lt;p&gt;I&#039;ll keep working on making my website even faster. As a next step, I plan to make pages with images faster by using lazy image loading.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>How NBC Sports supports the biggest media events online</title>
      <link>https://dri.es/how-nbc-sports-supports-the-biggest-media-events-online</link>
      <guid>https://dri.es/how-nbc-sports-supports-the-biggest-media-events-online</guid>
      <pubDate>Fri, 30 Nov 2018 10:08:53 -0500</pubDate>
      <description>&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://dri.es/files/cache/acquia/acquia-engage-2018-interview-with-eric-black-1280w.jpg&quot; alt=&quot;&quot; width=&quot;1280&quot; height=&quot;819&quot; /&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Many of Acquia&#039;s customers have hundreds or even thousands of sites, which vary in terms of scale, functionality, longevity and complexity.&lt;/p&gt;
&lt;p&gt;One thing that is very unique about Acquia is that we can help organizations scale from small to extremely large, one to many, and &lt;a href=&quot;https://dri.es/drupal-is-api-first-not-api-only&quot;&gt;coupled to decoupled&lt;/a&gt;. This scalability and flexibility is quite unique, and allows organizations to &lt;a href=&quot;https://dri.es/how-acquia-is-addressing-the-explosion-of-sites&quot;&gt;standardize on a single web platform&lt;/a&gt;. Standardizing on a single web platform not only removes the complexity from having to manage dozens of different technology stacks and teams, but also enables organizations to innovate faster.&lt;/p&gt;
&lt;div class=&quot;large&quot;&gt;
  &lt;figure&gt;&lt;img src=&quot;https://dri.es/files/images/acquia/acquia-engage-2018-nbc-sports.jpg&quot; alt=&quot;NBC Sports achieved 93 million users, 721 million video minutes, and top sports ranking using Acquia&amp;amp;#039;s digital solutions.&quot; width=&quot;1258&quot; height=&quot;700&quot; /&gt;
&lt;/figure&gt;

&lt;/div&gt;
&lt;p&gt;A great example is NBC Sports Digital. Not only does NBC Sports Digital have to manage dozens of sites across 30,000 sporting events each year, but it also has some of the most trafficked sites in the world.&lt;/p&gt;
&lt;p&gt;In 2018, Acquia supported NBC Sports Digital as it provided fans with unparalleled coverage of Super Bowl LII, the Pyeongchang Winter Games and the 2018 World Cup. As quoted in &lt;a href=&quot;http://nbcsportsgrouppressbox.com/2018/03/15/best-feb-ever-nbc-sports-digital-sets-february-sports-record-with-93-million-unique-users/&quot;&gt;NBC Sport&#039;s press release&lt;/a&gt;, NBC Sports Digital streamed more than 4.37 billion live minutes of video, served 93 million unique users, and delivered 721 million minutes of desktop video streamed. These are some of the highest trafficked events in the history of the web, and I&#039;m very proud that they are powered by &lt;a href=&quot;https://www.drupal.org/&quot;&gt;Drupal&lt;/a&gt; and &lt;a href=&quot;https://www.acquia.com/&quot;&gt;Acquia&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To learn more about how Acquia helps NBC Sports Digital deliver more than 10,000 sporting events every year, watch my conversation with Eric Black, CTO of NBC Sports Digital, in the video below:&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;div style=&quot;position: relative; padding-bottom: 56.25%; height: 0&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/iBxTztNSiU8&quot; style=&quot;position: absolute; top: 0; left: 0; width: 100%; height: 100%&quot; loading=&quot;lazy&quot; title=&quot;YouTube video&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Not every organization gets to entertain 100 million viewers around the world, but every business has its own World Cup. Whether it&#039;s Black Friday, Mother&#039;s Day, a new product launch or breaking news, we offer our customers the tools and services necessary to optimize efficiency and provide flexibility at any scale.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Responsive images for dri.es</title>
      <link>https://dri.es/responsive-images-for-dri-es</link>
      <guid>https://dri.es/responsive-images-for-dri-es</guid>
      <pubDate>Sun, 14 Oct 2018 18:36:30 -0400</pubDate>
      <description>&lt;p&gt;For a few years now I&#039;ve been planning to add support for &lt;a href=&quot;https://internetingishard.com/html-and-css/responsive-images/&quot;&gt;responsive images&lt;/a&gt; to my site.&lt;/p&gt;
&lt;p&gt;The past two weeks, I&#039;ve had to take multiple trips to the West Coast of the United States; last week I traveled from Boston to San Diego and back, and this week I&#039;m flying from Boston to San Francisco and back. I used some of that airplane time to add responsive image support to my site, and just pushed it to production from 30,000 feet in the air!&lt;/p&gt;
&lt;p&gt;When a website supports &lt;a href=&quot;https://internetingishard.com/html-and-css/responsive-images/&quot;&gt;responsive images&lt;/a&gt;, it allows a browser to choose between different versions of an image. The browser will select the most optimal image by taking into account not only the device&#039;s dimensions (e.g. mobile vs desktop) but also the device&#039;s screen resolution (e.g. regular vs retina) and the browser viewport (e.g. full-screen browser or not). In theory, a browser could also factor in the internet connection speed but I don&#039;t think they do.&lt;/p&gt;
&lt;p&gt;First of all, with responsive image support, images should always look crisp (I no longer serve an image that is too small for certain devices). Second, my site should also be faster, especially for people using older smartphones on low-bandwidth connections (I no longer serve an image that is too big for an older smartphone).&lt;/p&gt;
&lt;p class=&quot;pullquote&quot;&gt;Serving the right image to the right device can make a big difference in the user experience.&lt;/p&gt;
&lt;p&gt;Many articles suggest supporting three image sizes, however, based on my own testing with &lt;a href=&quot;https://developers.google.com/web/tools/chrome-devtools/&quot;&gt;Chrome&#039;s Developer Tools&lt;/a&gt;, I didn&#039;t feel that three sizes was sufficient. There are so many different screen sizes and screen resolutions today that I decided to offer six versions of each image: 480, 640, 768, 960, 1280 and 1440 pixels wide. And I&#039;m on the fence about adding 1920 as a seventh size.&lt;/p&gt;
&lt;p&gt;Because &lt;a href=&quot;https://dri.es/to-pesos-or-to-posse&quot;&gt;I believe in being in control of my own data&lt;/a&gt;, I host almost 10,000 original images on my site. This means that in addition to the original images, I now also store 60,000 image variants. To further improve the site experience, I&#039;m contemplating adding &lt;a href=&quot;https://en.wikipedia.org/wiki/WebP&quot;&gt;WebP&lt;/a&gt; variants as well – that would bring the total number of stored images to 130,000.&lt;/p&gt;
&lt;p&gt;If you notice that my photos are clearer and/or page delivery a bit faster, this is why. Through small changes like these, my goal is to continue to improve the user experience on dri.es.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>A fresh look for dri.es</title>
      <link>https://dri.es/a-fresh-look-for-dri-es</link>
      <guid>https://dri.es/a-fresh-look-for-dri-es</guid>
      <pubDate>Sat, 13 Oct 2018 15:07:24 -0400</pubDate>
      <description>&lt;p&gt;In &lt;a href=&quot;https://www.youtube.com/watch?v=rblt2EtFfC4&quot;&gt;1999&lt;/a&gt;, I decided to start dri.es (formally buytaert.net) as a place to blog, write, and deepen my thinking. While I ran other websites before dri.es, my blog is one of my longest running projects.&lt;/p&gt;
&lt;p&gt;Working on my site helps me relax, so it&#039;s not unusual for me to spend a few hours now and then making tweaks. This could include updating &lt;a href=&quot;https://dri.es/photos&quot;&gt;my photo galleries&lt;/a&gt;, working on &lt;a href=&quot;https://dri.es/my-posse-plan-for-evolving-my-site&quot;&gt;more POSSE features&lt;/a&gt;, fixing broken links, or upgrading to the latest version of Drupal.&lt;/p&gt;
&lt;p&gt;The past month, a collection of smaller updates have resulted in a new visual design for my site. If you are reading this post through an RSS aggregator or through my mailing list, consider checking out the new design on &lt;a href=&quot;https://dri.es&quot;&gt;dri.es&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;large&quot;&gt;
  &lt;figure&gt;&lt;img src=&quot;https://dri.es/files/cache/blog/dries-redesign-2018-1280w.png&quot; alt=&quot;2018 dri.es redesign&quot; width=&quot;1280&quot; height=&quot;661&quot; /&gt;
&lt;figcaption&gt;&lt;em&gt;Before (left) and after (right).&lt;/em&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;/div&gt;
&lt;p&gt;The new dri.es may not win design awards, but will hopefully make it easier to consume the content. My design goals were the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Improve the readability of the content&lt;/li&gt;
&lt;li&gt;Improve the discoverability of the content&lt;/li&gt;
&lt;li&gt;Optimize the performance of my site&lt;/li&gt;
&lt;li&gt;Give me more creative freedom&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Improve readability of the content&lt;/h3&gt;
&lt;p&gt;To improve the readability of the content, I implemented various &lt;a href=&quot;https://uxplanet.org/common-webpage-design-mistakes-59eed9831bd7&quot;&gt;usability best practices for spacing text and images&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I also adjusted the width of the main content area. For optimal readability, &lt;a href=&quot;https://www.smashingmagazine.com/2014/09/balancing-line-length-font-size-responsive-web-design/&quot;&gt;you should have between 45 and 75 characters on each line&lt;/a&gt;. No more, no less. The old design had about 95 characters on each line, while the new design is closer to 70.&lt;/p&gt;
&lt;p&gt;Both the line width and the spacing changes should improve the readability.&lt;/p&gt;
&lt;h3&gt;Improve the discoverability of content&lt;/h3&gt;
&lt;p&gt;I also wanted to improve the discoverability of my content. I cover a wide range of topics on my blog: from &lt;a href=&quot;https://dri.es/tag/drupal&quot;&gt;Drupal&lt;/a&gt; and &lt;a href=&quot;https://dri.es/tag/open-source&quot;&gt;Open Source&lt;/a&gt; to &lt;a href=&quot;https://dri.es/tag/startup-lessons&quot;&gt;startups&lt;/a&gt;, &lt;a href=&quot;https://dri.es/tag/investing&quot;&gt;investing&lt;/a&gt;, &lt;a href=&quot;https://dri.es/tag/travel&quot;&gt;travel&lt;/a&gt;, &lt;a href=&quot;https://dri.es/tag/photography&quot;&gt;photography&lt;/a&gt;, and the &lt;a href=&quot;https://dri.es/tag/open-web&quot;&gt;Open Web&lt;/a&gt;.  To help visitors understand what my site is about, I created a new navigation. The new &lt;a href=&quot;https://dri.es/topics&quot;&gt;Topics&lt;/a&gt;-page shows visitors a list of the main topics I write about. It&#039;s a small change, but it should help new visitors figure out what my site is about.&lt;/p&gt;
&lt;h3&gt;Optimize the performance of my site&lt;/h3&gt;
&lt;p&gt;Less noticeable is that the underlying HTML and CSS code is now entirely different. I&#039;m still using &lt;a href=&quot;https://www.drupal.org&quot;&gt;Drupal&lt;/a&gt;, of course, but I decided to rewrite my Drupal theme from scratch.&lt;/p&gt;
&lt;p&gt;The new design&#039;s CSS code is more than three times smaller: the previous design had almost 52K of theme-specific CSS while the new design has only 16K of theme-specific CSS.&lt;/p&gt;
&lt;p&gt;The new design also results in fewer HTTP requests as I replaced all stand-alone icons with &lt;a href=&quot;https://alistapart.com/article/practical-svg&quot;&gt;inline SVGs&lt;/a&gt;. Serving the page you are reading right now only takes 16 HTTP requests compared to 33 HTTP requests with the previous design.&lt;/p&gt;
&lt;p&gt;All this results in faster site performance. This is especially important for people visiting my site from a mobile device, and even more important for people visiting my site from areas in the world with slow internet. A lighter theme with fewer HTTP requests makes my site more accessible. It is something I plan to work more on in the future.&lt;/p&gt;
&lt;p class=&quot;pullquote&quot;&gt;Website bloat is a growing problem and impacts the user experience. I wanted to lead by example, and made my site simpler and faster to load.&lt;/p&gt;
&lt;p&gt;The new design also uses Flexbox and CSS Grid Layout – both are more modern CSS standards. The new design is fully supported in all main browsers: Chrome, Firefox, Safari and Edge. It is, however, not fully supported on Internet Explorer, which accounts for 3% of all my visitors. Internet Explorer users should still be able to read all content though.&lt;/p&gt;
&lt;h3&gt;Give me more creative freedom&lt;/h3&gt;
&lt;p&gt;Last but not least, the new design provides me with a better foundation to build upon in subsequent updates. I wanted more flexibility for how to lay out images in my blog posts, highlight important snippets, and add a table of content on long posts. You can see all three in action in this post, assuming you&#039;re looking at this blog post on a larger screen.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>How Wikipedia implemented link previews</title>
      <link>https://dri.es/how-wikipedia-implemented-link-previews</link>
      <guid>https://dri.es/how-wikipedia-implemented-link-previews</guid>
      <pubDate>Thu, 03 May 2018 15:20:10 -0400</pubDate>
      <description>&lt;p&gt;You might have noticed that &lt;a href=&quot;https://medium.com/freely-sharing-the-sum-of-all-knowledge/wikipedia-page-previews-738cddac7a21&quot;&gt;Wikipedia recently started enabling link previews&lt;/a&gt;; when you hover over a link, it displays a card with more information about the linked page.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://dri.es/files/images/blog/wikipedia-link-previews.jpg&quot; alt=&quot;A Wikipedia page about Drupal with a link preview showing a blog-related entry overlapping the text.&quot; width=&quot;2046&quot; height=&quot;1250&quot; /&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;My first reaction was: what took them so long? Link previews help to solve an important usability problem of having to open many articles, often in multiple browser tabs. However, after I started to read more about how &lt;a href=&quot;https://www.wikipedia.org/&quot;&gt;Wikipedia&lt;/a&gt; implemented the link previews, I was reminded of how hard it is to do things at the scale Wikipedia requires.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.com/@nirzar&quot;&gt;Nirzar Pangarka&lt;/a&gt;, who works as a designer at the Wikimedia Foundation, shared that &lt;a href=&quot;https://medium.com/freely-sharing-the-sum-of-all-knowledge/how-we-designed-page-previews-for-wikipedia-and-what-could-be-done-with-them-in-the-future-7a5fa6b07b96&quot;&gt;more than 10,000 links get hovered each second across Wikipedia&lt;/a&gt;. In another post, &lt;a href=&quot;https://medium.com/@dlyall&quot;&gt;David Lyall&lt;/a&gt;, an engineering manager at the Wikimedia Foundation, shared that they are seeing &lt;a href=&quot;https://medium.com/freely-sharing-the-sum-of-all-knowledge/why-it-took-a-long-time-to-build-that-tiny-link-preview-on-wikipedia-d5bd734df8fe&quot;&gt;up to half a million hits every minute on the API that serves the link preview cards&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I have a great appreciation for Wikipedia&#039;s seemingly straightforward link previews. Delivering a feature at this scale is an impressive achievement.&lt;/p&gt;
</description>
    </item>
  </channel>
</rss>
