Skip to content

Instantly share code, notes, and snippets.

@ellm
Last active April 21, 2024 20:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ellm/7ea79287250f3f9ec4563e1ccee0bebb to your computer and use it in GitHub Desktop.
Save ellm/7ea79287250f3f9ec4563e1ccee0bebb to your computer and use it in GitHub Desktop.
JavaScript Notes and Snippets

JavaScript Notes and Snippets

Promises

  • promise.all() can be used to queue up a few asynchronous calls to load before a subsquent script is called.
  • This can be useful for preloading libraries before some scripts that depend on the library are called.
this.searchTrigger.addEventListener('click', () => {
  // Lazyload Typeahead and Bloodhound libraries.
  Promise.all([
    getTypeAhead(),
    getBloodhound(),
  ]).then((loadedModules) => {
    const Bloodhound = loadedModules[1].default;

    if (! Bloodhound) {
      return;
    }

    this.setUpAutocomplete(Bloodhound);
    this.setAutocompleteCustomizations();
    // Make sure search field is focused.
    this.searchField.focus();
  });
});

Performance Notes

Frames

Painting

  • To get pixels from your webpage onto the screen, the browser paints such pixels.
  • Painting is an expensive operation.
  • In Dev tools, use "Performance" tab and run recording. "Paint" events will appear as green blocks in the Main thread.
  • translateZ() hack can be used to promote a paint to it's own layer and move the operation from the Main thread to the GPU. This helps reduce the operation cost (https://aerotwist.com/blog/on-translate3d-and-layer-creation-hacks/)
  • Alternatively, the will-change property can help browsers identify paint events that should happen on the GPU.
  • Knowing when to promote a layer will be valuable during your performance optimisation journey

Preload, Prefetch

Render Blocking Scripts

  • https://developers.google.com/web/tools/chrome-devtools/network-performance/
  • When the browser encounters a <script> tag, it must pause rendering and execute the script immediately
  • Find scripts that arent needed for page load and mark them asynchronous or defer their execution to speed up load time.
  • By marking this script with the async attribute and moving it to the bottom of the document's <body>, the page can load without waiting for the script
  • async is commonly used for third-party-scripts that are randomly placed in the DOM
  • defer scripts is loaded after domContentLoaded is finished (domContentLoaded is the point when both the DOM is ready and there are no stylesheets that are blocking JavaScript execution).

Network Tooling in Chrome

Binding

export default class MagazineTimeline extends Component {
   this.stickNavThrottle = new Throttle(
      this.setStickyNav.bind(this), // 'this' becomes bound to Class and not Throttle
      'scroll',
      document,
      50
   );
}

Creating Bookmarklets

-https://code.tutsplus.com/tutorials/create-bookmarklets-the-right-way--net-18154

Throttling/Debouncing

Fetch

// This will replace image src not found on local CDN with a remote CDN
(function () {
	console.clear();
	Array.prototype.forEach.call(document.querySelectorAll('img'), (el) => {
		fetch(el.src,{mode: 'no-cors', method: 'get'}).then(function(response) {
			if(200 !== response.status) {
				console.log('Image src missing: ', el.src);
				const newsrc = el.src.replace('old_url', 'new_url');
				// @todo: update additional attributes for lazyloading to work
				el.src = newsrc;
				el.srcset = newsrc;
				el.dataset.src = newsrc;
				el.dataset.srcset = newsrc;
				console.log('Image src updated: ', el.src);
			}
		})
	});
}());

window.scrollY

  • distance top of page has past the top of the view port in pixels
  • useful when calculating scroll depth percentage of page
// Basic formula for calculating scroll percentage
const pageWrap = document.querySelector('.page-wrapper');
const currY = window.scrollY;
const postHeight = window.innerHeight;
const scrollHeight = pageWrap.offsetHeight;
const scrollPercent = (currY / (scrollHeight - postHeight)) * 100;

onload() and Event Delegation

  • for each iframe, wait until it has loaded then addEventListener to a submit button within the iframe. Set a setTimeout to calculate a new height of the iframe based on the length of the content.
Array.prototype.forEach.call(iframes, (el) => {
    el.onload = function () {
        const iframe = el.contentWindow.document;
        iframe.addEventListener('click', (e) => {
          if (e.target && e.target.matches('input[type="submit"]')) {
            const self = this;
            setTimeout(() => {
              const newHeight =
                self.contentWindow.document.body.scrollHeight + 50;
              self.height = `${newHeight}px`;
            }, 500);
          }
        });
    };
});

load()

  • Wait until DOM has completely loaded then fire script.
  • deprecated function in jQuery.
jQuery(window).load(function() {
    // Stuff here will not fire until DOM has loaded completely.
    // Including AJAX
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment