Other minor JS glossary

  1. IIFE
  2. Closure
  3. Virtualized lists
  4. Inheritance in JS
  5. Promise
  6. Async / await
  7. "==" & "==="
  8. Critical render path
  9. CSS specifity rules
  10. Inline-block & inline display types
  11. Proxy and reflect
  12. Resource hints
  13. Browser performance metrics
  14. Script loading attributes

IIFE?

IIFE: Immediately Invoked Function Expression

JavaScript provides a variety of methods to define and execute Functions, there are named functions, anonymous functions and then there are Functions that are executed as soon as they are mounted, these functions are known as Immediately Invoked Function Expressions or IIFEs.

(function () {
// Function Logic Here.
})();

Closure

A closure is a stateful function that is returned by another function. A closure gives you access to an outer function’s scope from an inner function

function init() {
  var name = 'Mozilla'; // name is a local variable created by init
  function displayName() { // displayName() is the inner function, a closure
    alert(name); // use variable declared in the parent function
  }
  displayName();
}
init();

In above example, displayName function is a inner function inside init but, still has access to variables from outer function.

Virtualized lists

Virtual rendering is rendering only visible portion of a large element. Larger number of DOM nodes bring downt the page w.r.t to performance and usability. So it makes sense to load only the elements that are visible and unload them when they are not by replacing them with new ones.

react-window is built upon this technique & useful for rendering long & heavy lists

What is prototype inheritance ?

  • Object Prototype

    JavaScript is often described as a prototype-based language — to provide inheritance, objects can have a prototype object, which acts as a template object that it inherits methods and properties from. Prototype property is basically an object (also known as Prototype object), where we can attach methods and properties in a prototype object, which enables all the other objects to inherit these methods and properties.

  • Prototype inheritance

    When it comes to inheritance, JavaScript only has one construct: objects. Each object has a private property which holds a link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype. By definition, null has no prototype, and acts as the final link in this prototype chain.

Promise

A Promise is a holder for a value not necessarily known when the promise is created. It allows you to associate handlers with an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future.

Creating a simple promise
return new Promise((resolve, reject) => {
  try {
    // Do something
    resolve(data);
  } catch (err) {
    reject(err);
  }
});

Async / await

Async / await is promises with much easier to read syntax.

// Implicit return of a promise value
async function getAValue() {
  // Do something
  return 23;
}

// Consuming async function through promises
getAValue().then(x => console.log(x));
// Consuming async function through await
const returnedValue = await getAValue();
// You can also any thenable object & promise through await

async / await aids with implicit return values while executing the function. This helps in reducing bugs using a promise based function that used return instead of resolve. An example as below:

function validPromise() {
  return new Promise((res, rej) => {
    console.log('Executing valid promise');
    resolve('valid promise');
  });
}

function promiseThatDoesntResolve() {
  return new Promise((res, rej) => {
    console.log('Executing invalid promise');
    return 'invalid promise';
  })
}

// Prints valid promise
validPromise().then(x => console.log(x));
// Never resolves & hence we never get any output
promiseThatDoesntResolve().then(x => console.log(x));
Try above example in your console & see for yourself
  1. Execute validPromise().then(x => console.log(x))
  2. Verify that you see valid promise in your console
  3. Now, execute promiseThatDoesntResolve().then(x => console.log(x))
  4. Verify that promise is executed & output is not printed

We wouldn't have the same problem if both functions became async functions as demonstrated below

async function validAsync() {
  console.log("Executing valid promise");
  res("valid promise");
}

async function promiseThatDoesntResolve() {
  console.log("Executing invalid promise");
  return "invalid promise";
}

// Both work same as both are just returning value

Also you can notice in promise example that you have to promise funciton code keeps executing until end of function or a return statement i.e., any code post resolve will still get executed if return is not used

Difference between == and ===

"==" inherently converts type and "===" does not convert type.

Double Equals (==) checks for value equality only. It inherently does type coercion. This means that before checking the values, it converts the types of the variables to match each other.

On the other hand, Triple Equals (===) does not perform type coercion. It will verify whether the variables being compared have both the same value AND the same type.

Few examples
  • All are integers
    console.log(123 == 123); //true
    console.log(123 === 123); //true
  • All are integers but in strings
    console.log("123" == "123") //true
    console.log("123" === "123") //true
  • Same value but between integer & string.
    console.log("123" == 123); //true
    console.log("123" === 123); //false
  • Comparing 0 in string & number formats.
    console.log(0 == false) //true
    console.log(0 === false) //false
    
    // In string format
    console.log("0" == false) //true
    console.log("0" === false) //false
    
    // Empty string is same as 0 or false when doing double equals.
    console.log("" == false) //true
    console.log("" === false) //false
  • Comparing 1 in string & number formats.
    console.log(1 == true) //true
    console.log(1 === true) //false
    
    // In string format
    console.log("1" == true) //true
    console.log("1" === true) //false
  • Comparing null & undefined. You'd think hope both are same but nope!
    console.log(null == undefined) //true
    console.log(null === undefined) //false
The JS equality matrix with comparison between all weird values. Various permutations & combinations of equality between different values in JS

Critical render path

Here’s a quick overview of the steps performed by the browser when rendering a page:

  1. The browser downloads and parses the HTML markup and creates the DOM.
  2. Next, it downloads and processes the CSS markup and constructs the CSS Object Model (CSSOM).
  3. Then, it combines the necessary nodes from the DOM and CSSOM to create the Render Tree, a tree structure of all visible nodes required to render the page.
  4. It calculates the dimensions and position of every element on the page through the Layout process.
  5. Finally, the browser paints the pixels on the screen.
The document is marked as “interactive” when the user agent stops parsing the document. Meaning, the DOM tree is ready.
The user agent fires the DOMContentLoaded (DCL) event once any scripts marked with “defer have been executed, and there are no stylesheets that are blocking scripts. Meaning, the CSSOM is ready.

CSS specificity rules

CSS specificity is consider all styles that are applicable to the current element & determining which one to be applied based a set order. CSS specifity order is as follows in increasing order:

  1. Universal selector (*)
  2. Type / tagname selector (body, p, h1)
  3. Pseudo element selector (::before & ::after)
  4. Class selector (.navbar, .sidebar)
  5. Pseudo class selector (hover, active)
  6. Attribute selector ([href="#"], [role="group"])
  7. not selectors
  8. Inline style attribute
  9. !important

Difference between inline-block and inline ?

Compared to display: inline, the major difference is that inline-block allows to set a width and height on the element. Also, with display: inline, top and bottom margins & paddings are not respected, and with display: inline-block they are.

Example
Lorem ipsum dolor sit amet consectetur adipiscing elit, sed do eiusmod tempor incididunt ut ,
This is an element which is of "inline-block" display type and hence will not wrap even as it overflows into the next line in the element.
consectetur adipiscing elit, sed do eiusmod tempor incididunt ut consectetur adipiscing elit, sed do eiusmod tempor incididunt ut consectetur adipiscing elit, sed do eiusmo labore
This is an element with "inline" display type. This is really long text but this will wrap around like regular text due to the display type.
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi

Proxy & Reflect

-- TODO --

Resource hints in HTML

  1. dns-prefetch: indicates to the browser that it should perform the resolution of a given domain name (determining the IP to contact) before that domain is used to download resources
  2. preconnect: indicates to the browser that it should connect a given origin, before that domain is used to download resources. Preconnecting involves, like – dns-prefetch, the DNS resolution, but also the TCP handshake and TLS negotiation (if the page is secure)
  3. prefetch: indicates to the browser that it can download a given resource, even if it is not detected in the page. The resource is downloaded with a low priority
  4. preload: tells the browser that it must download a given resource as soon as possible, with high priority.

Browser performance metrics

  1. Time to Interactive - TTI
    TTI measures how long it takes a page to become fully interactive. A page is considered fully interactive when:
    1. The page displays useful content, which is measured by the First Contentful Paint,
    2. Event handlers are registered for most visible page elements
    3. The page responds to user interactions within 50 milliseconds.
  2. Total Blocking Time - TBT
    TBT measures the total amount of time that a page is blocked from responding to user input, such as mouse clicks, screen taps, or keyboard presses.
    The sum is calculated by adding the blocking portion of all long tasks between First Contentful Paint and Time to Interactive. Any task that executes for more than 50 ms is a long task. The amount of time after 50 ms is the blocking portion.
  3. Largest Contentful Paint - LCP
    LCP measures when the largest content element in the viewport is rendered to the screen.
  4. Time to First Byte - TTFB
    The time that it takes for a user's browser to receive the first byte of page content. This is completely server side work. Nothing that client can do besides identifying that this is the problem.
  5. First Contentful Paint - FCP
    FCP measures how long it takes the browser to render the first piece of DOM content after a user navigates to your page.

Script loading attributes

There are 3 different script loading scenarios
  1. No attribute: Pause parsing; Fetch the JS resource & execute it right away.
  2. async: Fetch the JS resource parallel to parsing HTML; Pause parsing when resource is available & execute it right away.
  3. defer: Fetch the JS resource parallel to parsing HTML; Execute resource once parser has completed it's job fully.

What is enumerable in Object

Objects has lot of properties to define a property. The enumerable attribute determines whether or not a property is accessible when the object properties are enumerated through an iterator.

Object.defineProperty(person, 'weight', {
  enumerable: false,
  value: '200kg'
  });

References:

  1. Geek for geeks explaination of IIFE
    https://www.geeksforgeeks.org/javascript-immediately-invoked-function-expressions-iife/
  2. MDN article for IIFE
    https://developer.mozilla.org/en-US/docs/Glossary/IIFE
  3. MDN article for Closure
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
  4. Building a virtualized list from scratch
    https://medium.com/ingeniouslysimple/building-a-virtualized-list-from-scratch-9225e8bec120
  5. Javascript prototype inheritance explaination
    https://javascript.info/prototype-inheritance
  6. MDN article on prototypes
    https://developer.mozilla.org/docs/Learn/JavaScript/Objects/Object_prototypes
  7. MDN article on inheritance chain
    https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
  8. MDN article on promises
    https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise
  9. Brilliant article on differences between equal to signs in JavaScript
    https://www.freecodecamp.org/news/javascript-triple-equals-sign-vs-double-equals-sign-comparison-operators-explained-with-examples/
  10. Lighthouse performance information.
    https://web.dev/lighthouse-performance/
  11. web.dev article
    https://web.dev/learn/css/specificity
  12. MDN article on CRP
    https://developer.mozilla.org/en-US/docs/Web/Performance/Critical_rendering_path
  13. web.dev article on CRP
    https://web.dev/learn/performance/understanding-the-critical-path
  14. Nice explaination about CRP by Niko Kaleev
    https://nitropack.io/blog/post/critical-rendering-path-optimization
  15. Chromium developers intro for CRP
    https://www.chromium.org/developers/the-rendering-critical-path/
  16. Another CRP article
    https://calendar.perfplanet.com/2012/deciphering-the-critical-rendering-path/