### Install Dependencies and Start Development Server Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/README.md This snippet provides instructions for setting up the development environment. It includes cloning the repository, installing necessary Node.js packages, and starting the local development server. Prerequisites include Node.js 18.0+ and npm 8.0+. ```bash git clone https://github.com/QuocHuannn/MyPortfolio.git cd MyPortfolio npm install npm run dev # Open http://localhost:5173 ``` -------------------------------- ### Setup Sticky Header Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html Initializes and updates a sticky header element that remains visible as the user scrolls. It uses `ResizeObserver` and scroll event listeners to manage the header's position. ```javascript _setupStickyHeader(){ this.topbarEl=this._dom.find("div.lh-topbar",this._dom.rootEl), this.categoriesEl=this._dom.find("div.lh-categories",this._dom.rootEl), requestAnimationFrame(()=>requestAnimationFrame(()=>{try{ this.stickyHeaderEl=this._dom.find("div.lh-sticky-header",this._dom.rootEl) } catch{return} this.highlightEl=this._dom.createChildOf(this.stickyHeaderEl,"div","lh-highlighter"); let e=this._getScrollParent(this._dom.find(".lh-container",this._dom.rootEl)); e.addEventListener("scroll",()=>this._updateStickyHeader()); let t=e instanceof window.Document?document.documentElement:e; new window.ResizeObserver(()=>this._updateStickyHeader()).observe(t) })) } _updateStickyHeader(){ if(!this.stickyHeaderEl)return; let e=this.topbarEl.getBoundingClientRect().bottom, t=this.categoriesEl.getBoundingClientRect().top, n=e>=t, i=Array.from(this._dom.rootEl.querySelectorAll(".lh-category")).filter(h=>h.getBoundingClientRect().top-window.innerHeight/2<0), a=i.length>0?i.length-1:0, l=this.stickyHeaderEl.query } ``` -------------------------------- ### Setup Collapse Details After Printing Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html Configures the behavior of collapsible details elements before and after printing. It uses `onbeforeprint` and `afterprint` events or `matchMedia` for broader browser compatibility. ```javascript _setUpCollapseDetailsAfterPrinting(){ "onbeforeprint"in self?self.addEventListener("afterprint",this.collapseAllDetails):self.matchMedia("print").addListener(t=>{t.matches?this.expandAllDetails():this.collapseAllDetails() }) } ``` -------------------------------- ### Available npm Scripts Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/README.md This snippet lists the common npm scripts used for managing the development and build process of the React project. These scripts facilitate starting the development server, building for production, previewing the build, and performing type checking and linting. ```bash npm run dev npm run build npm run preview npm run check ``` -------------------------------- ### Get Emulation Descriptions Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html This JavaScript method provides descriptive strings for device emulation settings, including CPU throttling, network throttling, and screen emulation. It differentiates between 'provided', 'devtools', and 'simulate' throttling methods and formats the output based on device type (mobile/desktop) and emulation status. ```javascript static getEmulationDescriptions(e){ let t,n,r,i=e.throttling,a=u.i18n,l=u.strings; switch(e.throttlingMethod){ case"provided":r=n=t=l.throttlingProvided; break; case"devtools":{ let{cpuSlowdownMultiplier:p,requestLatencyMs:g}=i; t=`${a.formatNumber(p)}x slowdown (DevTools)`, n=`${a.formatMilliseconds(g)} HTTP RTT, ${a.formatKbps(i.downloadThroughputKbps)} down, ${a.formatKbps(i.uploadThroughputKbps)} up (DevTools)`, r=g===150*3.75&&i.downloadThroughputKbps===1.6*1024*.9&&i.uploadThroughputKbps===750*.9?l.runtimeSlow4g:l.runtimeCustom; break } case"simulate":{ let{cpuSlowdownMultiplier:p,rttMs:g,throughputKbps:b}=i; t=`${a.formatNumber(p)}x slowdown (Simulated)`, n=`${a.formatMilliseconds(g)} TCP RTT, ${a.formatKbps(b)} throughput (Simulated)`, r=g===150&&b===1.6*1024?l.runtimeSlow4g:l.runtimeCustom; break } default:r=t=n=l.runtimeUnknown } let s=e.channel==="devtools"?!1:e.screenEmulation.disabled, c=e.channel==="devtools"?e.formFactor==="mobile":e.screenEmulation.mobile, d=l.runtimeMobileEmulation; s?d=l.runtimeNoEmulation:c||(d=l.runtimeDesktopEmulation); let h=s?void 0:`${e.screenEmulation.width}x${e.screenEmulation.height}, DPR ${e.screenEmulation.deviceScaleFactor}`; return{deviceEmulation:d,screenEmulation:h,cpuThrottling:t,networkThrottling:n,summary:r} } ``` -------------------------------- ### Express API Server Setup (TypeScript) Source: https://context7.com/quochuannn/quochuannn.github.io/llms.txt Sets up a basic Express.js REST API server with CORS, JSON parsing, and route handling for authentication and health checks. Includes error handling and a 404 handler. Dependencies include express and cors. ```typescript import express from 'express'; import cors from 'cors'; import authRoutes from './routes/auth.js'; const app = express(); app.use(cors()); app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true, limit: '10mb' })); // Routes app.use('/api/auth', authRoutes); // Health check endpoint app.use('/api/health', (req, res) => { res.status(200).json({ success: true, message: 'ok' }); }); // Error handler app.use((error, req, res, next) => { res.status(500).json({ success: false, error: 'Server internal error' }); }); // 404 handler app.use((req, res) => { res.status(404).json({ success: false, error: 'API not found' }); }); export default app; ``` -------------------------------- ### Bash: Common npm Development Scripts Source: https://context7.com/quochuannn/quochuannn.github.io/llms.txt Provides a set of common npm scripts for managing the development workflow of a Node.js project. These scripts cover dependency installation, starting development servers (frontend, backend, or both), code type checking, linting, testing (including watch mode and coverage), building for production, previewing the production build, and cleaning build artifacts. ```bash # Install dependencies npm install # Start development server (frontend only) npm run client:dev # Start API server (backend only) npm run server:dev # Start both frontend and backend concurrently npm run dev # Type check without emitting files npm run check # Lint code npm run lint # Fix linting issues npm run lint:fix # Run tests npm run test # Run tests in watch mode npm run test:watch # Run tests with coverage npm run test:coverage # Build for production (includes type checking) npm run build # Build with bundle analysis npm run build:analyze # Preview production build npm run preview # Clean build artifacts npm run clean ``` -------------------------------- ### Render Screenshot Overlay - JavaScript Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html Installs an overlay feature for full-page screenshots, enabling interactive elements or highlighting on the screenshot. It adds a CSS class to the root element and sets a CSS variable for the screenshot URL. ```javascript static installOverlayFeature(e){let{dom:t,rootEl:n,overlayContainerEl:r,fullPageScreenshot:i}=e,a="lh-screenshot-overlay--enabled";n.classList.contains(a)||(n.classList.add(a),n.addEventListener("click",l=>{let s=l ``` -------------------------------- ### Render Lighthouse Report UI Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html Renders the complete Lighthouse report UI within a specified DOM element. It prepares the report data, creates necessary DOM elements for headers, scores, warnings, and footers, and applies CSS classes for layout and responsiveness. It also handles initial setup and configuration of the report rendering. ```javascript var re=class{ constructor(e){ this._dom=e, this._opts={} } renderReport(e,t,n){ if(!this._dom.rootEl&&t){ console.warn("Please adopt the new report API in renderer/api.js."); let i=t.closest(".lh-root"); i?this._dom.rootEl=i:(t.classList.add("lh-root","lh-vars"),this._dom.rootEl=t) }else this._dom.rootEl&&t&&(this._dom.rootEl=t); n&&(this._opts=n), this._dom.setLighthouseChannel(e.configSettings.channel||"unknown"); let r=k.prepareReportResult(e); return this._dom.rootEl.textContent="", this._dom.rootEl.append(this._renderReport(r)), this._opts.occupyEntireViewport&&this._dom.rootEl.classList.add("lh-max-viewport"), this._dom.rootEl } _renderReportTopbar(e){ let t=this._dom.createComponent("topbar"), n=this._dom.find("a.lh-topbar__url",t); return n.textContent=e.finalDisplayedUrl, n.title=e.finalDisplayedUrl, this._dom.safelySetHref(n,e.finalDisplayedUrl), t } _renderReportHeader(){ let e=this._dom.createComponent("heading"), t=this._dom.createComponent("scoresWrapper"); return this._dom.find(".lh-scores-wrapper-placeholder",e).replaceWith(t), e } _renderReportFooter(e){ let t=this._dom.createComponent("footer"); return this._renderMetaBlock(e,t), this._dom.find(".lh-footer__version_issue",t).textContent=u.strings.footerIssue, this._dom.find(".lh-footer__version",t).textContent=e.lighthouseVersion, t } _renderMetaBlock(e,t){ let n=k.getEmulationDescriptions(e.configSettings||"{}"), r=e.userAgent.match(/(\w*Chrome/[\d.]+)/), i=Array.isArray(r)?r[1].replace("/", " ").replace("Chrome", "Chromium"): "Chromium", a=e.configSettings.channel, l=e.environment.benchmarkIndex.toFixed(0), s=e.environment.credits?.["axe-core"], c=[ `${u.strings.runtimeSettingsBenchmark}: ${l}`, `${u.strings.runtimeSettingsCPUThrottling}: ${n.cpuThrottling}` ]; n.screenEmulation&&c.push( `${u.strings.runtimeSettingsScreenEmulation}: ${n.screenEmulation}` ), s&&c.push(`${u.strings.runtimeSettingsAxeVersion}: ${s}`); let d=u.strings.runtimeAnalysisWindow; e.gatherMode==="timespan"?d=u.strings.runtimeAnalysisWindowTimespan: e.gatherMode==="snapshot"&&(d=u.strings.runtimeAnalysisWindowSnapshot); let h=[ ["date", `Captured at ${u.i18n.formatDateTime(e.fetchTime)}`], ["devices", `${n.deviceEmulation} with Lighthouse ${e.lighthouseVersion}`, c.join(" ")], ["samples-one", u.strings.runtimeSingleLoad, u.strings.runtimeSingleLoadTooltip], ["stopwatch", d], ["networkspeed", `${n.summary}`, `${u.strings.runtimeSettingsNetworkThrottling}: ${n.networkThrottling}`], ["chrome", `Using ${i}` + (a ? ` with ${a}` : ""), `${u.strings.runtimeSettingsUANetwork}: "${e.environment.networkUserAgent}"`] ], p=this._dom.find(".lh-meta__items",t); for(let[g,b,_]of h){ let m=this._dom.createChildOf(p, "li", "lh-meta__item"); m.textContent=b, _&&(m.classList.add("lh-tooltip-boundary"), let w=this._dom.createChildOf(m,"div","lh-tooltip"); w.textContent=_) m.classList.add("lh-report-icon", `lh-report-icon--${g}`) } } _renderReportWarnings(e){ if(!e.runWarnings||e.runWarnings.length===0)return this._dom.createElement("div"); let t=this._dom.createComponent("warningsToplevel"), n=this._dom.find(".lh-warnings__msg",t); n.textContent=u.strings.toplevelWarningsMessage; let r=[] for(let i of e.runWarnings){ let a=this._dom.createElement("li"); a.append(this._dom.convertMarkdownLinkSnippets(i)), r.push(a) } return this._dom.find("ul",t).append(...r),t } _renderScoreGauges(e,t,n){ let r=[], i=[] for(let a of Object.values(e.categories)){ let s=(n[a.id]||t).renderCategoryScore(a,e.categoryGroups||"{}",{gatherMode:e.gatherMode}), c=this._dom.find("a.lh-gauge__wrapper, a.lh-fraction__wrapper",s); c&&( this._dom.safelySetHref(c,`#${a.id}`), c.addEventListener("click",d=>{ if(!c.matches('a[href^="#"]'))return; let h=c.getAttribute("href"), p=this._dom.rootEl; if(!h||!p)return; let g=this._dom.find(h,p); d.preventDefault(),g.scrollIntoView() }), this._opts.onPageAnchorRendered?.(c) ), k.isPluginCategory(a.id)?i.push(s):r.push(s) } return [...r,...i] } _renderReport(e){ u.apply({providedStrings:e.i18n.rendererFormattedStrings,i18n:new te(e.configSettings.locale),reportJson:e}); let t=new X(this._dom,{fullPageScreenshot:e.fullPageScreenshot??void 0,entities:e.entities}), n=new G(this._dom,t), r={performance:new ne(this._dom,t)}, i=this._dom.createElement("div"); i.append(this._renderReportHeader()); let a=this._dom.createElement("div","lh-container"), l=this._dom.createElement("div","lh-report"); l.append(this._renderReportWarnings(e)); let s; Object.keys(e.categories).length===1?i.classList.add("lh-header--solo-category"): s=this._dom.createElement("div","lh-scores-header"); let d=this._dom.createElement("div"); d.classList.add("lh-scorescale-wrap"), d.append(this._dom.createComponent("scorescale")); if(s){ let b=this._dom.find(".lh-scores-container",i); s.append(...this._renderScoreGauges(e,n,r)), b.append(s,d); let _=this._dom.createElement("div","lh-sticky-header"); _.append(...this._renderScoreGauges(e,n,r)), a.append(_) } let h=this._dom.createElement("div") // ... rest of the _renderReport method } } ``` -------------------------------- ### Theme Storage API (TypeScript) Source: https://context7.com/quochuannn/quochuannn.github.io/llms.txt Provides utilities for managing and persisting theme preferences using localStorage or sessionStorage. Includes functions to get, set, update, subscribe to changes, import/export preferences as JSON, and monitor storage usage. Requires custom theme storage utility functions. ```typescript import { themeStorage, getThemePreferences, setThemePreferences } from './utils/themeStorage'; // Get current preferences const preferences = getThemePreferences(); console.log(preferences); // Output: { theme: 'light', animationsEnabled: true, transitionDuration: 300, ... } // Update specific preference themeStorage.updatePreference('theme', 'dark'); themeStorage.updatePreference('animationsEnabled', false); // Set multiple preferences at once setThemePreferences({ theme: 'dark', reducedMotion: true, fontSize: 'large', highContrast: true }); // Subscribe to preference changes const unsubscribe = themeStorage.subscribe((prefs) => { console.log('Preferences updated:', prefs); // React to changes from other tabs or components }); // Export preferences as JSON const json = themeStorage.exportPreferences(); console.log(json); // Import preferences from JSON const success = themeStorage.importPreferences(jsonString); // Check storage usage const info = themeStorage.getStorageInfo(); console.log(`Using ${info.percentage.toFixed(2)}% of available storage`); // Cleanup unsubscribe(); themeStorage.destroy(); ``` -------------------------------- ### Run Development and Checks (Bash) Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/docs/testing-documentation.md This snippet shows commands to run TypeScript checks and the development server using npm scripts. It also includes a placeholder for future automated test runner integration. ```bash # Run TypeScript checks npm run check # Run development server npm run dev # Access test routes programmatically # (Future enhancement: automated test runner) ``` -------------------------------- ### JavaScript Function to Check for Plugin Category Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html A simple JavaScript utility function to determine if a given string represents a Lighthouse plugin category by checking if it starts with 'lighthouse-plugin-'. ```javascript static isPluginCategory(e){return e.startsWith("lighthouse-plugin-")} ``` -------------------------------- ### Initialize Lighthouse Report Rendering Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html This function initializes the Lighthouse report rendering process. It takes Lighthouse JSON data, creates the report's DOM, and initializes various features. It also sets up event listeners for analytics and logging. ```javascript function Ie(o,e={}){let t=document.createElement("article");t.classList.add("lh-root","lh-vars");let n=new ee(t.ownerDocument,t),r=new re(n);return e._onSwapHook&&(n._onSwapHook=e._onSwapHook),r.renderReport(o,t,e),new ae(n,e).initFeatures(o),t} var le=class{ constructor(e){this.el=e;let t=document.createElement("style");if(t.textContent=` #lh-log { position: fixed; background-color: #323232; color: #fff; min-height: 48px; min-width: 288px; padding: 16px 24px; box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); border-radius: 2px; margin: 12px; font-size: 14px; cursor: default; transition: transform 0.3s, opacity 0.3s; transform: translateY(100px); opacity: 0; bottom: 0; left: 0; z-index: 3; display: flex; flex-direction: row; justify-content: center; align-items: center; } #lh-log.lh-show { opacity: 1; transform: translateY(0); } `,!this.el.parentNode)throw new Error("element needs to be in the DOM");this.el.parentNode.insertBefore(t,this.el),this._id=void 0} log(e,t=!0){this._id&&clearTimeout(this._id),this.el.textContent=e,this.el.classList.add("lh-show"),t&&(this._id=setTimeout(()=>{this.el.classList.remove("lh-show")},7e3))} warn(e){this.log("Warning: "+e)} error(e){this.log(e),setTimeout(()=>{throw new Error(e)},0)} hide(){this._id&&clearTimeout(this._id),this.el.classList.remove("lh-show")}} function At(){ let o=window.__LIGHTHOUSE_JSON__, e=Ie(o,{occupyEntireViewport:!0,getStandaloneReportHTML(){return document.documentElement.outerHTML}}); document.body.append(e), document.addEventListener("lh-analytics",t=>{ let n=t; "gtag"in window&&window.gtag("event",n.detail.name,n.detail.data??{}) }), document.addEventListener("lh-log",t=>{ let n=document.querySelector("div#lh-log"); if(!n)return; let r=new le(n), i=t.detail; switch(i.cmd){ case"log":r.log(i.msg);break; case"warn":r.warn(i.msg);break; case"error":r.error(i.msg);break; case"hide":r.hide();break; } }) } window.__initLighthouseReport__=At; })(); __initLighthouseReport__(); //# sourceURL=compiled-reportrenderer.js console.log('window.__LIGHTHOUSE_JSON__', __LIGHTHOUSE_JSON__); ``` -------------------------------- ### Health Check Endpoint (Bash) Source: https://context7.com/quochuannn/quochuannn.github.io/llms.txt Demonstrates how to perform a health check on a running API server using curl. It sends a GET request to the /api/health endpoint and expects a JSON response indicating the server's status. ```bash curl http://localhost:3001/api/health # Response { "success": true, "message": "ok" } ``` -------------------------------- ### Project Structure Overview Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/README.md This snippet outlines the typical project directory structure for a React application using Vite and TypeScript. It highlights key folders like `src` for components and types, `api` for backend routes, and configuration files. ```tree 📦 Portfolio/ ├── 📁 src/ │ ├── 📁 components/ # React components │ ├── 📁 data/ # Content and mock data │ ├── 📁 hooks/ # Custom React hooks │ ├── 📁 types/ # TypeScript definitions │ └── 📄 App.tsx # Main app component ├── 📁 api/ # Backend API routes ├── 📁 public/ # Static assets └── ⚙️ Config files # Vite, TypeScript, Tailwind ``` -------------------------------- ### Theme Management System Source: https://context7.com/quochuannn/quochuannn.github.io/llms.txt An advanced theme system that allows for persistence, smooth transitions, and management of user preferences, including light/dark mode and reduced motion settings. ```APIDOC ## Theme Management System ### Description An advanced theme system that allows for persistence, smooth transitions, and management of user preferences, including light/dark mode and reduced motion settings. ### Method N/A (Component/Hook Usage) ### Endpoint N/A (Component/Hook Usage) ### Parameters #### ThemeProvider Props - **defaultTheme** (string) - The default theme to apply if no preference is found. - **enableAdvancedFeatures** (boolean) - Enables additional theme customization features. - **enableThemeTransitions** (boolean) - Enables smooth transitions between themes. - **enablePresets** (boolean) - Enables pre-defined theme presets. - **autoSyncPreferences** (boolean) - Automatically synchronizes theme preferences across tabs/windows. ### Request Example ```typescript import { ThemeProvider } from './theme/optimized'; function App() { return ( ); } ``` ### Response #### useTheme Hook Return Values - **theme** (string) - The currently active theme name (e.g., 'light', 'dark'). - **actualTheme** (string) - The theme that is actually applied, considering system preferences. - **prefersReducedMotion** (boolean) - Indicates if the user's system preference for reduced motion is active. - **setTheme** (function) - Function to set the theme to a specific value. - **toggleTheme** (function) - Function to toggle between available themes. #### Response Example ```typescript import { useTheme } from './hooks/useTheme'; function MyComponent() { const { theme, actualTheme, prefersReducedMotion, setTheme, toggleTheme } = useTheme(); return ( ); } ``` ``` -------------------------------- ### Get URL Locator Function Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html This JavaScript function determines and returns a function that can extract a URL from audit result items. It prioritizes 'url' value types and falls back to 'source-location' types if available. The returned function handles parsing and extracting the origin from the URL. ```javascript static getUrlLocatorFn(e){ let t=e.find(r=>r.valueType==="url")?.key; if(t&&typeof t=="string") return r=>{ let i=r[t]; if(typeof i=="string") return i }; let n=e.find(r=>r.valueType==="source-location")?.key; if(n) return r=>{ let i=r[n]; if(typeof i=="object"&&i.type==="source-location") return i.url } } ``` -------------------------------- ### Tooltip Styling and Animations (CSS) Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html Defines styles for tooltips, including their appearance, positioning, and fade-in animation. It uses container queries to adjust tooltip width and ensures tooltips are displayed correctly on narrow screens. The animation `fadeInTooltip` controls the opacity transition for tooltips. ```css .lh-tooltip-boundary:hover .lh-tooltip { display: block; animation: fadeInTooltip 250ms; animation-fill-mode: forwards; animation-delay: 850ms; bottom: 100%; z-index: 1; will-change: opacity; right: 0; pointer-events: none; } .lh-tooltip::before { content: ""; border: solid transparent; border-bottom-color: #fff; border-width: 10px; position: absolute; bottom: -20px; right: 6px; transform: rotate(180deg); pointer-events: none; } @keyframes fadeInTooltip { 0% { opacity: 0; } 75% { opacity: 1; } 100% { opacity: 1; filter: drop-shadow(1px 0px 1px #aaa) drop-shadow(0px 2px 4px hsla(206, 6%, 25%, 0.15)); pointer-events: auto; } } ``` -------------------------------- ### Render Text URL (JavaScript) Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html Renders a URL string as a clickable link with optional host information. It parses the URL to extract the file path and hostname. If the hostname is present, it's displayed in parentheses. The link is created using the _renderLink utility. This is used for displaying resource URLs. ```JavaScript renderTextURL(e) { let t = e, n, r, i; try { let l = E.parseURL(t); n = l.file === "" ? l.origin : l.file; r = l.file === "" || l.hostname === "" ? "" : `(${l.hostname})`; i = t; } catch { n = t; } let a = this._dom.createElement("div", "lh-text__url"); if (a.append(this._renderLink({text: n, url: t})), r) { let l = this._renderText(r); l.classList.add("lh-text__url-host"), a.append(l); } return i && (a.title = t, a.dataset.url = t), a; } ``` -------------------------------- ### Get Entity Group Items in JavaScript Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html Processes items to be grouped by entity. It aggregates values for specified columns across items belonging to the same entity. It handles summing numeric values and prepares the data for rendering grouped rows. The function can sort the resulting items based on a provided criteria. ```javascript this._getEntityGroupItems(e) { let {items: t, headings: n, sortedBy: r} = e; if (!t.length || e.isEntityGrouped || !t.some(d => d.entity)) return []; let i = new Set(e.skipSumming || []); let a = []; for (let d of n) !d.key || i.has(d.key) || vt.includes(d.valueType) && a.push(d.key); let l = n[0].key; if (!l) return []; let s = new Map; for (let d of t) { let h = typeof d.entity == "string" ? d.entity : void 0, p = s.get(h) || {[l]: h || u.strings.unattributable,entity: h}; for (let g of a) p[g] = Number(p[g] || 0) + Number(d[g] || 0); s.set(h, p); } let c = [...s.values()]; return r && c.sort(k.getTableItemSortComparator(r)), c; } ``` -------------------------------- ### Optimize Responsive Images with Modern Formats (TypeScript) Source: https://context7.com/quochuannn/quochuannn.github.io/llms.txt Implements responsive image solutions by generating `srcset` and `sizes` attributes for optimal image loading. It supports modern image formats like AVIF and WebP, and integrates with a `LazyImage` component for lazy loading. The utilities help in determining the best image format and dimensions based on the viewport and device capabilities. ```typescript import { generateSrcSet, generateSizes, getOptimalFormat } from './utils/imageOptimization'; import LazyImage from './components/ui/LazyImage'; // Generate responsive srcset const srcSet = generateSrcSet('/images/hero.jpg', [320, 640, 768, 1024, 1280]); // Output: "/images/hero-320w.jpg 320w, /images/hero-640w.jpg 640w, ..." // Generate sizes attribute const sizes = generateSizes({ '(max-width: 640px)': '100vw', '(max-width: 1024px)': '50vw', 'default': '33vw' }); // Output: "(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw" // Get optimal image format const format = getOptimalFormat(); console.log(format); // 'avif', 'webp', or 'jpg' // Use LazyImage component function Gallery() { return ( ); } ``` -------------------------------- ### TypeScript: Configure Vite for Production Builds Source: https://context7.com/quochuannn/quochuannn.github.io/llms.txt Configures Vite for optimized production builds, including code splitting, target specification, and minification. It integrates plugins like React, tsconfig-paths, and a bundle visualizer for analyzing build output. The configuration defines manual chunks for common libraries like React and framer-motion to improve loading performance. ```typescript // vite.config.ts import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import tsconfigPaths from 'vite-tsconfig-paths'; import { visualizer } from 'rollup-plugin-visualizer'; export default defineConfig(({ mode }) => ({ base: '/', plugins: [ react(), tsconfigPaths(), ...(mode === 'analyze' ? [ visualizer({ filename: 'dist/bundle-analysis.html', open: true, gzipSize: true, brotliSize: true }) ] : []) ], build: { target: 'es2020', minify: 'esbuild', rollupOptions: { output: { manualChunks: (id) => { if (id.includes('node_modules')) { if (id.includes('react')) return 'react-vendor'; if (id.includes('framer-motion')) return 'motion'; if (id.includes('three')) return 'three'; return 'vendor'; } } } }, chunkSizeWarningLimit: 1000, cssCodeSplit: false, assetsInlineLimit: 4096 }, optimizeDeps: { include: ['react', 'react-dom', 'react-router-dom', 'framer-motion', 'three'] }, server: { port: 3000, open: true, cors: true } })); ``` -------------------------------- ### Get Table Item Sort Comparator Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html This function generates a comparator for sorting table items based on specified keys. It supports sorting by numbers and strings, handling different data types and providing warnings for unsupported types. The sorting is done in descending order for numbers and ascending for strings. ```javascript static getTableItemSortComparator(e){ return(t,n)=>{ for(let r of e){ let i=t[r],a=n[r]; if((typeof i!=typeof a||!["number","string"].includes(typeof i))&&console.warn(`Warning: Attempting to sort unsupported value type: ${r}.`),typeof i=="number"&&typeof a=="number"&&i!==a) return a-i; if(typeof i=="string"&&typeof a=="string"&&i!==a) return i.localeCompare(a) } return 0 } } ``` -------------------------------- ### Responsive Styles for Lighthouse Metrics (CSS) Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html Applies responsive styles to Lighthouse metrics container and individual metrics for narrow viewports. It adjusts layout for smaller screens, ensuring readability and proper alignment. Uses both media queries and container queries for compatibility. ```css /* TODO: remove this media query when `@container query` is fully supported by browsers */ @media screen and (max-width: 535px) { .lh-metrics-container { display: block; } .lh-metric { border-bottom: none !important; } .lh-category:not(.lh--hoisted-meta) .lh-metric:nth-last-child(1) { border-bottom: 1px solid var(--report-border-color-secondary) !important; } /* Change the grid to 3 columns for narrow viewport. */ .lh-metric__innerwrap { /* Icon -- Metric Name -- Metric Value */ grid-template-columns: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right)) 2fr 1fr; } .lh-metric__value { justify-self: end; grid-column-start: unset; } } @container lh-container (max-width: 535px) { .lh-metrics-container { display: block; } .lh-metric { border-bottom: none !important; } .lh-category:not(.lh--hoisted-meta) .lh-metric:nth-last-child(1) { border-bottom: 1px solid var(--report-border-color-secondary) !important; } /* Change the grid to 3 columns for narrow viewport. */ .lh-metric__innerwrap { /* Icon -- Metric Name -- Metric Value */ grid-template-columns: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right)) 2fr 1fr; } .lh-metric__value { justify-self: end; grid-column-start: unset; } } ``` -------------------------------- ### Lighthouse Tools Container Creation Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html JavaScript code for creating the container element for various Lighthouse tools. It assigns the 'lh-tools' class for styling purposes. ```javascript let c = o.createElement("div", "lh-tools"); ``` -------------------------------- ### Create Top-Level Warning Component Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html This snippet creates a top-level warning component with a message and a list. This component uses the `o` object (likely the document) to create the necessary DOM elements. It returns a document fragment containing the created elements. ```javascript function gt(o){let e=o.createFragment(),t=o.createElement("div","lh-warnings lh-warnings--toplevel"),n=o.createElement("p","lh-warnings__msg"),r=o.createElement("ul");return t.append(" ",n," ",r," "),e.append(t),e} ``` -------------------------------- ### Lighthouse Metric Rendering and Scoring Source: https://github.com/quochuannn/quochuannn.github.io/blob/main/lighthouse-performance.html This JavaScript class `ne` extends a base class `G` and handles the rendering of Lighthouse performance metrics. It includes methods for calculating ratings based on scores, constructing URLs for scoring calculators, and calculating the overall impact of metric savings. It interacts with `window.localStorage` for state persistence. ```javascript var Ae="__lh__insights_audits_toggle_state_2",ne=class extends G{ _memoryInsightToggleState="DEFAULT"; _renderMetric(e){ let t=this.dom.createComponent("metric"), n=this.dom.find(".lh-metric",t); n.id=e.result.id; let r=k.calculateRating(e.result.score,e.result.scoreDisplayMode); n.classList.add(`lh-metric--${r}`); let i=this.dom.find(".lh-metric__title",t); i.textContent=e.result.title; let a=this.dom.find(".lh-metric__value",t); a.textContent=e.result.displayValue||""; let l=this.dom.find(".lh-metric__description",t); if(l.append(this.dom.convertMarkdownLinkSnippets(e.result.description)),e.result.scoreDisplayMode==="error"){ l.textContent="", a.textContent="Error!"; let s=this.dom.createChildOf(l,"span"); s.textContent=e.result.errorMessage||"Report error: no metric information" }else e.result.scoreDisplayMode==="notApplicable"&& (a.textContent="--") return n } _getScoringCalculatorHref(e){ let t=e.filter(h=>h.group==="metrics"), n=e.find(h=>h.id==="interactive"), r=e.find(h=>h.id==="first-cpu-idle"), i=e.find(h=>h.id==="first-meaningful-paint"); n&&t.push(n), r&&t.push(r), i&&typeof i.result.score==="number"&& t.push(i); let a=h=>Math.round(h*100)/100, s=[...t.map(h=>{ let p; return typeof h.result.numericValue==="number"?(p=h.id==="cumulative-layout-shift"?a(h.result.numericValue):Math.round(h.result.numericValue),p=p.toString()):p="null",[h.acronym||h.id,p] })] u.reportJson&&(s.push(["device",u.reportJson.configSettings.formFactor]), s.push(["version",u.reportJson.lighthouseVersion])); let c=new URLSearchParams(s), d=new URL("https://googlechrome.github.io/lighthouse/scorecalc/"); return d.hash=c.toString(), d.href } overallImpact(e,t){ if(!e.result.metricSavings)return{overallImpact:0,overallLinearImpact:0}; let n=0, r=0; for(let[i,a]of Object.entries(e.result.metricSavings)){ if(a===void 0)continue; let l=t.find(g=>g.acronym===i); if(!l||l.result.score===null)continue; let s=l.result.numericValue; if(!s)continue; let c=a/s*l.weight; r+=c; let d=l.result.scoringOptions; if(!d)continue; let p=(E.computeLogNormalScore(d,s-a)-l.result.score)*l.weight; n+=p } return{overallImpact:n,overallLinearImpact:r} } _persistInsightToggleToStorage(e){ try{ window.localStorage.setItem(Ae,e) }finally{ this._memoryInsightToggleState=e } } _getInsightToggleState(){ let e=this._getRawInsightToggleState(); return e==="DEFAULT"&&(e="INSIGHTS"), e } _getRawInsightToggleState(){ try{ let e=window.localStorage.getItem(Ae); if(e==="AUDITS"||e==="INSIGHTS")return e }catch{ return this._memoryInsightToggleState } return"DEFAULT" } _setInsightToggleButtonText(e){ let t=this._getInsightToggleState(); e.innerText=t==="AUDITS"?u.strings.tryInsights:u.strings.goBackToAudits } _renderInsightsToggle(e){ let t=this.dom.createChildOf(e,"div","lh-perf-insights-toggle"), n=this.dom.createChildOf(t,"span","lh-perf-toggle-text"), r=this.dom.createElement("span","lh-perf-insights-icon insights-icon-url"); n.appendChild(r), n.appendChild(this.dom.convertMarkdownLinkSnippets(u.strings.insightsNotice)); let a=this.dom.createChildOf(t,"button","lh-button lh-button-insight-toggle"); this._setInsightToggleButtonText(a), a.addEventListener("click",l=>{ l.preventDefault(); let s=this.dom.maybeFind(".lh-perf-audits--swappable"); s&& this.dom.swapSectionIfPossible(s); let d=this._getInsightToggleState()==="AUDITS"?"INSIGHTS":"AUDITS"; this.dom.fireEventOn("lh-analytics",this.dom.document(),{name:"toggle_insights",data:{newState:d}}), this._persistInsightToggleToStorage(d), this._setInsightToggleButtonText(a) }), t.appendChild(a) } render(e,t,n){ let r=u.strings, i=this.dom.createElement("div","lh-category"); i.id=e.id, i.append(this.renderCategoryHeader(e,t,n)); let a=e.auditRefs.filter(g=>g.group==="metrics"); if(a.length){ let[g,b]=this.renderAuditGroup(t.metrics), _=this.dom.createElement("input","lh-metrics-toggle__input"), m=`lh-metrics-toggle${u.getUniqueSuffix()}`; _.setAttribute("aria-label","Toggle the display of metric descriptions"), _.type="checkbox", _.id=m, g.prepend(_); let w=this.dom.find(".lh-audit-group__header",g), f=this.dom.crea ```