Frontend Flashcards
What are the key differences between REST and GraphQL APIs, and when would you choose one over the other?
REST: Fixed endpoints, multiple requests for related data, over-fetching/under-fetching issues.
GraphQL: Single endpoint, flexible queries, fetch only needed data, efficient for complex relationships.
When to choose:
- REST: Simple APIs, caching, well-structured resources.
- GraphQL: Dynamic queries, complex relationships, reduced requests, frontend flexibility.
How would you ensure that a web application you build is accessible (A11Y
) and adheres to best practices for users with disabilities?
- Semantic HTML: Use proper elements (<button>, <label>, <nav>, etc.).</label></button>
- ARIA Attributes: Add aria-labels, roles, and live regions where needed.
- Keyboard Navigation: Ensure all interactive elements are reachable via Tab and Enter.
- Contrast & Colors: Maintain WCAG-compliant contrast ratios.
- Alt Text: Provide descriptive alt for images.
- Screen Reader Testing: Use VoiceOver, NVDA, or JAWS for validation.
- Forms & Inputs: Associate labels properly and use error messages with guidance.
- Responsive & Scalable Text: Ensure text resizes without breaking layout.
- Avoid Motion Issues: Reduce animations for users with motion sensitivity (prefers-reduced-motion).
- Automated Testing: Use Lighthouse, axe, or WAVE tools to check compliance.
What are the benefits of using a component-based architecture in frameworks like React, Angular, or Vue.js?
Reusability: Build once, use anywhere, reducing code duplication.
Maintainability: Easier debugging and updates with modular components.
Scalability: Facilitates large-scale applications by breaking UI into smaller, manageable parts.
Encapsulation: Components manage their own state and logic, reducing side effects.
Performance Optimization: Efficient updates with virtual DOM (React) and change detection (Angular, Vue).
Readability & Organization: Clear separation of concerns improves code structure.
Faster Development: Teams can work on independent components in parallel.
Cross-Framework Compatibility: Components can be reused with frameworks like Web Components.
What are some strategies to improve the performance of a large-scale frontend application?
Code Splitting & Lazy Loading: Load only necessary code (React.lazy, import() in Webpack).
Optimized Rendering: Use memoization (React.memo, useMemo, useCallback).
Efficient State Management: Reduce unnecessary re-renders with Context API, Redux, or Zustand.
Virtual DOM Optimization: Minimize re-renders by using key props correctly.
Image & Asset Optimization: Use WebP, lazy loading, and responsive images.
Minification & Compression: Enable Gzip/Brotli compression and minify JS/CSS.
Caching & CDN: Store assets, API responses, and static files in a CDN.
Reduce Third-Party Scripts: Limit unnecessary dependencies and optimize bundle size.
Debounce & Throttle: Optimize event listeners (scroll, resize, input).
Performance Monitoring: Use Lighthouse, Web Vitals, and DevTools to identify bottlenecks.
Describe a closure
A closure is a function that remembers the variables from its outer scope even after the outer function has executed. It allows functions to retain access to their lexical scope.
Uses of Closures:
1. Data Encapsulation – Create private variables.
2. Memoization – Cache results for performance.
3. Event Handlers & Callbacks – Maintain state in asynchronous operations.
Example in Simple Words:
1. You tell a secret to your friend.
2. Your friend remembers it, even if you walk away.
3. Later, they can still say the secret!
What is the difference between const
, let
, and var
?
var
→ Function-scoped, hoisted with undefined, can be reassigned and redeclared.let
→ Block-scoped, hoisted but not initialized, can be reassigned but not redeclared.const
→ Block-scoped, hoisted but not initialized, cannot be reassigned or redeclared.
Best Practice: Use const by default, use let when reassignment is needed, and avoid var
What are some ES6 methods and what do they do?
.map()
→ Creates a new array by applying a function to each element..filter()
→ Returns a new array with elements that pass a condition..reduce()
→ Accumulates array values into a single result..find()
→ Returns the first element that meets a condition..findIndex()
→ Returns the index of the first matching element..forEach()
→ Iterates over an array (does not return a new array)..includes()
→ Checks if an array contains a specific value..some()
→ Returns true if at least one element meets a condition..every()
→ Returns true if all elements meet a condition..Object.entries()
→ Converts an object into an array of key-value pairs..Object.values()
→ Returns an array of object values..Object.keys()
→ Returns an array of object keys.
What is the difference between apply
, call
, and bind
?
All three methods are used to change the this context of a function, but they differ in how they pass arguments:
call()
→ Invokes the function immediately, passing arguments individually.
function greet(name) { console.log(`Hello, ${name}!`); } greet.call(null, "Alice"); // "Hello, Alice!"
apply()
→ Invokes the function immediately, passing arguments as an array.
function sum(a, b) { return a + b; } console.log(sum.apply(null, [5, 10])); // 15
bind()
→ Returns a new function with a set this value and preset arguments, but doesn’t invoke it immediately.
function multiply(a, b) { return a * b; } const double = multiply.bind(null, 2); console.log(double(5)); // 10
Describe the JavaScript Event Loop
The JavaScript Event Loop manages asynchronous tasks in a single-threaded environment. It ensures that operations like I/O, timers, and promises don’t block execution.
How It Works:
1. Call Stack → Executes synchronous code (LIFO - Last In, First Out).
2. Web APIs → Handles asynchronous tasks (e.g., setTimeout, fetch).
3. Callback Queue → Stores callbacks from setTimeout, setInterval, etc.
4. Microtask Queue → Stores Promises (.then()), MutationObserver, queueMicrotask().
5. Event Loop → Moves tasks from queues to the call stack when it’s empty.
Execution Order:
1. Call Stack executes synchronous code.
2. Microtask Queue (Promise.then) executes before Callback Queue.
3. Callback Queue executes (setTimeout, setInterval, DOM events).
console.log("Start"); setTimeout(() => console.log("Timeout"), 0); Promise.resolve().then(() => console.log("Promise")); console.log("End");
Output:
Start End Promise Timeout
Key Takeaway: Microtasks (Promises) run before macrotasks (setTimeout).
Explain the this
keyword in JavaScript
It depends on how it’s called.
- Regular functions: this depends on how they are called.
- Arrow functions: this is inherited from the surrounding scope.
- Explicit binding (call, apply, bind) can override the default this behavior.
What is a Promise in JavaScript?
A Promise is an object that represents the eventual completion (or failure) of an asynchronous operation. It has three states:
- Pending → Initial state, operation not completed.
- Fulfilled → Operation completed successfully (.then()).
- Rejected → Operation failed (.catch()).
What are Prototypes in JavaScript?
A prototype is an object that other objects inherit properties and methods from. It enables inheritance in JavaScript.
function Person(name) { this.name = name; } Person.prototype.sayHello = function() { console.log(`Hello, I'm ${this.name}`); }; const user = new Person("Alice"); user.sayHello(); // "Hello, I'm Alice"
Waht is Observer pattern in JavaScript?
The Observer Pattern is a design pattern where an object (Subject) maintains a list of Observers (listeners) and notifies them when its state changes.
Used in event-driven programming (e.g., DOM events, Pub-Sub, Redux).
class Subject { constructor() { this.observers = []; } subscribe(observer) { this.observers.push(observer); } unsubscribe(observer) { this.observers = this.observers.filter(obs => obs !== observer); } notify(data) { this.observers.forEach(observer => observer(data)); } } const subject = new Subject(); const observer1 = data => console.log(`Observer 1: ${data}`); const observer2 = data => console.log(`Observer 2: ${data}`); subject.subscribe(observer1); subject.subscribe(observer2); subject.notify("Event triggered!"); // Output: Observer 1: Event triggered! // Observer 2: Event triggered!
What is Module Pattern in JavaScript?
The Module Pattern is used to encapsulate code, creating private and public variables/methods using closures. It helps avoid global scope pollution.
Encapsulates logic, prevents global scope pollution, and keeps data private.
const Counter = (function() { let count = 0; // Private variable return { increment: () => ++count, decrement: () => --count, getCount: () => count }; })(); console.log(Counter.increment()); // 1 console.log(Counter.increment()); // 2 console.log(Counter.getCount()); // 2
Who benefits from accessibility?
People with Disabilities → Users with visual, auditory, motor, or cognitive impairments.
Elderly Users → Those with declining vision, hearing, or motor skills.
Temporary Disabilities → Injuries (e.g., broken arm) or situational impairments (e.g., bright sunlight).
Non-Native Speakers → Clear navigation and text improve usability.
Users with Slow Internet → Lightweight, well-structured pages load faster.
SEO & Businesses → Search engines favor accessible websites, increasing reach.
Name some ways responsive/mobile first design can affect accessibility
Improves Readability & Usability
- Uses relative units (rem, %, vh) for scalable text.
- Ensures proper contrast ratios for readability.
Enhances Navigation
- Uses larger touch targets for mobile users.
- Implements skip links and keyboard-friendly navigation.
Supports Assistive Technologies
- Ensures semantic HTML for screen readers.
- Uses ARIA roles only when necessary.
Optimizes Performance
- Reduces unnecessary animations (respects prefers-reduced-motion).
- Uses lazy loading to improve page speed.
Describe instances where one might use a link or button
Rule of Thumb: Links navigate, buttons perform actions!
**Use a <a> (Link) when:**
- Navigating to another page or section.
- Opening external resources (target=”_blank”).
- Jumping within a page (href=”#section”).</a>
**Use a <button> when:**
- Triggering an action (e.g., form submission, modal opening).
- Performing JavaScript functions (onClick).
- Toggling UI elements (e.g., dropdowns, accordions).</button>
How would you convince your Manager to allocate funds for an accessibility audit?
Avoid lawsuits by meeting WCAG, ADA, or local regulations.
Business Growth & Market Reach
- 1 billion+ people worldwide have disabilities → More potential users/customers.
SEO & Performance Benefits
- Accessible sites rank higher on Google and improve user experience.
Better Usability for Everyone
- Improves navigation, readability, and mobile experience for all users.
Competitive Advantage
- Many companies overlook accessibility—this is a way to stand out.
What is the accessibility tree?
The Accessibility Tree is a structure derived from the DOM, used by screen readers and assistive technologies to interpret web content.
Ensuring a clean Accessibility Tree improves usability for all users!
How It Works:
- Built from semantic HTML and ARIA attributes.
- Excludes elements like display: none, visibility: hidden.
- Represents roles, states, and properties of UI elements.