Unit 6: Web Application Development and Deployment
I. Orientation: The Development-to-Deployment Lifecycle
Modern client-side web development treats a website as a software product that must be written, inspected, corrected, organised, measured, versioned and published. This unit covers the tooling and discipline surrounding that cycle: the browser as a debugging instrument, the interactive UI as the artefact, Git/GitHub as the version and delivery mechanism, and performance and best practices as the quality criteria.
Defining properties and conventions assumed throughout:
- Client-side execution: HTML, CSS and JavaScript are parsed and run inside the user's browser; there is no server process to inspect, so diagnosis happens in the browser itself.
- Single-threaded JavaScript: one call stack plus an event loop with task and microtask queues; blocking code freezes rendering and input.
- The DOM as shared state: the Document Object Model is the live tree the browser renders; all UI interactivity is DOM mutation.
- Static hosting model: GitHub Pages serves files as-is over HTTPS — no PHP, no Node runtime, no database. Anything dynamic must be client-side or an external API.
- Git's unit of work: the commit — an immutable snapshot with a parent pointer, author, timestamp and SHA-1 hash.
- Progressive enhancement and graceful degradation: core content works without JS; enhancements layer on top.
II. Diagnosing Faults in Client-Side Code
A. Debugging Techniques
Debugging is the systematic reduction of the search space between a symptom and its cause; guessing is not debugging.
- Reproduce first: fix the exact inputs, browser and steps. A bug that appears only after a form submit is a different bug from one on page load.
- Bisection (divide and conquer): comment out or disable half the suspect code; the half that still fails contains the defect.
git bisectapplies the same logic across commit history. - Print/trace debugging:
console.logwith labels, plus richer variants:
JSconsole.table(users); // array of objects as a grid console.group('cart update'); // indented, collapsible block console.time('render'); /* ... */ console.timeEnd('render'); // ms elapsed console.assert(total >= 0, 'negative total', total); - Breakpoint debugging: pause execution and inspect live scope rather than guessing values.
debugger;in source pauses when DevTools is open. - Rubber-duck and minimal reproduction: rewrite the failure as the smallest possible snippet; the act of stripping context usually exposes the cause.
- Common client-side fault classes:
undefinedfrom a mistyped property,nullfrom querying the DOM before it exists,thisrebinding in callbacks, off-by-one in loops, stale closures insidesetTimeout, and race conditions between twofetchcalls.
B. Browser Developer Tools
DevTools (F12 / Ctrl+Shift+I) is the primary instrument; each panel answers a different question.
- Elements: live DOM tree and computed CSS. Answers "why is this box the wrong size?" — check the box-model diagram and the strikethrough overridden rules in Styles.
- Console: REPL against the page. Type
$0for the currently selected element,$$('a')for a querySelectorAll shorthand. - Sources: set line breakpoints, conditional breakpoints (
i === 5), DOM-mutation and event-listener breakpoints; then Step over (F10), Step into (F11), and read the Scope and Call Stack panes. Watch expressions evaluate on every pause. - Network: each request's status, type, size, and waterfall timing. Diagnose 404s on a wrong asset path, CORS failures, and payload sizes; "Disable cache" and throttling to "Slow 3G" simulate real users.
- Performance: records a flame chart of scripting, rendering and painting; long yellow bars are long tasks (>50 ms).
- Application: localStorage, sessionStorage, cookies, service workers and cache.
- Lighthouse: audits Performance, Accessibility, Best Practices and SEO, scoring 0–100.
C. Error Handling
Error handling converts unexpected states into controlled, reportable outcomes instead of a blank screen.
try…catch…finally: guards synchronous throwing code;finallyruns regardless, for cleanup such as hiding a spinner.
JStry { const data = JSON.parse(raw); } catch (err) { console.error(err.name, err.message); // e.g. SyntaxError showMessage('Could not read saved data.'); } finally { spinner.hidden = true; }- Error objects:
name,message,stack. Built-ins includeSyntaxError,TypeError,ReferenceError,RangeError. Custom types extendError:
JSclass ValidationError extends Error { constructor(field) { super(`Invalid ${field}`); this.name = 'ValidationError'; } } - Asynchronous errors: a rejected promise is not caught by an enclosing
tryunless awaited. Use.catch()ortry/await/catch. Note thatfetchrejects only on network failure — a 404 resolves, so testresponse.okexplicitly. - Global safety nets:
window.onerror/window.addEventListener('error')for uncaught exceptions andunhandledrejectionfor orphaned promises — used to log to a monitoring service. - Fail-soft UI: validate input at the boundary, show human-readable messages next to the offending field, keep technical detail in the console, and never silently swallow with an empty
catch {}.
III. Building the Interactive Client
A. Interactive User Interface Development
Interactivity is the loop: user event → state change → DOM update → visible feedback.
- Event-driven core:
element.addEventListener('click', handler); the event object carriestarget,currentTarget,preventDefault()andstopPropagation(). - Event delegation: attach one listener to a static parent and test
e.target.closest('.item'). Essential for lists whose rows are created dynamically — one listener instead of 500. - Controlled feedback: every action needs visible acknowledgement — disabled button plus "Saving…", skeleton placeholders during
fetch, inline validation onblur. - Accessible interaction: keyboard reachability,
aria-live="polite"for status messages, focus management after opening a modal, and visible:focus-visibleoutlines. - Throttle vs debounce:
- Debounce — run once after activity stops (search-as-you-type, 300 ms).
- Throttle — run at most once per interval (scroll/resize handlers, 100 ms).
B. Client-Side Application Design
A client-side application separates what is true (state) from what is shown (view).
- Single source of truth: hold state in one object; render is a function of it.
JSlet state = { todos: [], filter: 'all' }; function setState(patch) { state = { ...state, ...patch }; render(state); } - Unidirectional data flow: events call
setState; onlyrendertouches the DOM. Removes the "who changed this element?" class of bug. - Component thinking: each UI unit owns its markup template, its handlers and its slice of state; communicates via arguments and callbacks, not globals.
- Persistence and routing:
localStorage.setItem('todos', JSON.stringify(...))for survival across reloads;history.pushStateplus ahashchange/popstatehandler for client-side routing. - Separation of concerns: data access (fetch layer) → logic (pure functions) → presentation (render). Pure functions are unit-testable without a browser.
C. Code Organization
Organisation is what keeps a working app modifiable six months later.
- File structure:
index.html,/css,/js,/assets,/data; one concern per file (api.js,ui.js,state.js,main.js). - ES modules: explicit dependencies, own scope, no globals.
HTML<script type="module" src="js/main.js"></script>
JSexport function formatPrice(n) { return `₹${n.toFixed(2)}`; } import { formatPrice } from './utils.js'; - Naming and style:
camelCasefor JS identifiers,PascalCasefor classes,kebab-casefor files and CSS classes; BEM (card__title--active) to keep CSS specificity flat. - DRY and single responsibility: extract a repeated block into a named function; a function that both fetches and renders should be split.
- Tooling: Prettier for formatting, ESLint for defect-prone patterns,
.editorconfigfor consistency, JSDoc comments explaining why rather than what.
IV. Performance
A. Website Performance Fundamentals
Performance is measured, not asserted, and is dominated by bytes transferred and main-thread work.
- Core Web Vitals: LCP (Largest Contentful Paint) ≤ 2.5 s — perceived load; INP (Interaction to Next Paint) ≤ 200 ms — responsiveness; CLS (Cumulative Layout Shift) ≤ 0.1 — visual stability.
- The critical rendering path: HTML → DOM, CSS → CSSOM, then Render Tree → Layout → Paint → Composite. CSS blocks rendering; a plain
<script>in<head>blocks parsing — usedefer(execute after parse, in order) orasync. - Reduce bytes: minify CSS/JS, gzip/Brotli compression, WebP/AVIF images with
srcset, subset fonts withfont-display: swap, tree-shake unused code. - Reduce requests and defer work: bundle small files,
loading="lazy"on below-fold images, code-split with dynamicimport(). - Avoid layout thrash: batch DOM reads then writes; reading
offsetHeightafter a write forces synchronous reflow. Animatetransform/opacityonly — they skip layout and paint. - Caching: long
Cache-Controllifetimes plus filename hashing (app.8f3a2.js) so a new deploy invalidates cleanly.
V. Version Control and Publication
A. GitHub Repository Management
A repository is the project's history plus its collaboration surface.
- Core cycle:
BASHgit init git add . git commit -m "feat: add cart total calculation" git remote add origin https://github.com/user/repo.git git push -u origin main - Branching:
git switch -c feature/cartisolates work; merge via a Pull Request so changes are reviewed and diffed before reachingmain. - Repository hygiene:
README.md(purpose, setup, live link),.gitignore(node_modules/,.env,.DS_Store),LICENSE, meaningful commit messages in the imperative mood (Conventional Commits:feat:,fix:,docs:). - Collaboration features: Issues for tracked defects, labels and milestones,
Fixes #12in a commit to auto-close, protected branches, and Actions for CI on every push.
B. Website Hosting using GitHub Pages
GitHub Pages serves static files directly from a repository over HTTPS at no cost.
- Enable: Settings → Pages → Source: Deploy from a branch → branch
main, folder/ (root)or/docs. URL becomeshttps://<user>.github.io/<repo>/. A repo named<user>.github.ioserves at the root domain. - Requirements and gotchas: an
index.htmlat the chosen root; relative asset paths (./css/style.css, not/css/style.css) because the site sits in a subpath; a.nojekyllfile to stop Jekyll ignoring folders beginning with_; propagation delay of a minute or two after each push. - Custom domains: add a
CNAMEfile and point DNS at GitHub; then enable "Enforce HTTPS". - Limitations: no server-side code, no secrets (everything is public), soft limits around 1 GB site size and 100 GB/month bandwidth — so API keys must live behind a proxy, never in the repo.
VI. Discipline and Assistance
A. Web Development Best Practices
Best practices are the defaults that prevent whole categories of defect.
- Semantic, valid HTML:
<header> <nav> <main> <article> <footer>, one<h1>,alton every meaningful image — this is also the accessibility and SEO baseline. - Responsive by default:
<meta name="viewport" content="width=device-width, initial-scale=1">, mobile-first media queries, fluid units (rem,%,clamp()), Flexbox/Grid over floats. - Security: escape user input with
textContentrather thaninnerHTMLto block XSS; HTTPS everywhere;rel="noopener noreferrer"ontarget="_blank". - Accessibility: contrast ratio ≥ 4.5:1 for body text, labels tied to inputs via
for/id, logical tab order. - Testing and cross-browser checks: verify in at least one Chromium, one Firefox and one Safari/WebKit engine; test with cache disabled and on a throttled connection.
B. Improving Web Applications using GitHub Copilot
Copilot is an AI pair programmer that suggests code inline from the surrounding context; it accelerates typing, not thinking.
- How it is driven: open files, function names, type signatures and comments form the prompt. A precise comment yields precise code:
JS// debounce fn by delay ms, cancel previous timer on each call - Productive uses: boilerplate (fetch wrappers, form validators, ARIA attributes), regex, test cases, JSDoc, converting callbacks to
async/await, and Copilot Chat for/explainon unfamiliar code or/fixon a stack trace. - Refactoring and review: ask for an extraction of duplicated logic into a helper, or a performance rewrite (delegation instead of per-row listeners), then diff the suggestion.
- Limits and responsibilities: suggestions may be subtly wrong, insecure (unescaped
innerHTML), outdated (deprecated APIs) or licence-encumbered. Every accepted line must be read, run and tested; never accept generated code that handles secrets or authentication unreviewed. - Interaction with the rest of the unit: Copilot writes candidate code, but DevTools, error handling, Lighthouse scores and Git history remain the means of verifying that the code is actually correct.
Did this save you a night before the exam?
LPU Notes is free, and it stays free. Ads cover part of the server bill. The rest comes out of a student's own pocket: the domain, the storage, and keeping the site up through the weeks everyone needs it at once.
The payment button didn't load. An ad blocker or a filtered network is the usual reason. to try again.
Nothing here is ever locked, and nothing unlocks. Chip in only if it was worth it. What it pays for →