Skip to content

Commit ec746d0

Browse files
authored
Merge pull request #136 from stedman/optimize
Optimize code to achieve 4 Hundos
2 parents 639d9b5 + 62293b1 commit ec746d0

26 files changed

+1329
-2189
lines changed

.eleventy.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
const fs = require('fs');
22
const pluginRss = require('@11ty/eleventy-plugin-rss');
3+
const htmlmin = require('html-minifier');
34
const sassWatch = require('./_includes/sass-watch');
45
const filter = require('./_includes/filter');
56
const scAvatar = require('./_includes/shortcodes/avatar');
7+
const scResponsiveImage = require('./_includes/shortcodes/responsive-image');
8+
const scSocialSvg = require('./_includes/shortcodes/social-svg');
69
const scMeetupDetails = require('./_includes/shortcodes/meetup-details');
710
const scVideoPlayer = require('./_includes/shortcodes/video-player');
811

@@ -68,9 +71,32 @@ module.exports = (eleventyConfig) => {
6871
// SHORTCODE: Resize and cache images.
6972
eleventyConfig.addLiquidShortcode('avatar', scAvatar);
7073

74+
// SHORTCODE: Generate responsive image.
75+
eleventyConfig.addLiquidShortcode('responsiveImage', scResponsiveImage);
76+
77+
// SHORTCODE: Add social icon SVG block.
78+
eleventyConfig.addLiquidShortcode('socialSvg', scSocialSvg);
79+
7180
// PLUGIN: RSS feed
7281
eleventyConfig.addPlugin(pluginRss);
7382

83+
// TRANSFORM: minify HTML
84+
eleventyConfig.addTransform('htmlmin', (content, outputPath) => {
85+
if (typeof outputPath === 'string' && outputPath.endsWith('.html')) {
86+
const minified = htmlmin.minify(content, {
87+
useShortDoctype: true,
88+
removeComments: true,
89+
collapseWhitespace: true,
90+
minifyCSS: true,
91+
minifyJS: true,
92+
});
93+
94+
return minified;
95+
}
96+
97+
return content;
98+
});
99+
74100
// BROWSERSYNC: add ability to see 404.html in dev mode
75101
eleventyConfig.setBrowserSyncConfig({
76102
callbacks: {

_includes/shortcodes/meetup-details.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,13 @@ const fullDate = (dateValue) => {
3333
module.exports = function meetupDetails(meetDate, venue, after, msgHeader, meetTitle, meetUrl) {
3434
const header = msgHeader || 'Meetup details';
3535

36-
const meetHeader = meetTitle && meetUrl
36+
const svgBlock = `<svg display="none">
37+
<g id="alarm"><path d='M153.59,110.46A21.41,21.41,0,0,0,152.48,79h0A62.67,62.67,0,0,0,112,64l-3.27.09-.48,0C74.4,66.15,48,95.55,48.07,131c0,19,8,29.06,14.32,37.11a20.61,20.61,0,0,0,14.7,7.8c.26,0,.7.05,2,.05a19.06,19.06,0,0,0,13.75-5.89Z'/><path d='M403.79,64.11l-3.27-.1H400a62.67,62.67,0,0,0-40.52,15,21.41,21.41,0,0,0-1.11,31.44l60.77,59.65A19.06,19.06,0,0,0,432.93,176c1.28,0,1.72,0,2-.05a20.61,20.61,0,0,0,14.69-7.8c6.36-8.05,14.28-18.08,14.32-37.11C464,95.55,437.6,66.15,403.79,64.11Z'/><path d='M256.07,96c-97,0-176,78.95-176,176a175.23,175.23,0,0,0,40.81,112.56L84.76,420.69a16,16,0,1,0,22.63,22.62l36.12-36.12a175.63,175.63,0,0,0,225.12,0l36.13,36.12a16,16,0,1,0,22.63-22.62l-36.13-36.13A175.17,175.17,0,0,0,432.07,272C432.07,175,353.12,96,256.07,96Zm16,176a16,16,0,0,1-16,16h-80a16,16,0,0,1,0-32h64V160a16,16,0,0,1,32,0Z'/></g>
38+
<g id="calendar"><path d='M416,64H400V48.45c0-8.61-6.62-16-15.23-16.43A16,16,0,0,0,368,48V64H144V48.45c0-8.61-6.62-16-15.23-16.43A16,16,0,0,0,112,48V64H96a64,64,0,0,0-64,64V416a64,64,0,0,0,64,64H416a64,64,0,0,0,64-64V128A64,64,0,0,0,416,64ZM136,416a24,24,0,1,1,24-24A24,24,0,0,1,136,416Zm0-80a24,24,0,1,1,24-24A24,24,0,0,1,136,336Zm80,80a24,24,0,1,1,24-24A24,24,0,0,1,216,416Zm0-80a24,24,0,1,1,24-24A24,24,0,0,1,216,336Zm80,80a24,24,0,1,1,24-24A24,24,0,0,1,296,416Zm0-80a24,24,0,1,1,24-24A24,24,0,0,1,296,336Zm0-80a24,24,0,1,1,24-24A24,24,0,0,1,296,256Zm80,80a24,24,0,1,1,24-24A24,24,0,0,1,376,336Zm0-80a24,24,0,1,1,24-24A24,24,0,0,1,376,256Zm72-120v16a8,8,0,0,1-8,8H72a8,8,0,0,1-8-8V128A32.09,32.09,0,0,1,96,96H416a32.09,32.09,0,0,1,32,32Z'/></g>
39+
<g id="location-sharp"><path d='M256,32C167.67,32,96,96.51,96,176c0,128,160,304,160,304S416,304,416,176C416,96.51,344.33,32,256,32Zm0,224a64,64,0,1,1,64-64A64.07,64.07,0,0,1,256,256Z'/></g>
40+
</svg>`;
41+
42+
const meetHeaderBlock = meetTitle && meetUrl
3743
? `<div class="title is-size-4">
3844
<a href="${meetUrl}">${meetTitle}</a>
3945
</div>`
@@ -62,25 +68,26 @@ module.exports = function meetupDetails(meetDate, venue, after, msgHeader, meetT
6268
}
6369

6470
return `<div class="message flex-item flex-item-0">
71+
${svgBlock}
6572
<div class="message-header">
6673
${header}
6774
</div>
6875
6976
<div class="message-body">
70-
${meetHeader}
77+
${meetHeaderBlock}
7178
7279
<div>
7380
DATE
7481
<span class="icon has-text-grey-dark">
75-
<ion-icon src="/assets/ionicon/calendar.svg"></ion-icon>
82+
<svg class="icon-item" viewBox="0 0 512 512"><use xlink:href="#calendar"></use></svg>
7683
</span>
7784
<time class="has-text-primary has-text-weight-bold" dateTime="${meetDate.toISOString().substring(0, 10)}">${fullDate(meetDate)}</time>
7885
</div>
7986
8087
<div>
8188
TIME
8289
<span class="icon has-text-grey-dark">
83-
<ion-icon src="/assets/ionicon/alarm.svg"></ion-icon>
90+
<svg class="icon-item" viewBox="0 0 512 512"><use xlink:href="#alarm"></use></svg>
8491
</span>
8592
<time class="has-text-primary has-text-weight-bold" dateTime="15:30">7:30PM</time> -
8693
<time class="has-text-primary has-text-weight-bold" dateTime="21:00">9:00PM</time>
@@ -89,7 +96,7 @@ module.exports = function meetupDetails(meetDate, venue, after, msgHeader, meetT
8996
<div>
9097
LOCATION
9198
<span class="icon has-text-grey-dark">
92-
<ion-icon src="/assets/ionicon/location-sharp.svg"></ion-icon>
99+
<svg class="icon-item" viewBox="0 0 512 512"><use xlink:href="#location-sharp"></use></svg>
93100
</span>
94101
<strong class="has-text-primary">${venueOrg.name}</strong>
95102
${venueLocation}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const Image = require('@11ty/eleventy-img');
2+
3+
module.exports = async (src, alt, outputFormat = 'jpeg') => {
4+
if (alt === undefined) {
5+
throw new Error(`Responsive Image: missing ALT attribute from: ${src}`);
6+
}
7+
8+
try {
9+
const stats = await Image(src, {
10+
formats: [outputFormat],
11+
urlPath: '/assets/img/',
12+
outputDir: '_site/assets/img/',
13+
widths: [400, 800, null],
14+
});
15+
16+
const lowestSrc = stats[outputFormat][0];
17+
const sizes = '(max-width: 400px) 400px, (max-width: 800px) 800px, 100vw';
18+
const sourceBlock = Object.values(stats).map((imageFormat) => `<source type="image/${imageFormat[0].format}" srcset="${imageFormat.map((entry) => `${entry.url} ${entry.width}w`).join(', ')}" sizes="${sizes}">`).join('\n');
19+
20+
return `<picture class="image">
21+
${sourceBlock}
22+
<img src="${lowestSrc.url}" width="${lowestSrc.width}" height="${lowestSrc.height}" alt="${alt}" loading="lazy">`;
23+
} catch (err) {
24+
// eslint-disable-next-line no-console
25+
console.error('Responsive Image: eleventy-img error:', err);
26+
27+
// load empty img src (as placeholder)
28+
return `<img src="" alt="${alt}" loading="lazy">`;
29+
}
30+
};

_includes/shortcodes/social-svg.js

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

_includes/social-links.liquid

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
1+
{%- socialSvg -%}
2+
13
{%- if person.email %}
2-
<a class="icon tooltip" href="mailto:{{ person.email }}" title="Email: {{ person.email }}">
3-
<ion-icon class="is-size-3" src="{{ '/assets/ionicon/at-circle.svg' | url }}"><i class="is-sr-only">email</i></ion-icon>
4+
<a class="icon tooltip" href="mailto:{{ person.email }}" aria-label="Email: {{ person.email }}">
5+
<svg class="icon-item" viewBox="0 0 512 512"><use xlink:href="#at-circle"></use></svg>
46
</a>
57
{% endif -%}
68

79
{%- if person.homepage %}
8-
<a class="icon tooltip" href="{{ person.homepage }}" title="Home: {{ person.homepage }}">
9-
<ion-icon class="is-size-3" src="{{ '/assets/ionicon/home.svg' | url }}"><i class="is-sr-only">homepage</i></ion-icon>
10+
<a class="icon tooltip" href="{{ person.homepage }}" aria-label="Home: {{ person.homepage }}">
11+
<svg class="icon-item" viewBox="0 0 512 512"><use xlink:href="#home"></use></svg>
1012
</a>
1113
{% endif -%}
1214

1315
{%- if person.twitter %}
14-
<a class="icon tooltip" href="https://twitter.com/{{ person.twitter }}" title="Twitter: {{ person.twitter }}">
15-
<ion-icon class="is-size-3" src="{{ '/assets/ionicon/logo-twitter.svg' | url }}"><i class="is-sr-only">Twitter</i></ion-icon>
16+
<a class="icon tooltip" href="https://twitter.com/{{ person.twitter }}" aria-label="Twitter: {{ person.twitter }}">
17+
<svg class="icon-item" viewBox="0 0 512 512"><use xlink:href="#logo-twitter"></use></svg>
1618
</a>
1719
{% endif -%}
1820

1921
{%- if person.github %}
20-
<a class="icon tooltip" href="https://github.com/{{ person.github }}" title="GitHub: {{ person.github }}">
21-
<ion-icon class="is-size-3" src="{{ '/assets/ionicon/logo-github.svg' | url }}"><i class="is-sr-only">GitHub</i></ion-icon>
22+
<a class="icon tooltip" href="https://github.com/{{ person.github }}" aria-label="GitHub: {{ person.github }}">
23+
<svg class="icon-item" viewBox="0 0 512 512"><use xlink:href="#logo-github"></use></svg>
2224
</a>
2325
{% endif -%}
2426

2527
{%- if person.linkedin %}
26-
<a class="icon tooltip" href="https://www.linkedin.com/in/{{ person.linkedin }}" title="LinkedIn: {{ person.linkedin }}">
27-
<ion-icon class="is-size-3" src="{{ '/assets/ionicon/logo-linkedin.svg' | url }}"><i class="is-sr-only">LinkedIn</i></ion-icon>
28+
<a class="icon tooltip" href="https://www.linkedin.com/in/{{ person.linkedin }}" aria-label="LinkedIn: {{ person.linkedin }}">
29+
<svg class="icon-item" viewBox="0 0 512 512"><use xlink:href="#logo-linkedin"></use></svg>
2830
</a>
2931
{% endif -%}

_layouts/base.liquid

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,16 @@
2424
<title>{{ pageTitle }}</title>
2525
<link rel=alternate type=application/atom+xml href="{{ site.url }}{{ '/feed.xml' | url }}" title="{{ site.title }} Atom feed" />
2626
<link rel="stylesheet" href="{{ '/assets/css/main.css' | url }}">
27-
<script type="module" src="https://unpkg.com/ionicons@5.0.0/dist/ionicons/ionicons.esm.js"></script>
28-
<script nomodule="" src="https://unpkg.com/ionicons@5.0.0/dist/ionicons/ionicons.js"></script>
2927
</head>
3028
<body>
31-
<header class="page-header hero is-primary">
32-
<div class="hero-body is-paddingless">
29+
<svg display="none">
30+
<g id="logo-github"><path d='M256,32C132.3,32,32,134.9,32,261.7c0,101.5,64.2,187.5,153.2,217.9a17.56,17.56,0,0,0,3.8.4c8.3,0,11.5-6.1,11.5-11.4,0-5.5-.2-19.9-.3-39.1a102.4,102.4,0,0,1-22.6,2.7c-43.1,0-52.9-33.5-52.9-33.5-10.2-26.5-24.9-33.6-24.9-33.6-19.5-13.7-.1-14.1,1.4-14.1h.1c22.5,2,34.3,23.8,34.3,23.8,11.2,19.6,26.2,25.1,39.6,25.1a63,63,0,0,0,25.6-6c2-14.8,7.8-24.9,14.2-30.7-49.7-5.8-102-25.5-102-113.5,0-25.1,8.7-45.6,23-61.6-2.3-5.8-10-29.2,2.2-60.8a18.64,18.64,0,0,1,5-.5c8.1,0,26.4,3.1,56.6,24.1a208.21,208.21,0,0,1,112.2,0c30.2-21,48.5-24.1,56.6-24.1a18.64,18.64,0,0,1,5,.5c12.2,31.6,4.5,55,2.2,60.8,14.3,16.1,23,36.6,23,61.6,0,88.2-52.4,107.6-102.3,113.3,8,7.1,15.2,21.1,15.2,42.5,0,30.7-.3,55.5-.3,63,0,5.4,3.1,11.5,11.4,11.5a19.35,19.35,0,0,0,4-.4C415.9,449.2,480,363.1,480,261.7,480,134.9,379.7,32,256,32Z'/></g>
31+
<g id="logo-slack"><path d='M126.12,315.1A47.06,47.06,0,1,1,79.06,268h47.06Z'/><path d='M149.84,315.1a47.06,47.06,0,0,1,94.12,0V432.94a47.06,47.06,0,1,1-94.12,0Z'/><path d='M196.9,126.12A47.06,47.06,0,1,1,244,79.06v47.06Z'/><path d='M196.9,149.84a47.06,47.06,0,0,1,0,94.12H79.06a47.06,47.06,0,0,1,0-94.12Z'/><path d='M385.88,196.9A47.06,47.06,0,1,1,432.94,244H385.88Z'/><path d='M362.16,196.9a47.06,47.06,0,0,1-94.12,0V79.06a47.06,47.06,0,1,1,94.12,0Z'/><path d='M315.1,385.88A47.06,47.06,0,1,1,268,432.94V385.88Z'/><path d='M315.1,362.16a47.06,47.06,0,0,1,0-94.12H432.94a47.06,47.06,0,1,1,0,94.12Z'/></g>
32+
<g id="logo-twitter"><path d='M496,109.5a201.8,201.8,0,0,1-56.55,15.3,97.51,97.51,0,0,0,43.33-53.6,197.74,197.74,0,0,1-62.56,23.5A99.14,99.14,0,0,0,348.31,64c-54.42,0-98.46,43.4-98.46,96.9a93.21,93.21,0,0,0,2.54,22.1,280.7,280.7,0,0,1-203-101.3A95.69,95.69,0,0,0,36,130.4C36,164,53.53,193.7,80,211.1A97.5,97.5,0,0,1,35.22,199v1.2c0,47,34,86.1,79,95a100.76,100.76,0,0,1-25.94,3.4,94.38,94.38,0,0,1-18.51-1.8c12.51,38.5,48.92,66.5,92.05,67.3A199.59,199.59,0,0,1,39.5,405.6,203,203,0,0,1,16,404.2,278.68,278.68,0,0,0,166.74,448c181.36,0,280.44-147.7,280.44-275.8,0-4.2-.11-8.4-.31-12.5A198.48,198.48,0,0,0,496,109.5Z'/></g>
33+
</svg>
34+
35+
<header class="page-header hero">
36+
<div class="hero-body is-primary is-paddingless">
3337
<div class="container">
3438
<div class="navbar" role="navigation" aria-label="main navigation">
3539
<div class="navbar-brand">
@@ -53,15 +57,11 @@
5357
</div>
5458
</div>
5559
</div>
56-
</header>
5760

58-
{%- if page.url == '/' -%}
59-
<section class="hero">
60-
<figure class="image">
61-
<img src="{{ '/assets/img/carlos-alfonso-AlBgcDfDG_s-unsplash_3by1-prog1.jpg' | url }}" alt="Austin skyline" title="Photo by Carlos Alfonso on Unsplash" loading="lazy">
62-
</figure>
63-
</section>
64-
{%- endif -%}
61+
{%- if page.url == '/' -%}
62+
{% responsiveImage "./assets/img/carlos-alfonso-AlBgcDfDG_s-unsplash_min.jpg", "Austin Skyline by Carlos Alfonso on Unsplash" %}
63+
{%- endif -%}
64+
</header>
6565

6666
<main class="page-main section has-background-white">
6767
<div class="container">
@@ -99,20 +99,20 @@
9999
</div>
100100
<div class="navbar-end">
101101
<a class="navbar-item is-inline-block-tablet" href="https://twitter.com/{{ site.author.twitter }}">
102-
<span class="icon tooltip" title="&ldquo;@{{ site.author.twitter }}&rdquo; on Twitter">
103-
<ion-icon class="is-size-3" src="{{ '/assets/ionicon/logo-twitter.svg' | url }}"></ion-icon>
102+
<span class="icon tooltip" aria-label="&ldquo;@{{ site.author.twitter }}&rdquo; on Twitter">
103+
<svg class="icon-item" viewBox="0 0 512 512"><use xlink:href="#logo-twitter"></use></svg>
104104
</span>
105105
<span class="is-sr-only-desktop">Twitter: @{{ site.author.twitter }}</span>
106106
</a>
107107
<a class="navbar-item is-inline-block-tablet" href="https://{{ site.author.slack }}.slack.com">
108-
<span class="icon tooltip" title="&ldquo;{{ site.author.slack }}&rdquo; on Slack">
109-
<ion-icon class="is-size-3" src="{{ '/assets/ionicon/logo-slack.svg' | url }}"></ion-icon>
108+
<span class="icon tooltip" aria-label="&ldquo;{{ site.author.slack }}&rdquo; on Slack">
109+
<svg class="icon-item" viewBox="0 0 512 512"><use xlink:href="#logo-slack"></use></svg>
110110
</span>
111111
<span class="is-hidden-desktop">Slack: {{ site.author.slack }}</span>
112112
</a>
113113
<a class="navbar-item is-inline-block-tablet" href="https://github.com/{{ site.author.github }}">
114-
<span class="icon tooltip" title="&ldquo;{{ site.author.github }}&rdquo; on GitHub">
115-
<ion-icon class="is-size-3" src="{{ '/assets/ionicon/logo-github.svg' | url }}"></ion-icon>
114+
<span class="icon tooltip" aria-label="&ldquo;{{ site.author.github }}&rdquo; on GitHub">
115+
<svg class="icon-item" viewBox="0 0 512 512"><use xlink:href="#logo-github"></use></svg>
116116
</span>
117117
<span class="is-hidden-desktop">GitHub: {{ site.author.github }}</span>
118118
</a>

_meetups/2016-01-19-meetup.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
layout: meetup
3-
title: Alex Sexton talks about client-side "security"
3+
title: Alex Sexton talks about client-side &quot;security&quot;
44
author: astacy
55
when: 2016-01-19T19:30:00-06:00
66
speakers:

_sass/_main.scss

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
@charset "utf-8";
22

33
// tetradic harmony via https://color.joelb.dev/hex/ED1878
4-
$tetradic0: hsl(333, 85%, 50%);
5-
$tetradic1: hsl(213, 85%, 50%);
4+
$tetradic0: hsl(333, 85%, 45%); // darkened 5% for a11y contrast
5+
$tetradic1: hsl(213, 85%, 45%); // darkened 5% for a11y contrast
66
$tetradic2: hsl(153, 85%, 40%); // lightness reduced by 10%
77
$tetradic3: hsl(33, 85%, 50%);
88

@@ -14,6 +14,7 @@ $info: $tetradic1;
1414
// @import "../node_modules/bulma/sass/utilities/_all.sass";
1515
@import "../node_modules/bulma/sass/utilities/initial-variables.sass";
1616

17+
$link: darken($blue, 3%); // darkened 3% for a11y contrast
1718
$scheme-main: $white-ter;
1819
$footer-background-color: $white-ter;
1920

@@ -78,19 +79,31 @@ $footer-background-color: $white-ter;
7879
* BULMA CUSTOMIZATIONS
7980
*/
8081

81-
.hero.is-primary {
82+
.hero-body.is-primary {
83+
background-color: $primary;
84+
8285
.navbar-item,
8386
.navbar-link {
8487
// reduce opacity for a11y color contrast
8588
color: hsla(0, 100%, 100%, 0.8);
89+
90+
&:hover,
91+
&:focus {
92+
background-color: darken($primary, 5%);
93+
}
8694
}
8795
}
8896

97+
.content li + li {
98+
margin-top: 0.5em;
99+
}
100+
89101
.icon {
90102
vertical-align: bottom;
91103

92104
.card & {
93105
margin-top: 2px;
106+
width: 2em;
94107
}
95108

96109
@media screen and (min-width: $desktop) {
@@ -100,6 +113,15 @@ $footer-background-color: $white-ter;
100113
}
101114
}
102115

116+
.icon-item {
117+
fill: currentColor;
118+
width: 84%;
119+
120+
.message-body & {
121+
width: 71%;
122+
}
123+
}
124+
103125
.page-main {
104126
a {
105127
text-decoration: underline;

_sass/_tooltips.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* TOOLTIP
33
*/
44

5-
.tooltip[title] {
5+
.tooltip[aria-label] {
66
position: relative;
77

88
.pic & {
@@ -27,7 +27,7 @@
2727
background-color: hsla(0, 0%, 20%, 0.95);
2828
border-radius: 3px;
2929
color: #fff;
30-
content: attr(title);
30+
content: attr(aria-label);
3131
font-size: 14px;
3232
line-height: 1.2;
3333
margin-bottom: 5px;
59.4 KB
Loading

0 commit comments

Comments
 (0)