From b20102785abf8e74ab117f41e0dc5454ee6211a6 Mon Sep 17 00:00:00 2001 From: LD-Reborn Date: Thu, 1 Jan 2026 14:57:37 +0100 Subject: [PATCH] Added CriticalCSS, defered CSS and JS, fixed heading order, fixed front-end querycache url, added response compression and caching --- .gitignore | 2 + .../Controllers/Frontend/HomeController.cs | 8 +- src/Server/CriticalCSS/Account.Login.css | 1 + .../CriticalCSS/CriticalCSSGenerator.js | 129 ++++++++++++++++++ src/Server/CriticalCSS/Home.Index.css | 1 + src/Server/CriticalCSS/Home.Searchdomains.css | 1 + src/Server/CriticalCSS/README.md | 10 ++ src/Server/Program.cs | 39 +++++- src/Server/Views/Home/Index.cshtml | 95 +++++++------ src/Server/Views/Home/Searchdomains.cshtml | 10 +- src/Server/Views/Shared/_Layout.cshtml | 40 ++++-- src/Server/wwwroot/css/site.css | 26 ++++ .../wwwroot/fonts/bootstrap-icons.woff2 | Bin 0 -> 130608 bytes 13 files changed, 307 insertions(+), 55 deletions(-) create mode 100644 src/Server/CriticalCSS/Account.Login.css create mode 100644 src/Server/CriticalCSS/CriticalCSSGenerator.js create mode 100644 src/Server/CriticalCSS/Home.Index.css create mode 100644 src/Server/CriticalCSS/Home.Searchdomains.css create mode 100644 src/Server/CriticalCSS/README.md create mode 100644 src/Server/wwwroot/fonts/bootstrap-icons.woff2 diff --git a/.gitignore b/.gitignore index 45efc47..b5f7b8e 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,5 @@ src/Server/logs src/Shared/bin src/Shared/obj src/Server/wwwroot/logs/* +src/Server/CriticalCSS/node_modules +src/Server/CriticalCSS/package*.json diff --git a/src/Server/Controllers/Frontend/HomeController.cs b/src/Server/Controllers/Frontend/HomeController.cs index 9a6c732..a54bd56 100644 --- a/src/Server/Controllers/Frontend/HomeController.cs +++ b/src/Server/Controllers/Frontend/HomeController.cs @@ -20,8 +20,14 @@ public class HomeController : Controller _domainManager = domainManager; } - [Authorize] [HttpGet("/")] + public IActionResult Root() + { + return Redirect("/Home/Index"); + } + + [Authorize] + [HttpGet("Index")] public IActionResult Index() { return View(); diff --git a/src/Server/CriticalCSS/Account.Login.css b/src/Server/CriticalCSS/Account.Login.css new file mode 100644 index 0000000..f0290d7 --- /dev/null +++ b/src/Server/CriticalCSS/Account.Login.css @@ -0,0 +1 @@ +@charset "UTF-8";.align-items-center{align-items:center!important}.mb-2{margin-bottom:.5rem!important}@media (min-width:1200px){h2{font-size:2rem}h3{font-size:1.75rem}.fs-3{font-size:1.75rem!important}}.btn{display:inline-block;font-weight:400;line-height:1.5;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;border-radius:.25rem}.mb-0{margin-bottom:0!important}.overflow-auto{overflow:auto!important}.text-nowrap{white-space:nowrap!important}@media (min-width:768px){.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-6{flex:0 0 auto;width:50%}.col-md-8{flex:0 0 auto;width:66.66666667%}}h1,h2,h3{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}@media (min-width:1200px){h3{font-size:1.75rem}.fs-3{font-size:1.75rem!important}h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:576px){.container{max-width:540px}}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}@media (min-width:768px){.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-6{flex:0 0 auto;width:50%}.col-md-8{flex:0 0 auto;width:66.66666667%}}.p-2{padding:.5rem!important}@media (min-width:1200px){h3{font-size:1.75rem}.fs-3{font-size:1.75rem!important}}.btn-warning{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-sm{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (min-width:768px){.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-6{flex:0 0 auto;width:50%}}.h-100{height:100%!important}.badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item{position:relative;display:block;padding:.5rem 1rem;color:#212529;text-decoration:none;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush{border-radius:0}@media (min-width:576px){.container{max-width:540px}.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.mt-3{margin-top:1rem!important}@media (min-width:576px){.d-sm-inline-flex{display:inline-flex!important}}.progress{display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.mt-2{margin-top:.5rem!important}h1,h2{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h2{font-size:calc(1.325rem + .9vw)}p{margin-top:0;margin-bottom:1rem}.fs-3{font-size:calc(1.3rem + .6vw)!important}@media (min-width:1200px){h2{font-size:2rem}.fs-3{font-size:1.75rem!important}}.visually-hidden{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.mb-4{margin-bottom:1.5rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(var(--bs-gutter-y) * -1);margin-right:calc(var(--bs-gutter-x) * -.5);margin-left:calc(var(--bs-gutter-x) * -.5)}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.d-sm-inline-flex{display:inline-flex!important}.container{max-width:540px}}.g-4{--bs-gutter-x:1.5rem}.g-4{--bs-gutter-y:1.5rem}@media (min-width:768px){.col-md-6{flex:0 0 auto;width:50%}}.d-flex{display:flex!important}.fs-5{font-size:1.25rem!important}.card-title{margin-bottom:.5rem}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}@media (min-width:576px){.container{max-width:540px}.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.d-sm-inline-flex{display:inline-flex!important}}.card-body{flex:1 1 auto;padding:1rem}@media (min-width:576px){.container{max-width:540px}.d-sm-inline-flex{display:inline-flex!important}.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-rgb:33,37,41;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%}h1{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}ul{padding-left:2rem}ul{margin-top:0;margin-bottom:1rem}a{color:#0d6efd;text-decoration:underline}label{display:inline-block}button{border-radius:0}button,input{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button{text-transform:none}[type=button],[type=submit],button{-webkit-appearance:button}::-moz-focus-inner{padding:0;border-style:none}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}.container,.container-fluid{width:100%;padding-right:var(--bs-gutter-x,.75rem);padding-left:var(--bs-gutter-x,.75rem);margin-right:auto;margin-left:auto}@media (min-width:576px){.d-sm-inline-flex{display:inline-flex!important}.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}@media (min-width:1400px){.container{max-width:1320px}}.form-label{margin-bottom:.5rem}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.25rem}.form-control:focus{color:#212529;background-color:#fff;border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0}.btn-primary{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.collapse:not(.show){display:none}.nav-link{display:block;padding:.5rem 1rem;color:#0d6efd;text-decoration:none}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:.5rem;padding-bottom:.5rem}.navbar>.container-fluid{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.d-sm-inline-flex{display:inline-flex!important}}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.55)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.55);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.border-top{border-top:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.w-100{width:100%!important}.flex-grow-1{flex-grow:1!important}.justify-content-between{justify-content:space-between!important}.mt-4{margin-top:1.5rem!important}.mb-3{margin-bottom:1rem!important}.pb-3{padding-bottom:1rem!important}.text-center{text-align:center!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:#6c757d!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}html{font-size:14px}@media (min-width:768px){html{font-size:16px}}.form-control:focus{box-shadow:0 0 0 .1rem #fff,0 0 0 .25rem #258cfb}html{position:relative;min-height:100%}body{margin-bottom:60px} \ No newline at end of file diff --git a/src/Server/CriticalCSS/CriticalCSSGenerator.js b/src/Server/CriticalCSS/CriticalCSSGenerator.js new file mode 100644 index 0000000..418896a --- /dev/null +++ b/src/Server/CriticalCSS/CriticalCSSGenerator.js @@ -0,0 +1,129 @@ +import { generate } from 'critical'; +import fs from 'fs'; +import path from 'path'; + +import puppeteer from 'puppeteer'; + +const browser = await puppeteer.launch(); +const page = await browser.newPage(); + +// Login +await page.goto('http://localhost:5146/Account/Login'); +await page.type('#username', 'admin'); +await page.type('#password', 'UnsafePractice.67'); +await page.click('button[type=submit]'); +await page.waitForNavigation(); + +// Extract cookies +const cookies = await page.cookies(); +await browser.close(); + +async function generateCriticalCSSForViews() { + const viewsDir = '../Views'; + + // Helper function to get all .cshtml files recursively + function getAllCshtmlFiles(dir) { + let results = []; + const list = fs.readdirSync(dir); + + list.forEach(file => { + const filePath = path.join(dir, file); + const stat = fs.statSync(filePath); + console.log("DEBUG@2"); + console.log(filePath); + if (stat && stat.isDirectory()) { + // Recursively get files from subdirectories + results = results.concat(getAllCshtmlFiles(filePath)); + } else if (file.endsWith('.cshtml') && filePath.search("/_") == -1) { + results.push(filePath); + } + }); + + return results; + } + + // Helper function to convert file path to URL path + function filePathToUrlPath(filePath) { + // Remove 'Views/' prefix + let relativePath = filePath.replace(/^Views[\/\\]/, ''); + + // Remove .cshtml extension + relativePath = relativePath.replace(/\.cshtml$/, ''); + + // Convert to URL format (replace \ with / and capitalize first letter) + const urlPath = relativePath + .split(/[\/\\]/) + .map((segment, index) => + index === 0 ? segment : segment.charAt(0).toUpperCase() + segment.slice(1) + ) + .join('/'); + + // Handle the case where we have a single file (like Index.cshtml) + if (relativePath.includes('/')) { + // Convert to URL path format: Views/Home/Index.cshtml -> /Home/Index + return '/' + relativePath.replace(/\\/g, '/').replace(/\.cshtml$/, ''); + } else { + // For files directly in Views folder (like Views/Index.cshtml) + return '/' + relativePath.replace(/\.cshtml$/, ''); + } + } + + // Get all .cshtml files + const cshtmlFiles = getAllCshtmlFiles(viewsDir); + const criticalCssDir = '.'; +// if (!fs.existsSync(criticalCssDir)) { +// fs.mkdirSync(criticalCssDir, { recursive: true }); +// } + + // Process each file + for (const file of cshtmlFiles) { + try { + const urlPath = filePathToUrlPath(file).replace("../", "").replace("/Views", ""); + + // Generate critical CSS + await generate({ + src: `http://localhost:5146${urlPath}`, + inline: false, + width: 1920, + height: 1080, + penthouse: { + customHeaders: { + cookie: cookies.map(c => `${c.name}=${c.value}`).join('; ') + }, + forceExclude: ['.btn'], // Otherwise buttons end up colorless and .btn overrides other classes like .btn-warning, etc. - so it has to be force-excluded here and re-added later + forceInclude: [ + '[data-bs-theme=dark]', + '.navbar', + '.col-md-4', + '.visually-hidden', // visually hidden headings + '.bi-info-circle-fill', '.text-info', // info icon + '.container', '.col-md-6', '.row', '.g-4', '.row>*', + 'p', '.fs-3', '.py-4', // title + '.mb-4', + '.card', '.card-body', '.p-2', // card + 'h2', '.card-title', '.fs-5', // card - title + '.d-flex', '.justify-content-between', '.mt-2', // card - content + '.progress', '.mt-3', // card - progress bar + '.list-group', '.list-group-flush', '.list-group-item', '.list-group-flush>.list-group-item', '.list-group-flush>.list-group-item:last-child', '.badge', '.bg-warning', '.bg-success', '.h-100', // card - health check list + '.btn', '.btn-sm', '.btn-primary', '.btn-warning', '.btn-danger', // Searchdomains buttons + '.col-md-8', '.sidebar', + '.mb-0', '.mb-2', '.align-items-center', + 'h3', '.col-md-3', '.col-md-2', '.text-nowrap', '.overflow-auto' + ] + }, + target: { + css: path.join(criticalCssDir, urlPath.replace(/\//g, '.').replace(/^\./, '').replace("...", "") + '.css') + } + }); + + console.log(`Critical CSS generated for: ${urlPath}`); + } catch (err) { + console.error(`Error processing ${file}:`, err); + } + } + + console.log('All critical CSS files generated!'); +} + +// Run the function +generateCriticalCSSForViews().catch(console.error); \ No newline at end of file diff --git a/src/Server/CriticalCSS/Home.Index.css b/src/Server/CriticalCSS/Home.Index.css new file mode 100644 index 0000000..f0290d7 --- /dev/null +++ b/src/Server/CriticalCSS/Home.Index.css @@ -0,0 +1 @@ +@charset "UTF-8";.align-items-center{align-items:center!important}.mb-2{margin-bottom:.5rem!important}@media (min-width:1200px){h2{font-size:2rem}h3{font-size:1.75rem}.fs-3{font-size:1.75rem!important}}.btn{display:inline-block;font-weight:400;line-height:1.5;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;border-radius:.25rem}.mb-0{margin-bottom:0!important}.overflow-auto{overflow:auto!important}.text-nowrap{white-space:nowrap!important}@media (min-width:768px){.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-6{flex:0 0 auto;width:50%}.col-md-8{flex:0 0 auto;width:66.66666667%}}h1,h2,h3{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}@media (min-width:1200px){h3{font-size:1.75rem}.fs-3{font-size:1.75rem!important}h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:576px){.container{max-width:540px}}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}@media (min-width:768px){.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-6{flex:0 0 auto;width:50%}.col-md-8{flex:0 0 auto;width:66.66666667%}}.p-2{padding:.5rem!important}@media (min-width:1200px){h3{font-size:1.75rem}.fs-3{font-size:1.75rem!important}}.btn-warning{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-sm{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (min-width:768px){.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-6{flex:0 0 auto;width:50%}}.h-100{height:100%!important}.badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item{position:relative;display:block;padding:.5rem 1rem;color:#212529;text-decoration:none;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush{border-radius:0}@media (min-width:576px){.container{max-width:540px}.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.mt-3{margin-top:1rem!important}@media (min-width:576px){.d-sm-inline-flex{display:inline-flex!important}}.progress{display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.mt-2{margin-top:.5rem!important}h1,h2{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h2{font-size:calc(1.325rem + .9vw)}p{margin-top:0;margin-bottom:1rem}.fs-3{font-size:calc(1.3rem + .6vw)!important}@media (min-width:1200px){h2{font-size:2rem}.fs-3{font-size:1.75rem!important}}.visually-hidden{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.mb-4{margin-bottom:1.5rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(var(--bs-gutter-y) * -1);margin-right:calc(var(--bs-gutter-x) * -.5);margin-left:calc(var(--bs-gutter-x) * -.5)}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.d-sm-inline-flex{display:inline-flex!important}.container{max-width:540px}}.g-4{--bs-gutter-x:1.5rem}.g-4{--bs-gutter-y:1.5rem}@media (min-width:768px){.col-md-6{flex:0 0 auto;width:50%}}.d-flex{display:flex!important}.fs-5{font-size:1.25rem!important}.card-title{margin-bottom:.5rem}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}@media (min-width:576px){.container{max-width:540px}.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.d-sm-inline-flex{display:inline-flex!important}}.card-body{flex:1 1 auto;padding:1rem}@media (min-width:576px){.container{max-width:540px}.d-sm-inline-flex{display:inline-flex!important}.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-rgb:33,37,41;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%}h1{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}ul{padding-left:2rem}ul{margin-top:0;margin-bottom:1rem}a{color:#0d6efd;text-decoration:underline}label{display:inline-block}button{border-radius:0}button,input{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button{text-transform:none}[type=button],[type=submit],button{-webkit-appearance:button}::-moz-focus-inner{padding:0;border-style:none}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}.container,.container-fluid{width:100%;padding-right:var(--bs-gutter-x,.75rem);padding-left:var(--bs-gutter-x,.75rem);margin-right:auto;margin-left:auto}@media (min-width:576px){.d-sm-inline-flex{display:inline-flex!important}.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}@media (min-width:1400px){.container{max-width:1320px}}.form-label{margin-bottom:.5rem}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.25rem}.form-control:focus{color:#212529;background-color:#fff;border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0}.btn-primary{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.collapse:not(.show){display:none}.nav-link{display:block;padding:.5rem 1rem;color:#0d6efd;text-decoration:none}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:.5rem;padding-bottom:.5rem}.navbar>.container-fluid{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.d-sm-inline-flex{display:inline-flex!important}}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.55)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.55);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.border-top{border-top:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.w-100{width:100%!important}.flex-grow-1{flex-grow:1!important}.justify-content-between{justify-content:space-between!important}.mt-4{margin-top:1.5rem!important}.mb-3{margin-bottom:1rem!important}.pb-3{padding-bottom:1rem!important}.text-center{text-align:center!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:#6c757d!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}html{font-size:14px}@media (min-width:768px){html{font-size:16px}}.form-control:focus{box-shadow:0 0 0 .1rem #fff,0 0 0 .25rem #258cfb}html{position:relative;min-height:100%}body{margin-bottom:60px} \ No newline at end of file diff --git a/src/Server/CriticalCSS/Home.Searchdomains.css b/src/Server/CriticalCSS/Home.Searchdomains.css new file mode 100644 index 0000000..f0290d7 --- /dev/null +++ b/src/Server/CriticalCSS/Home.Searchdomains.css @@ -0,0 +1 @@ +@charset "UTF-8";.align-items-center{align-items:center!important}.mb-2{margin-bottom:.5rem!important}@media (min-width:1200px){h2{font-size:2rem}h3{font-size:1.75rem}.fs-3{font-size:1.75rem!important}}.btn{display:inline-block;font-weight:400;line-height:1.5;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;border-radius:.25rem}.mb-0{margin-bottom:0!important}.overflow-auto{overflow:auto!important}.text-nowrap{white-space:nowrap!important}@media (min-width:768px){.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-6{flex:0 0 auto;width:50%}.col-md-8{flex:0 0 auto;width:66.66666667%}}h1,h2,h3{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}@media (min-width:1200px){h3{font-size:1.75rem}.fs-3{font-size:1.75rem!important}h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:576px){.container{max-width:540px}}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}@media (min-width:768px){.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-6{flex:0 0 auto;width:50%}.col-md-8{flex:0 0 auto;width:66.66666667%}}.p-2{padding:.5rem!important}@media (min-width:1200px){h3{font-size:1.75rem}.fs-3{font-size:1.75rem!important}}.btn-warning{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-sm{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (min-width:768px){.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-6{flex:0 0 auto;width:50%}}.h-100{height:100%!important}.badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item{position:relative;display:block;padding:.5rem 1rem;color:#212529;text-decoration:none;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush{border-radius:0}@media (min-width:576px){.container{max-width:540px}.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.mt-3{margin-top:1rem!important}@media (min-width:576px){.d-sm-inline-flex{display:inline-flex!important}}.progress{display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.mt-2{margin-top:.5rem!important}h1,h2{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h2{font-size:calc(1.325rem + .9vw)}p{margin-top:0;margin-bottom:1rem}.fs-3{font-size:calc(1.3rem + .6vw)!important}@media (min-width:1200px){h2{font-size:2rem}.fs-3{font-size:1.75rem!important}}.visually-hidden{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.mb-4{margin-bottom:1.5rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(var(--bs-gutter-y) * -1);margin-right:calc(var(--bs-gutter-x) * -.5);margin-left:calc(var(--bs-gutter-x) * -.5)}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.d-sm-inline-flex{display:inline-flex!important}.container{max-width:540px}}.g-4{--bs-gutter-x:1.5rem}.g-4{--bs-gutter-y:1.5rem}@media (min-width:768px){.col-md-6{flex:0 0 auto;width:50%}}.d-flex{display:flex!important}.fs-5{font-size:1.25rem!important}.card-title{margin-bottom:.5rem}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}@media (min-width:576px){.container{max-width:540px}.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.d-sm-inline-flex{display:inline-flex!important}}.card-body{flex:1 1 auto;padding:1rem}@media (min-width:576px){.container{max-width:540px}.d-sm-inline-flex{display:inline-flex!important}.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-rgb:33,37,41;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%}h1{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}ul{padding-left:2rem}ul{margin-top:0;margin-bottom:1rem}a{color:#0d6efd;text-decoration:underline}label{display:inline-block}button{border-radius:0}button,input{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button{text-transform:none}[type=button],[type=submit],button{-webkit-appearance:button}::-moz-focus-inner{padding:0;border-style:none}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}.container,.container-fluid{width:100%;padding-right:var(--bs-gutter-x,.75rem);padding-left:var(--bs-gutter-x,.75rem);margin-right:auto;margin-left:auto}@media (min-width:576px){.d-sm-inline-flex{display:inline-flex!important}.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}@media (min-width:1400px){.container{max-width:1320px}}.form-label{margin-bottom:.5rem}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.25rem}.form-control:focus{color:#212529;background-color:#fff;border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0}.btn-primary{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.collapse:not(.show){display:none}.nav-link{display:block;padding:.5rem 1rem;color:#0d6efd;text-decoration:none}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:.5rem;padding-bottom:.5rem}.navbar>.container-fluid{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.d-sm-inline-flex{display:inline-flex!important}}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.55)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.55);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.border-top{border-top:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.w-100{width:100%!important}.flex-grow-1{flex-grow:1!important}.justify-content-between{justify-content:space-between!important}.mt-4{margin-top:1.5rem!important}.mb-3{margin-bottom:1rem!important}.pb-3{padding-bottom:1rem!important}.text-center{text-align:center!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:#6c757d!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}html{font-size:14px}@media (min-width:768px){html{font-size:16px}}.form-control:focus{box-shadow:0 0 0 .1rem #fff,0 0 0 .25rem #258cfb}html{position:relative;min-height:100%}body{margin-bottom:60px} \ No newline at end of file diff --git a/src/Server/CriticalCSS/README.md b/src/Server/CriticalCSS/README.md new file mode 100644 index 0000000..994df3c --- /dev/null +++ b/src/Server/CriticalCSS/README.md @@ -0,0 +1,10 @@ +# How to use CriticalCSS +1. Install it here +```bash +npm i -D critical +npm install puppeteer +``` +2. Run the css generator: +```bash +node CriticalCSSGenerator.js +``` \ No newline at end of file diff --git a/src/Server/Program.cs b/src/Server/Program.cs index 37b6bdc..6c1bb66 100644 --- a/src/Server/Program.cs +++ b/src/Server/Program.cs @@ -13,6 +13,7 @@ using System.Reflection; using System.Configuration; using Microsoft.OpenApi.Models; using Shared.Models; +using Microsoft.AspNetCore.ResponseCompression; var builder = WebApplication.CreateBuilder(args); @@ -115,6 +116,24 @@ builder.Services.AddAuthorization(options => policy => policy.RequireRole("Admin")); }); +builder.Services.AddResponseCompression(options => +{ + options.EnableForHttps = true; + options.Providers.Add(); + options.Providers.Add(); + options.MimeTypes = + [ + "text/plain", + "text/css", + "application/javascript", + "text/javascript", + "text/html", + "application/xml", + "text/xml", + "application/json", + "image/svg+xml" + ]; +}); var app = builder.Build(); @@ -180,6 +199,8 @@ if (configuration.ApiKeys is not null) }); } +app.UseResponseCompression(); + // Add localization var supportedCultures = new[] { "de", "de-DE", "en-US" }; var localizationOptions = new RequestLocalizationOptions() @@ -189,6 +210,22 @@ var localizationOptions = new RequestLocalizationOptions() app.UseRequestLocalization(localizationOptions); app.MapControllers(); -app.UseStaticFiles(); +app.UseStaticFiles(new StaticFileOptions +{ + OnPrepareResponse = ctx => + { + string requestPath = ctx.Context.Request.Path.ToString(); + string[] cachedSuffixes = [".css", ".js", ".png", ".ico", ".woff2"]; + if (cachedSuffixes.Any(suffix => requestPath.EndsWith(suffix))) + { + ctx.Context.Response.GetTypedHeaders().CacheControl = + new Microsoft.Net.Http.Headers.CacheControlHeaderValue() + { + Public = true, + MaxAge = TimeSpan.FromDays(365) + }; + } + } +}); app.Run(); diff --git a/src/Server/Views/Home/Index.cshtml b/src/Server/Views/Home/Index.cshtml index 79b3339..bffca7b 100644 --- a/src/Server/Views/Home/Index.cshtml +++ b/src/Server/Views/Home/Index.cshtml @@ -18,9 +18,10 @@ }
-

+

Searchdomains

+

@(hasName ? T["Hi, {0}!", name] : T["Hi!"]) - +

@@ -28,7 +29,7 @@
-
@T["Embedding Cache"]
+

@T["Embedding Cache"]

@T["Size"] @@ -62,7 +63,7 @@
-
@T["Health Checks"]
+

@T["Health Checks"]