1. Explain the difference between @wire and @track decorators in LWC. When would you use each one, and what happens if you use @wire on a property that doesn't need reactivity?
@track makes a property reactive so the component re-renders when it changes, while @wire binds a property or function to an Apex method or Lightning data service (LDS) and automatically manages the request lifecycle. Use @track for local component state and @wire for server data. If you use @wire on a non-reactive property, it will still execute the Apex method and attempt to bind results, wasting resources and potentially causing unexpected behavior since the component won't re-render even if the value changes.
2. You have an LWC that fetches a list of Accounts via @wire and displays them in a table. The user filters the list locally, but the filter is slow and the component freezes briefly. What are two approaches to fix this performance issue?
First, you can debounce the filter input using a timer so that filtering logic doesn't run on every keystroke, reducing the frequency of DOM updates. Second, you can move the filtering logic into a separate compute or use a getter with conditional rendering to avoid unnecessary re-renders. Alternatively, use the track decorator sparingly and only on filtered data rather than the entire array, or paginate the results so only a small subset is rendered at once, which reduces the DOM size and improves responsiveness.
3. Your LWC component uses @wire to fetch Account data, but the wired function sometimes receives stale data after a user updates a record in a different component. How would you ensure the data refreshes correctly?
You should use the refreshApex function imported from 'lightning/uiRecordApi' to manually refresh the wired data after a user mutation occurs. Listen for custom events or use a message service (like Lightning Message Service) to notify the component when data changes elsewhere, then call refreshApex on the wired response property to force a re-fetch from the server. Alternatively, if using getRecord or getRelatedListRecords from LDS, set the recordIds or parameters dynamically so the wire re-executes when dependencies change.
4. Describe the lifecycle order of LWC hooks. If you need to fetch data and set up event listeners, which hooks would you use and in what order?
The lifecycle order is constructor, connectedCallback, renderedCallback, and disconnectedCallback. Use connectedCallback to fetch data via @wire or imperatively call Apex, and to attach global event listeners or initialize properties. Use renderedCallback to access the DOM after render is complete, such as focusing an input or setting up chart libraries. Use disconnectedCallback to clean up listeners and unsubscribe from streams. Avoid side effects in the constructor as it fires before the component is attached to the DOM.
5. You're building an LWC form with a custom lookup field that must validate against a Salesforce record type. The lookup should only show records of a specific type when the user types. How would you implement this?
Create an Apex method that accepts a search string and record type filter, returning matching records. In the LWC, use a handleSearchChange method that calls the Apex function imperatively via ldsUtils or a regular Apex call when the user types, then populate a dropdown list with results. Filter the results server-side in Apex using a SOQL query with a WHERE clause that checks the RecordTypeId, ensuring only valid records are returned. You can also use the lightning-combobox or a custom dropdown and debounce the search input to avoid too many server calls.
6. Explain the concept of slot usage in LWC. When would you use named slots versus unnamed slots, and what happens if a parent passes content to a slot name that doesn't exist in the child?
Unnamed (default) slots accept any child content that doesn't specify a slot attribute, while named slots target specific regions by matching the slot attribute name. Use unnamed slots for simple wrapper components and named slots when you need to compose complex layouts with multiple distinct content areas. If a parent passes content with a slot name that doesn't exist in the child component, that content will not render and will be silently ignored; this is a common source of bugs when slot names are mistyped or when components are refactored without updating parent references.
7. You're integrating a third-party JavaScript library (e.g., Chart.js) into your LWC. Describe the steps you would take to bundle and use it, and what restrictions or gotchas you might encounter.
Bundle the library as a static resource or npm package in your project, then import it in your LWC using a static resource import statement or es6 import if using npm. Initialize the library in renderedCallback after the DOM is fully rendered, and ensure the library doesn't conflict with Salesforce's Lightning locker service, which restricts access to certain browser APIs for security. Test thoroughly in your org as some third-party code may be blocked by locker, and always clean up library instances in disconnectedCallback to prevent memory leaks.
8. Your LWC receives a large list of records as a tracked property. When this list changes, the component re-renders and the user's scroll position resets to the top. How would you preserve scroll position across re-renders?
Store the current scroll position before the list updates using a getter or a separate tracked property that captures scrollTop from the container element. After the list updates and the component re-renders, use renderedCallback to restore the scroll position by setting scrollTop on the container. Alternatively, use a key binding on the list items so that the same DOM nodes persist across re-renders, which prevents the scroll reset from occurring in the first place. Be careful not to track the scroll position itself, as that would cause infinite re-renders.
9. Explain the difference between a property and an attribute in LWC. When would you make a property public, and what are the implications of using public properties versus passing data through attributes?
Properties are JavaScript class fields that are private by default, while public properties decorated with @api are exposed as component attributes that can be set by parent components or in markup. Use @api for data that a parent must pass down or configuration that changes after component creation. Public properties are evaluated as JavaScript expressions in markup, so they allow two-way binding concepts, but they're harder to debug and can cause tight coupling; attributes decorated with @api are more explicit and testable. Avoid exposing unnecessary properties publicly as it increases the component's surface area and makes refactoring harder.
10. You're debugging an LWC where a @wire function is being called multiple times unexpectedly. What are the most common causes, and how would you diagnose and fix this issue?
The most common cause is that the wire dependency list is changing on every render, triggering a re-execution; check that you're not passing computed values or new object references as dependencies. Other causes include accidentally modifying tracked properties inside the wired callback, or having multiple @wire decorators with overlapping dependencies. Diagnose by adding console.log statements in the Apex method and the wire callback to track invocations, and review your dependency arrays for unstable values. Fix by memoizing dependencies, using getters that return stable references, or converting to imperative Apex calls if the wire pattern doesn't fit your use case.
11. Design an LWC that displays a list of Contacts and allows users to edit them inline. What considerations would you need to account for regarding state management, validation, and data persistence?
Maintain two tracked properties: one for the original data and one for edited versions, so you can detect changes and enable save/cancel buttons. Validate each field as the user edits using a custom validation function that checks Salesforce field rules, and display error messages near the problematic fields. On save, call an Apex method with the modified records using the updateRecord function or a custom imperative call, handle errors gracefully, and refresh the list using refreshApex. Implement optimistic updates to improve perceived performance, but always fall back to server truth if the save fails, and provide clear feedback about which records succeeded or failed.
12. Explain Lightning Message Service (LMS) and when you would use it instead of passing data via events or component properties. Provide a scenario where LMS is the better choice.
LMS allows decoupled communication between LWC components that don't have a direct parent-child relationship, such as components in different regions of a page or in different apps. Use LMS instead of bubbling custom events when you have siblings or nested components that aren't closely coupled, as it avoids prop drilling and makes components more reusable. A good scenario is a dashboard with multiple independent LWC widgets where one widget filters data and another displays results; instead of passing the filter through a parent wrapper, the filter widget publishes a message to LMS that the result widget subscribes to, decoupling the two completely.


