git log --pretty=format:"* %s" v0.0.8..v0.1.0 > changelog.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const loader = new loadScript(); | |
loader.load([ | |
'//apis.google.com/js/client:platform.js?onload=startApp', | |
'//cdnjs.cloudflare.com/ajax/libs/dropbox.js/0.10.3/dropbox.min.js' | |
]).then(({length}) => { | |
console.log(`${length} scripts loaded!`); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[lcp] | |
const po = new PerformanceObserver(() => {}); | |
po.observe({type: 'largest-contentful-paint', buffered: true}); | |
const lastEntry = po.takeRecords().slice(-1)[0]; | |
return lastEntry.renderTime || lastEntry.loadTime; | |
[cls] | |
const po = new PerformanceObserver(() => {}); | |
po.observe({type: 'layout-shift', buffered: true}); | |
return po.takeRecords().reduce((val, entry) => val + entry.value, 0); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const puppeteer = require('puppeteer'); | |
const Good3G = { | |
'offline': false, | |
'downloadThroughput': 1.5 * 1024 * 1024 / 8, | |
'uploadThroughput': 750 * 1024 / 8, | |
'latency': 40 | |
}; | |
const phone = puppeteer.KnownDevices['Nexus 5X']; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<img data-src="unicorn.jpg" loading="lazy" alt=".." class="lazyload"/> | |
<script> | |
// Select all images with the class "lazyload" | |
const images = document.querySelectorAll("img.lazyload"); | |
// Check if the browser supports the "loading" attribute | |
if ('loading' in HTMLImageElement.prototype) { | |
// If so, we'll update all <img src> to point to the data-src instead | |
images.forEach(img => { | |
img.src = img.dataset.src; |
- Web Page Usability Matters
- PageSpeed Insights w/Lighthouse and Chrome User Experience Report
- Data Saver for Chrome on Android - enable and then look at about:flags for Lite Pages and other interventions
- web.dev/fast - code-labs and tooling for optimizing performance
- Lighthousebot for using Lighthouse in continuous integration
- Bundlesize for JavaScript budgets in CI
- Start performance budgeting
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Examples at https://gist.github.com/bendc/9b05735dfa6966859025#gistcomment-1370485 | |
// array utils | |
// ================================================================================================= | |
const combine = (...arrays) => [].concat(...arrays); | |
const compact = arr => arr.filter(Boolean); |
Working with a React codebase and want to use Preact? Ideally, you should use preact and preact-compat for your dev, prod and test builds. This will enable you to discover any interop bugs early on. If you would prefer to only alias preact and preact-compat in Webpack for production builds (e.g if your preference is using React DevTools and enzyme), make sure to thoroughly test everything works as expected before deploying to your servers.
Workbox runtime caching recipes
Your Service Worker script will need to import in Workbox and initialize it before calling any of the routes documented in this write-up, similar to the below:
importScripts('workbox-sw.prod.v1.3.0.js');
const workbox = new WorkboxSW();
// Placeholder array populated automatically by workboxBuild.injectManifest()
NewerOlder