A blog with 100/100 Performance score; based on https://github.com/google/eleventy-high-performance-blog
-
Run dev server
Navigate into your new site’s directory and start it up.
cd cmolina.dev/ npm i npm run watch # Your site will be running at http://localhost:8080
-
Deploy ✨
The website is hosted with Firebase. You will need to install its CLI globally
npm install -g firebase-tools
and runfirebase login
once.# build and serve prod assets npm run build npx -y serve _site # Checkout http://localhost:5000/, # then stop the server and push to prod! npm run deploy # see it live https://cmolina.dev/
Review the previous implementation at https://github.com/cmolina/cmolina.dev_gatsby-starter-blog
- Perfect score in applicable lighthouse audits (including accessibility).
- Single HTTP request to First Contentful Paint.
- Very optimized Largest Contentful Paint (score depends on image usage, but images are optimized).
- 0 Cumulative Layout Shift.
- ~0 First Input Delay.
- Generates multiple sizes of each image and uses them in
srcset
. - Generates a blurry placeholder for each image (without adding an HTML element or using JS).
- Transcodes images to AVIF and webp and generates
picture
element. - Transcodes GIFs to muted looping autoplaying MP4 videos for greatly reduced file size.
- Lazy loads images (using native
loading=lazy
). - Async decodes images (using
decoding=async
). - Lazy layout of images and placeholders using
content-visibility: auto
. - Avoids CLS impact of images by inferring and providing width and height (Supported in Chrome, Firefox and Safari 14+).
- Downloads remote images and stores/serves them locally.
- Immutable URLs.
- Defaults to the compact "classless" Bahunya CSS framework.
- Inlines CSS.
- Dead-code-eliminates / tree-shakes / purges (pick your favorite word) unused CSS on a per-page basis with PurgeCSS.
- Minified CSS with csso.
- Immutable URLs for JS.
- Sets immutable caching headers for images, fonts, and JS (CSS is inlined). Currently implements for Netlify
_headers
file. - Minifies HTML and optimizes it for compression. Uses html-minifier with aggressive options.
- Uses rollup to bundle JS and minifies it with terser.
- Prefetches same-origin navigations when a navigation is likely.
- If an AMP files is present, optimizes it.
- Serves fonts from same origin.
- Makes fonts
display:optional
.
- Supports locally serving Google Analytics's JS and proxying it's hit requests to a Netlify proxy (other proxies could be easily added).
- Supports sending Core Web Vitals metrics to Google Analytics as events.
- Support for noscript hit requests.
- Avoids blocking onload on analytics requests.
- To turn this on, specify
googleAnalyticsId
inmetadata.json
. (Note, that this is not compatible with the not-yet-commonly used version 4 of Google Analytics.)
- Uses 🚨 as favicon during local development.
- Supports a range of default tests.
- Runs build and tests on
git push
. - Sourcemap generated for JS.
- Share button preferring
navigator.share()
and falling back to Twitter. Using OS-like share-icon. - Support for OGP metadata.
- Support for Twitter metadata.
- Support for schema.org JSON-LD.
- Sitemap.xml generation.
- Read time estimate.
- Animated scroll progress bar…
- …with an optimized implementation that should never cause a layout.
Generates a strong Content-Security-Policy (CSP) using HTTP headers.
- Default-src is self.
- Disallows plugins.
- Generates hash based CSP for the JS used on the site.
- To extend the CSP with new rules, see CSP.js
- Downloaded remote images, and generated sizes are cached in the local filesystem…
- …and SHOULD be committed to git.
.persistimages.sh
helps with this.
This is not an officially supported Google product, but rather Malte's private best-effort open-source project.
Originally, I added the original repo as a remote with
git remote add upstream [email protected]:google/eleventy-high-performance-blog.git
To do the merge, I run
git fetch upstream
git merge upstream/main main --allow-unrelated-histories -s subtree --squash
Then, for each modified file:
- Unstage all files
- Solve conflicts and stage them
- Reset some changes, particularly
- new and modified files in directories like
img
,img/remote
, andposts
- deleted files, which are files like posts that should remain
- new and modified files in directories like
- For each modified file, bring back the changes that should remain and stage them
- For each deleted file, ensure it is not needed anymore before staging them
After this, ensure everything is still working and make a commit with the following message: chore: Squashed changes from google/eleventy-high-performance-blog
.
- Install node v16;
nvm i lts/gallium
- If you fail to install the dependencies due to
sharp
failing to build, ensurearch
returnsarm64
- you uninstall
libvips
withbrew uninstall vips
, or setup theSHARP_IGNORE_GLOBAL_LIBVIPS
env variable
- Follow the steps under Quick Start