diff --git a/src/posts/2023/from-ics-to-json-surfacing-anticipated-albums.md b/src/posts/2023/from-ics-to-json-surfacing-anticipated-albums.md new file mode 100644 index 00000000..cc4724fc --- /dev/null +++ b/src/posts/2023/from-ics-to-json-surfacing-anticipated-albums.md @@ -0,0 +1,69 @@ +--- +date: '2023-06-08' +title: 'From ICS to JSON: surfacing anticipated albums' +draft: false +tags: ['development', 'music', 'automation'] +image: https://cdn.coryd.dev/blog/album-releases.jpg +--- + +I use MusicHarbor by [Marcos Tanaka](https://marcosatanaka.com) to track upcoming albums from my favorite artists (typically by syncing [my last.fm data](https://www.last.fm/user/cdme_) with the app.) When I see something new that I want to add to my collection I throw it on a calendar creatively titled `Albums`. + +My calendar sits over at Proton which lets you share calendars with other users or as a syncable/downloadable `ics` file. As another entry into a list of experiments done because they can be I decided to surface these album events on [my now page](https://coryd.dev/now)[^1]. + +To do this I installed `ics-to-json-extended` and created a data file: + +```javascript +const { AssetCache } = require('@11ty/eleventy-fetch') +const ics = require('ics-to-json-extended') +const { DateTime } = require('luxon') + +module.exports = async function () { +const URL = process.env.SECRET_FEED_ALBUM_RELEASES +const icsToJson = ics.default +const asset = new AssetCache('album_release_data') +if (asset.isCacheValid('1h')) return await asset.getCachedValue() +const icsRes = await fetch(URL) +const icsData = await icsRes.text() +const data = icsToJson(icsData) +return data.filter((d) => DateTime.fromISO(d.startDate) > DateTime.now()) +} +``` + +We surface the url, require the ICS conversion library, cache and convert the response using [Luxon](https://www.npmjs.com/package/luxon)'s `DateTime` interface to compare the current time and dates in the object returned from the calendar, which look like this: + +```json +{ + startDate: '20180505T020000Z', + endDate: '20180505T060000Z', + location: 'url', + summary: 'Artist - Album' +} +``` + +Rendering the output is as simple as: +{% raw %} + +```liquid +{% if albumReleases.size > 0 %} +

+ {% heroicon "solid" "calendar" "Albums I'm looking forward to" "height=28" %} +
Albums I'm looking forward to
+

+ +{% endif %} +``` + +{% endraw %} +Leaving us with: +{% image '', 'Albums I\'m looking forward to', 'w-full', '600px' %} + +[^1]: At this point, a dev playground. diff --git a/src/posts/2023/optimizing-for-performance-with-eleventy.md b/src/posts/2023/optimizing-for-performance-with-eleventy.md index 96ab5265..f7831eae 100644 --- a/src/posts/2023/optimizing-for-performance-with-eleventy.md +++ b/src/posts/2023/optimizing-for-performance-with-eleventy.md @@ -60,6 +60,7 @@ ELEVENTY_PRODUCTION=true eleventy && NODE_ENV=production npx tailwindcss -i ./ta The site include's Prism for code syntax highlighting and this is embedded and minified in the `` of each page at build time: {% raw %} + ```liquid {% capture css %} {% include "../assets/styles/prism.css" %} @@ -68,16 +69,20 @@ The site include's Prism for code syntax highlighting and this is embedded and m {{ css | cssmin }} ``` + {% endraw %} This is made possible by leveraging CleanCSS in (you guessed it) `.eleventy.js`: {% raw %} + ```javascript const CleanCSS = require('clean-css') ... // css filters eleventyConfig.addFilter('cssmin', (code) => new CleanCSS({}).minify(code).styles) ``` + {% endraw %} + ## Minify HTML output Final HTML output for the site is minified when it's built using `@sherby/eleventy-plugin-files-minifier` which, [per the docs](https://www.npmjs.com/package/@sherby/eleventy-plugin-files-minifier): @@ -99,6 +104,7 @@ module.exports = function (eleventyConfig) { Finally (and this is something that took me longer than it should have to do), we optimize images at build time using `@11ty/eleventy-image`, defining a shortcode in `.eleventy.js` as follows: {% raw %} + ```javascript // image shortcode eleventyConfig.addShortcode('image', async function (src, alt, css, sizes, loading) { @@ -120,17 +126,20 @@ eleventyConfig.addShortcode('image', async function (src, alt, css, sizes, loadi return Image.generateHTML(metadata, imageAttributes) }) ``` + {% endraw %} This is most impactful on [my now page](https://coryd.dev/now) which is populated with quite a few images and, when used, looks something like this: {% raw %} + ```liquid {% image artistImg, artistName, 'rounded-lg', '225px', 'eager' %} ``` + {% endraw %} -For this page in particular, the images that are rendered above the fold are set to load as `eager` to mitigate performance impacts related to [too much lazy loading](https://web.dev/lcp-lazy-loading/). These images are fetched from caches hosted at [Bunny.net](https://bunny.net/?ref=revw3mehej) when the site is built. +For this page in particular, the images that are rendered above the fold are set to load as `eager` to mitigate performance impacts related to [too much lazy loading](https://web.dev/lcp-lazy-loading/). These images are fetched from caches hosted at Bunny.net when the site is built. All of these boilerplate steps leave us with a quick to load, accessible and resilient site: -{% image 'https://cdn.coryd.dev/blog/page-speed.jpg', 'Pagespeed scores for coryd.dev/now', 'w-full', '600px' %} +{% image '', 'Pagespeed scores for coryd.dev/now', 'w-full', '600px' %} [^1]: It's easy, flexible and helps mitigate my lack of an eye for design by providing safe baselines.