{"id":20021,"date":"2026-06-15T08:34:43","date_gmt":"2026-06-15T06:34:43","guid":{"rendered":"https:\/\/webhosting.de\/http-conditional-caching-etag-last-modified-performance-guide\/"},"modified":"2026-06-15T08:34:43","modified_gmt":"2026-06-15T06:34:43","slug":"http-betinget-caching-etag-sidst-aendret-ydeevnevejledning","status":"publish","type":"post","link":"https:\/\/webhosting.de\/da\/http-conditional-caching-etag-last-modified-performance-guide\/","title":{"rendered":"Forst\u00e5else af HTTP-betinget caching med ETag og Last-Modified"},"content":{"rendered":"<p>HTTP-caching sparer tid og data, da jeg kun indl\u00e6ser ressourcerne igen, hvis de rent faktisk er blevet \u00e6ndret. Om <strong>ETag<\/strong> og <strong>Sidst \u00e6ndret<\/strong> kontrollerer jeg ved hj\u00e6lp af en betinget foresp\u00f8rgsel, om serveren svarer med 304 Not Modified, hvilket reducerer dataoverf\u00f8rslen og serverbelastningen betydeligt.<\/p>\n\n<h2>Centrale punkter<\/h2>\n\n<p>F\u00f8lgende hovedpunkter viser, hvad jeg l\u00e6gger v\u00e6gt p\u00e5 ved betinget caching med <strong>ETag<\/strong> og <strong>Sidst \u00e6ndret<\/strong> opm\u00e6rksomhed.<\/p>\n<ul>\n  <li><strong>Mindre trafik<\/strong>: U\u00e6ndrede filer returnerer en 304-status, ikke hele br\u00f8dteksten \u2013 det reducerer datam\u00e6ngden og ventetiden m\u00e6rkbart.<\/li>\n  <li><strong>Bedre ydeevne<\/strong>: Kortere ventetider forbedrer brugeroplevelsen og Core Web Vitals, hvilket <strong>SEO<\/strong> hj\u00e6lper.<\/li>\n  <li><strong>To mekanismer<\/strong>: Last-Modified\/If-Modified-Since og ETag\/If-None-Match sikrer en p\u00e5lidelig validering af cachen.<\/li>\n  <li><strong>Cache-kontrol<\/strong>: Direktiver styrer opdatering, genindl\u00e6sning og adf\u00e6rd i mellemliggende cacher.<\/li>\n  <li><strong>Kombination<\/strong>: De to metoder tilsammen sikrer h\u00f8j n\u00f8jagtighed og enkle alternativl\u00f8sninger.<\/li>\n<\/ul>\n<p>F\u00f8rst tjekker jeg, hvilke ressourcer der skifter ret ofte, og hvilke der sj\u00e6ldent g\u00f8r det. For filer, der sj\u00e6ldent \u00e6ndres, s\u00e6tter jeg en <strong>Sidst \u00e6ndret<\/strong>-tidspunktet og tilf\u00f8jer en ETag. Til dynamiske svar foretr\u00e6kker jeg at bruge <strong>ETag<\/strong>, fordi enhver \u00e6ndring i indholdet straks kan ses. P\u00e5 den m\u00e5de aflaster jeg serverne, reducerer ventetiderne og leverer meget hurtige sider til tilbagevendende bes\u00f8gende. Denne strategi styrker <strong>Core Web Vitals<\/strong> og dermed indirekte synligheden.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/conditional-caching-8923.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>HTTP-betinget caching: S\u00e5dan kontrollerer jeg gyldigheden<\/h2>\n\n<p>N\u00e5r der foretages et nyt opkald, sender klienten ud over GET-metoden yderligere headere, som jeg analyserer p\u00e5 serversiden. Hvis ressourcen har det samme <strong>ETag<\/strong> Hvis den er den samme som i cachen (If-None-Match), returnerer jeg 304 Not Modified uden indhold. Hvis der ikke er sket \u00e6ndringer i tidsstemplet (If-Modified-Since), reagerer serveren ligeledes med 304. Hvis dato eller klokkesl\u00e6t ikke l\u00e6ngere stemmer, sender jeg 200 OK med nyt indhold samt opdateret <strong>Sidst \u00e6ndret<\/strong> og ETag. P\u00e5 den m\u00e5de sparer jeg b\u00e5ndbredde, holder cachen opdateret og sikrer m\u00e6rkbart hurtigere indl\u00e6sningstider.<\/p>\n\n<h2>Last-Modified og If-Modified-Since i dagligdagen<\/h2>\n\n<p>Overskriften <strong>Sidst \u00e6ndret<\/strong> Jeg baserer mig p\u00e5 filens faktiske \u00e6ndringstidspunkt, f.eks. fra filsystemet. Hvis der senere kommer en anmodning med \u00bbIf-Modified-Since\u00ab, og ressourcen ikke er \u00e6ndret siden da, svarer jeg med 304. Denne metode er ukompliceret, let at forst\u00e5 og ideel til statiske ressourcer som CSS, JS eller billeder. Begr\u00e6nsningerne ligger i sekundrasteret for HTTP-tidsstempler og situationer, hvor indholdet \u00e6ndrer sig logisk, uden at der findes et entydigt filtidspunkt. Hvor Last-Modified st\u00f8der p\u00e5 sine begr\u00e6nsninger, supplerer en <strong>ETag<\/strong> kontrollen.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/meeting_http_caching_4573.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>ETag og If-None-Match i dynamiske systemer<\/h2>\n\n<p>En <strong>ETag<\/strong> genererer jeg som en hash, et versions-ID eller fra en database-kolonne, der markerer status\u00e6ndringer. Ved gentagen adgang sender browseren If-None-Match, jeg sammenligner tagget med min aktuelle v\u00e6rdi og svarer derefter med 304 eller 200. Denne sammenligning registrerer enhver meningsfuld indholds\u00e6ndring uden at stole p\u00e5 filens tidsstempel. Is\u00e6r ved API'er, sammensatte sider eller personaliserede fragmenter giver det meget n\u00f8jagtige resultater. Det er vigtigt, at jeg holder ETags konsistente i klyngemilj\u00f8er, s\u00e5 ingen server tilf\u00e6ldigt bruger en anden <strong>Dag<\/strong> produceret.<\/p>\n\n<h2>S\u00e5dan kombinerer du Cache-Control korrekt<\/h2>\n\n<p>Med <strong>Cache-kontrol<\/strong> Her definerer jeg, hvor l\u00e6nge indholdet betragtes som opdateret uden yderligere foresp\u00f8rgsel, og hvorn\u00e5r browseren skal revalidere det. Jeg indstiller passende max-age-v\u00e6rdier afh\u00e6ngigt af, hvor ofte der sker \u00e6ndringer, og bruger must-revalidate, hvis for\u00e6ldede data ville v\u00e6re kritiske. For versionerede filer er en lang gyldighedsperiode velegnet, mens svar, der \u00e6ndres ofte, har en kortere levetid og derefter kan kontrolleres n\u00f8jagtigt via ETag eller dato. P\u00e5 denne m\u00e5de kombinerer jeg korte svartider med korrekt aktualitet. Hvis du vil l\u00e6se mere om emnet, finder du mange eksempler under <a href=\"https:\/\/webhosting.de\/da\/http-cache-kontrol-strategier-hosting-cachemaster\/\">Cache-Control-strategier<\/a>, som jeg bruger i praksis.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/http-caching-etag-concept-3892.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>S\u00e5dan foreg\u00e5r et betinget GET-anmodning trin for trin<\/h2>\n\n<p>Ved den f\u00f8rste anmodning returnerer serveren 200 OK med Cache-Control, <strong>Sidst \u00e6ndret<\/strong> og ETag, gemmer browseren det hele. Ved n\u00e6ste bes\u00f8g afg\u00f8r alderen i cachen, om der er behov for en revalidering. Er det n\u00f8dvendigt, sender browseren en foresp\u00f8rgsel med If-None-Match og\/eller If-Modified-Since. Hvis v\u00e6rdierne stemmer overens med den aktuelle tilstand, sender jeg 304 Not Modified, og klienten bruger sin cache videre. Hvis de ikke l\u00e6ngere passer, f\u00f8lger 200 OK med en ny body og opdateret <strong>Valideringsdata<\/strong>.<\/p>\n\n<h2>Sammenligning: ETag vs. Last-Modified<\/h2>\n\n<p>Begge metoder giver mig kontrol, men adskiller sig med hensyn til arbejdsbyrde, n\u00f8jagtighed og egnethed. <strong>Sidst \u00e6ndret<\/strong> udm\u00e6rker sig ved enkel implementering og klar semantik, s\u00e5 l\u00e6nge jeg har korrekte tidsstempler. ETag gengiver indholdet meget pr\u00e6cist, men kr\u00e6ver lidt logik at generere. I mange ops\u00e6tninger kombinerer jeg begge dele og drager dermed fordel af enkelhed plus pr\u00e6cis genkendelse. Den f\u00f8lgende tabel opsummerer typiske egenskaber og hj\u00e6lper med beslutningen.<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th><strong>Aspekt<\/strong><\/th>\n      <th><strong>Sidst \u00e6ndret<\/strong><\/th>\n      <th><strong>ETag<\/strong><\/th>\n      <th><strong>Hint<\/strong><\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>Identitet<\/td>\n      <td>Tidspunkt for seneste \u00e6ndring<\/td>\n      <td>Indholds-hash eller versions-ID<\/td>\n      <td><strong>Tid<\/strong> vs. indholdsbaseret identifikator<\/td>\n    <\/tr>\n    <tr>\n      <td>\u00c6ndringsregistrering<\/td>\n      <td>Sekundopl\u00f8sning, indirekte<\/td>\n      <td>Direkte rettet mod indholdet<\/td>\n      <td>ETag registrerer selv de mindste <strong>Forskelle<\/strong><\/td>\n    <\/tr>\n    <tr>\n      <td>implementering<\/td>\n      <td>Meget let, filsystemet er tilstr\u00e6kkeligt<\/td>\n      <td>Kr\u00e6ver generering og konsistens<\/td>\n      <td>Klynger har brug for ens <strong>ETags<\/strong><\/td>\n    <\/tr>\n    <tr>\n      <td>Brug<\/td>\n      <td>Statiske ressourcer<\/td>\n      <td>Dynamiske svar<\/td>\n      <td>Kombinationen d\u00e6kker mange <strong>Sager<\/strong> fra<\/td>\n    <\/tr>\n    <tr>\n      <td>Svar p\u00e5 sp\u00f8rgsm\u00e5l<\/td>\n      <td>304 med u\u00e6ndret tidsstempel<\/td>\n      <td>304 ved identisk tag<\/td>\n      <td>200 ved \u00e6ndringer med nyt <strong>V\u00e6rdi<\/strong><\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/tech_office_caching_4721.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Praksis: Effektiv levering af statiske ressourcer<\/h2>\n\n<p>Statiske filer som CSS, JS og billeder \u00e6ndres sj\u00e6ldent og egner sig til lange <strong>max-alder<\/strong>-tider. For filer med versionsstyring indstiller jeg lange tidsintervaller p\u00e5 op til et \u00e5r og markerer dem som uforanderlige, s\u00e5 browseren indl\u00e6ser dem uden at sp\u00f8rge om tilladelse. For ikke-versionerede assets v\u00e6lger jeg kortere tidsfrister og stoler p\u00e5 revalidering via ETag og Last-Modified. P\u00e5 den m\u00e5de undg\u00e5r jeg for\u00e6ldet indhold og holder trafikken nede. Hvis jeg s\u00f8rger for ikke at <a href=\"https:\/\/webhosting.de\/da\/http-cache-headers-saboterer-caching-cachefix\/\">Sabotage af cache-header<\/a> ved at lade det st\u00e5, opn\u00e5r jeg en h\u00f8j hitrate i cachen.<\/p>\n\n<h2>Praksis: API'er og dynamiske sider<\/h2>\n\n<p>N\u00e5r det g\u00e6lder API'er, foretr\u00e6kker jeg som regel <strong>ETags<\/strong>, som jeg danner ud fra det serialiserede resultat eller en versionskolonne. Hvis dataposten \u00e6ndres, genererer jeg en ny tag, hvilket klienterne straks registrerer. For indhold med usikkert tidsstempel undg\u00e5r jeg ofte Last-Modified, s\u00e5 der ikke opst\u00e5r et forkert indtryk af aktualitet. Derudover styrer jeg levetiden via Cache-Control og tvinger til revalidering efter udl\u00f8b. P\u00e5 den m\u00e5de holder jeg dataene p\u00e5lideligt opdaterede uden at g\u00f8re svarene un\u00f8dvendigt store.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/developer_desk_caching_3947.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Test og overv\u00e5gning af cache-hitrate<\/h2>\n\n<p>Jeg tjekker overskrifter som <strong>ETag<\/strong>, Last-Modified, If-None-Match og If-Modified-Since i udviklerv\u00e6rkt\u00f8jerne. Her holder jeg \u00f8je med responskoderne, is\u00e6r 304 kontra 200, for at se, hvor effektiv min revalidering er. Hvis 304 sj\u00e6ldent forekommer, justerer jeg Cache-Control, gyldighedsperioder og ETag-generering. Logfiler og m\u00e5linger viser mig, hvilke stier der svarer un\u00f8dvendigt meget. Til samlede forbedringer bruger jeg gerne en <a href=\"https:\/\/webhosting.de\/da\/http-conditional-requests-cache-validation-optimisation-package\/\">Pakke med betingede anmodninger<\/a>, der samler konfiguration og test.<\/p>\n\n<h2>Hostingarkitektur og ETag-f\u00e6lder<\/h2>\n\n<p>I ops\u00e6tninger med flere servere skal en <strong>ETag<\/strong> skal v\u00e6re uafh\u00e6ngig af instansen, ellers mislykkes genkendelsen. Jeg s\u00f8rger for, at alle noder bruger den samme logik og den samme n\u00f8gle til genereringen. Reverse proxyer eller CDN'er m\u00e5 ikke \u00e6ndre ETag'er og b\u00f8r videresende statusheadere korrekt. Ved implementeringer med asset-fingerprints undg\u00e5r jeg server-side genberegning af ETag, hvis filen allerede har en versioneret URL. Ensartede regler forhindrer inkonsekvente svar og holder cache-hitrate h\u00f8j.<\/p>\n\n<h2>Friskhed kontra validering: Pr\u00e6cis anvendelse af direktiver<\/h2>\n\n<p>Jeg skelner klart mellem <em>Friskhed<\/em> (hvor l\u00e6nge m\u00e5 en cache bruge en kopi uden at sp\u00f8rge om lov?) og <em>Validering<\/em> (hvordan tjekker jeg, om den stadig er gyldig?). Om <strong>Cache-kontrol<\/strong> styrer jeg begge dele meget detaljeret: <strong>max-alder<\/strong> fastl\u00e6gger levetiden hos klienten, <strong>s-maxage<\/strong> til delte cacher s\u00e5som proxyservere. <strong>offentlig<\/strong> tillader cachelagring i delte cacher, <strong>privat<\/strong> begr\u00e6nser det til den endelige browser. <strong>skal-revalidere<\/strong> tvinger til foresp\u00f8rgsler efter udl\u00f8b, mens <strong>uforanderlig<\/strong> undg\u00e5r un\u00f8dvendige revalideringer af versionerede aktiver. <strong>no-cache<\/strong> forbyder ikke caching, men kr\u00e6ver altid en revalidering; <strong>ingen opbevaring<\/strong> forbyder derimod fuldst\u00e6ndigt lagring. \u00c6ldre <strong>Udl\u00f8ber<\/strong>-Header bruger jeg kun som en sikkerhedsforanstaltning; jeg flytter konsekvent logikken over til Cache-Control. Og hvis jeg vil afb\u00f8de udfald, hj\u00e6lper <strong>stale-while-revalidate<\/strong> og <strong>stale-if-fejl<\/strong>, for at kunne dele indhold, der er udl\u00f8bet p\u00e5 kort sigt, mens jeg opdaterer i baggrunden eller omg\u00e5r fejl.<\/p>\n\n<h2>St\u00e6rke og svage ETags, komprimering og varianter<\/h2>\n\n<p>Jeg skelner bevidst mellem st\u00e6rke og svage validatorer. <strong>St\u00e6rke ETags<\/strong> identificerer n\u00f8jagtig den samme repr\u00e6sentation \u2013 ideelt, hvis jeg ogs\u00e5 <strong>Anmodninger om r\u00e6kkevidde<\/strong> \u00f8nsker at betjene effektivt. <strong>Svage ETags<\/strong> (Pr\u00e6fiks <code>W\/<\/code>) er tilstr\u00e6kkeligt, hvis semantisk ensartethed er nok, f.eks. ved sm\u00e5, irrelevante format\u00e6ndringer. Det vigtige er h\u00e5ndteringen af <strong>Kompression<\/strong>: Hvis jeg leverer indhold, der er kodet med b\u00e5de gzip og brotli, m\u00e5 en enkelt ETag ikke g\u00e6lde for alle varianter. Enten skal jeg generere ETag'en ud fra den ukomprimerede version og derudover angive en passende <strong>Vary: Accept-kodning<\/strong>, eller jeg genererer ensartede, men forskellige ETags for hver variant. P\u00e5 den m\u00e5de undg\u00e5r jeg fejlresultater og 200-svar, der egentlig burde v\u00e6re 304. Ved <strong>If-omr\u00e5de<\/strong> Jeg kombinerer r\u00e6kkeviddeforesp\u00f8rgsler med en validator: Hvis ETag eller datoen stemmer overens, svarer jeg med 206 Partial Content; ellers returnerer jeg 200 med fuld body, s\u00e5 klienten har et konsistent grundlag.<\/p>\n\n<h2>At mestre Vary-headere og indholdsforhandling til fulde<\/h2>\n\n<p>N\u00e5r serveren leverer forskellige repr\u00e6sentationer afh\u00e6ngigt af kravene, s\u00e6tter jeg <strong>Varierer<\/strong> korrekt. Typiske eksempler er <strong>Accept-Encoding<\/strong> (kompression), <strong>Accept-sprog<\/strong> (lokalisering) eller specifikke feature-flags. Jeg undg\u00e5r at bruge flygtige headere som <strong>Brugeragent<\/strong> eller endda <strong>Kage<\/strong> at variere, fordi det \u00f8del\u00e6gger cache-hitraten fuldst\u00e6ndigt. N\u00e5r personalisering er n\u00f8dvendig, markerer jeg svar som <strong>privat<\/strong> eller <strong>ingen opbevaring<\/strong> og adskiller dem tydeligt fra ressourcer, der kan caches offentligt. Vigtigt: Variationer p\u00e5virker ogs\u00e5 ETags \u2013 hver variant skal have sin egen, konsistente validator. P\u00e5 den m\u00e5de sikrer jeg, at browsere, proxyservere og CDN'er anvender den samme logik, og at ingen variant ved en fejltagelse blandes sammen med en anden.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/httpcaching-verstehen-2638.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Betingede foresp\u00f8rgsler ud over GET<\/h2>\n\n<p>Betingede anmodninger virker ikke kun ved l\u00e6sning. Til skrivende metoder bruger jeg <strong>Hvis-match<\/strong> eller <strong>If-Unmodified-Since<\/strong>til <em>manglende opdateringer<\/em> at forhindre. Hvis klienten ved en PUT- eller DELETE-anmodning returnerer den senest set ETag via <strong>Hvis-match<\/strong> hvis serverens tilstand stadig er den samme, gennemf\u00f8rer jeg \u00e6ndringen \u2013 ellers svarer jeg med <strong>412 Foruds\u00e6tning opfyldt<\/strong>. For at holde styr p\u00e5 klienterne kan serveren desuden <strong>428 Foruds\u00e6tning p\u00e5kr\u00e6vet<\/strong> etablere. Til hurtige test uden body bruger jeg <strong>HEAD<\/strong>, der giver mig de samme overskrifter som en GET-anmodning; perfekt, n\u00e5r jeg vil teste metadata. Og ved <strong>304<\/strong>-I svarene medtager jeg igen alle de headere, der er relevante for cachen (Cache-Control, ETag, Expires, Last-Modified), s\u00e5 klienten kan opdatere sine metadata uden at overf\u00f8re selve indholdet.<\/p>\n\n<h2>Sikkerhed, databeskyttelse og compliance<\/h2>\n\n<p>Jeg gemmer ikke personlige eller f\u00f8lsomme oplysninger i den offentlige cache. Her bruger jeg <strong>Cache-kontrol: privat<\/strong> eller <strong>ingen opbevaring<\/strong>, s\u00e5 browseren eller ingen instans overhovedet gemmer indholdet. V\u00e6r forsigtig med brugerkonti og dashboards: Svar med <strong>S\u00e6t cookie<\/strong> eller <strong>Autorisation<\/strong> m\u00e5 ikke ved en fejltagelse kunne caches offentligt. ETags kan i sig selv misbruges som sporingsvektorer, hvis de forbliver u\u00e6ndrede i l\u00e6ngere tid. Jeg im\u00f8deg\u00e5r dette ved kun aktivt at anvende validatorer der, hvor caching ogs\u00e5 er \u00f8nsket, og ved at deaktivere dem p\u00e5 brugerspecifikke ruter eller holde levetiden kort. P\u00e5 den m\u00e5de forener jeg ydeevne med krav til databeskyttelse.<\/p>\n\n<h2>Implementeringsdetaljer og pr\u00e6stationsomkostninger<\/h2>\n\n<p>Oprettelsen af en ETag m\u00e5 ikke koste mere end den giver i gevinst. Ved store filer eller ressourcekr\u00e6vende renderinger gemmer jeg tagget sammen med metadata (filkontrolsum, build-hash, database-<em>r\u00e6kkeversion<\/em>) og gentager den ikke ved hver eneste anmodning. Ved sammensatte sider hj\u00e6lper en <em>Version-Compose-strategi<\/em>: Jeg sammens\u00e6tter ETag'en af stabile del-ETag'er (f.eks. skabelon, datafragment, konfiguration), s\u00e5 sm\u00e5 \u00e6ndringer resulterer i en m\u00e5lrettet, men reproducerbar ny v\u00e6rdi. I klynger synkroniserer jeg genereringslogikken i et f\u00e6lles bibliotek og kontrollerer den i CI, s\u00e5 ingen instans afviger. For ekstremt store blobs satser jeg p\u00e5 hurtige checksummer (CRC64) eller gemmer build-hashes i stedet for at hashe body on-the-fly. Hvor absolut byte-lighed ikke er n\u00f8dvendig, er det tilstr\u00e6kkeligt <strong>svage ETags<\/strong> som et pragmatisk kompromis.<\/p>\n\n<h2>Almindelige fejl og hvordan du undg\u00e5r dem<\/h2>\n\n<ul>\n  <li><strong>Tilf\u00e6ldige ETags<\/strong>: Hvis tags genereres p\u00e5 ny ved hver foresp\u00f8rgsel, er enhver revalidering meningsl\u00f8s. Jeg s\u00f8rger for deterministiske v\u00e6rdier, der kun \u00e6ndres, n\u00e5r der sker en reel \u00e6ndring.<\/li>\n  <li><strong>Forkert kombination af direktiver<\/strong>: <em>ingen opbevaring<\/em> ETag nytter ikke noget \u2013 browseren gemmer det alligevel ikke. Jeg v\u00e6lger ensartede kombinationer for at opn\u00e5 den \u00f8nskede funktion.<\/li>\n  <li><strong>Overdreven Vary<\/strong>: Variationer i cookie- eller user-agent-strengen \u00f8del\u00e6gger cachen. Jeg begr\u00e6nser Vary til reelle \u00e6ndringer i repr\u00e6sentationen.<\/li>\n  <li><strong>Kompressionsf\u00e6lder<\/strong>: En f\u00e6lles ETag for gzip og br medf\u00f8rer fejlresultater. Jeg knytter ETags korrekt til den konkrete variant og angiver Vary korrekt.<\/li>\n  <li><strong>Tidsafvigelse<\/strong>: Un\u00f8jagtige serverure forvrider \u00bbLast-Modified\u00ab-v\u00e6rdien. Jeg holder tidskilderne synkroniserede, s\u00e5 \u00bbIf-Modified-Since\u00ab fungerer korrekt.<\/li>\n  <li><strong>Forveksling af no-cache<\/strong>: Mange l\u00e6ser det som \u201eikke cache\u201c. Det, der menes, er \u201ealtid revalider\u201c. Til et egentligt forbud bruger jeg <em>ingen opbevaring<\/em>.<\/li>\n<\/ul>\n\n<h2>Fejlfinding, m\u00e5linger og arbejdsgange<\/h2>\n\n<p>For at finde fejlen starter jeg i fanen \u00bbNetv\u00e6rk\u00ab: Er det korrekt? <strong>Cache-kontrol<\/strong>? Opst\u00e5r ved genoptr\u00e6ning <strong>304<\/strong> i stedet for 200? Passer <strong>ETag<\/strong> og <strong>Sidst \u00e6ndret<\/strong> mellem foresp\u00f8rgsel og svar? Jeg tjekker <strong>Varierer<\/strong>, for at se, om varianterne er genkendt korrekt. I logfilerne f\u00e5r jeg vist <em>Hit\/Miss<\/em>-kvoter, 304-procenter og gennemsnitlige responsst\u00f8rrelser pr. sti. Hvis 304-procenten stiger, falder datam\u00e6ngden og TTFB typisk m\u00e6rkbart. I belastningstests simulerer jeg gentagne opkald for at m\u00e5le revalideringsomkostninger i stedet for overf\u00f8rselsomkostninger. Ved afvigelser fjerner jeg gradvist forstyrrende faktorer: Set-Cookie, for strenge Vary-regler, modstridende headere som Pragma. P\u00e5 den m\u00e5de finder jeg hurtigt den flaskehals, der presser hitraten.<\/p>\n\n<h2>Service Worker som et supplerende cache-lag<\/h2>\n\n<p>Hvis jeg bruger en service worker, bruger jeg den som et ekstra lag, ikke som et modstridende lag. Jeg lader den udf\u00f8re de samme <strong>Cache-kontrol<\/strong>-Respekter signalerne og kombiner strategier som <em>stale-while-revalidate<\/em> bevidst med HTTP-validering via ETag og Last-Modified. I tilf\u00e6lde af offline-tilstande kan workeren levere midlertidigt for\u00e6ldede ressourcer og revalidere dem i baggrunden. Det er vigtigt, at den videregiver betingelsesheadere korrekt, ellers mister jeg fordelene ved 304 p\u00e5 netv\u00e6rksstr\u00e6kningen. P\u00e5 den m\u00e5de drager ogs\u00e5 PWA-scenarier fordel af korrekt HTTP-caching i stedet for at omg\u00e5 dens mekanismer.<\/p>\n\n<h2>SEO-effekt og Core Web Vitals<\/h2>\n\n<p>Forbedre hurtige svar <strong>UX<\/strong> og brugersignaler, hvilket forbedrer placeringerne i s\u00f8geresultaterne. Is\u00e6r tilbagevendende bes\u00f8gende drager fordel af dette, da deres browser henter mange filer direkte fra cachen eller via 304-bekr\u00e6ftelser. Denne lavere ventetid har en positiv indvirkning p\u00e5 FCP, LCP og TTFB, som jeg reducerer ved hj\u00e6lp af m\u00e5lrettet revalidering. Desuden sparer serveren regnetid, som jeg kan bruge til spidsbelastninger eller ressourcekr\u00e6vende anmodninger. P\u00e5 den m\u00e5de opretholder jeg ydeevnen, mens indholdet leveres korrekt og rettidigt.<\/p>\n\n<h2>Resum\u00e9: Min handlingsplan<\/h2>\n\n<p>Jeg er afh\u00e6ngig af en klar <strong>Kombination<\/strong> ud fra Cache-Control, Last-Modified og ETag. Til statiske ressourcer v\u00e6lger jeg lange gyldighedsperioder og sikrer mig ved hj\u00e6lp af revalidering, hvis filerne ikke er versionerede. For dynamiske svar genererer jeg p\u00e5lidelige ETags og holder klynger konsistente. Derefter kontrollerer jeg med v\u00e6rkt\u00f8jer, metrics og logs, om 304 forekommer ofte nok, og justerer indstillingerne. S\u00e5dan sikrer jeg hurtig levering, lavere belastning og en bedre brugeroplevelse gennem effektiv <strong>HTTP-caching<\/strong>.<\/p>","protected":false},"excerpt":{"rendered":"<p>L\u00e6r, hvordan HTTP-betinget caching med ETag og Last-Modified fungerer, hvordan validering af browserens cache gennemf\u00f8res, og hvordan du dermed kan optimere indl\u00e6sningstider, b\u00e5ndbredde og serverbelastning.<\/p>","protected":false},"author":1,"featured_media":20014,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[834],"tags":[],"class_list":["post-20021","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-plesk-webserver-plesk-administration-anleitungen"],"acf":[],"_wp_attached_file":null,"_wp_attachment_metadata":null,"litespeed-optimize-size":null,"litespeed-optimize-set":null,"_elementor_source_image_hash":null,"_wp_attachment_image_alt":null,"stockpack_author_name":null,"stockpack_author_url":null,"stockpack_provider":null,"stockpack_image_url":null,"stockpack_license":null,"stockpack_license_url":null,"stockpack_modification":null,"color":null,"original_id":null,"original_url":null,"original_link":null,"unsplash_location":null,"unsplash_sponsor":null,"unsplash_exif":null,"unsplash_attachment_metadata":null,"_elementor_is_screenshot":null,"surfer_file_name":null,"surfer_file_original_url":null,"envato_tk_source_kit":null,"envato_tk_source_index":null,"envato_tk_manifest":null,"envato_tk_folder_name":null,"envato_tk_builder":null,"envato_elements_download_event":null,"_menu_item_type":null,"_menu_item_menu_item_parent":null,"_menu_item_object_id":null,"_menu_item_object":null,"_menu_item_target":null,"_menu_item_classes":null,"_menu_item_xfn":null,"_menu_item_url":null,"_trp_menu_languages":null,"rank_math_primary_category":null,"rank_math_title":null,"inline_featured_image":null,"_yoast_wpseo_primary_category":null,"rank_math_schema_blogposting":null,"rank_math_schema_videoobject":null,"_oembed_049c719bc4a9f89deaead66a7da9fddc":null,"_oembed_time_049c719bc4a9f89deaead66a7da9fddc":null,"_yoast_wpseo_focuskw":null,"_yoast_wpseo_linkdex":null,"_oembed_27e3473bf8bec795fbeb3a9d38489348":null,"_oembed_c3b0f6959478faf92a1f343d8f96b19e":null,"_trp_translated_slug_en_us":null,"_wp_desired_post_slug":null,"_yoast_wpseo_title":null,"tldname":null,"tldpreis":null,"tldrubrik":null,"tldpolicylink":null,"tldsize":null,"tldregistrierungsdauer":null,"tldtransfer":null,"tldwhoisprivacy":null,"tldregistrarchange":null,"tldregistrantchange":null,"tldwhoisupdate":null,"tldnameserverupdate":null,"tlddeletesofort":null,"tlddeleteexpire":null,"tldumlaute":null,"tldrestore":null,"tldsubcategory":null,"tldbildname":null,"tldbildurl":null,"tldclean":null,"tldcategory":null,"tldpolicy":null,"tldbesonderheiten":null,"tld_bedeutung":null,"_oembed_d167040d816d8f94c072940c8009f5f8":null,"_oembed_b0a0fa59ef14f8870da2c63f2027d064":null,"_oembed_4792fa4dfb2a8f09ab950a73b7f313ba":null,"_oembed_33ceb1fe54a8ab775d9410abf699878d":null,"_oembed_fd7014d14d919b45ec004937c0db9335":null,"_oembed_21a029d076783ec3e8042698c351bd7e":null,"_oembed_be5ea8a0c7b18e658f08cc571a909452":null,"_oembed_a9ca7a298b19f9b48ec5914e010294d2":null,"_oembed_f8db6b27d08a2bb1f920e7647808899a":null,"_oembed_168ebde5096e77d8a89326519af9e022":null,"_oembed_cdb76f1b345b42743edfe25481b6f98f":null,"_oembed_87b0613611ae54e86e8864265404b0a1":null,"_oembed_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_oembed_time_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_tldname":null,"_tldclean":null,"_tldpreis":null,"_tldcategory":null,"_tldsubcategory":null,"_tldpolicy":null,"_tldpolicylink":null,"_tldsize":null,"_tldregistrierungsdauer":null,"_tldtransfer":null,"_tldwhoisprivacy":null,"_tldregistrarchange":null,"_tldregistrantchange":null,"_tldwhoisupdate":null,"_tldnameserverupdate":null,"_tlddeletesofort":null,"_tlddeleteexpire":null,"_tldumlaute":null,"_tldrestore":null,"_tldbildname":null,"_tldbildurl":null,"_tld_bedeutung":null,"_tldbesonderheiten":null,"_oembed_ad96e4112edb9f8ffa35731d4098bc6b":null,"_oembed_8357e2b8a2575c74ed5978f262a10126":null,"_oembed_3d5fea5103dd0d22ec5d6a33eff7f863":null,"_eael_widget_elements":null,"_oembed_0d8a206f09633e3d62b95a15a4dd0487":null,"_oembed_time_0d8a206f09633e3d62b95a15a4dd0487":null,"_aioseo_description":null,"_eb_attr":null,"_eb_data_table":null,"_oembed_819a879e7da16dd629cfd15a97334c8a":null,"_oembed_time_819a879e7da16dd629cfd15a97334c8a":null,"_acf_changed":null,"_wpcode_auto_insert":null,"_edit_last":null,"_edit_lock":null,"_oembed_e7b913c6c84084ed9702cb4feb012ddd":null,"_oembed_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_time_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_03514b67990db061d7c4672de26dc514":null,"_oembed_time_03514b67990db061d7c4672de26dc514":null,"rank_math_news_sitemap_robots":null,"rank_math_robots":null,"_eael_post_view_count":"112","_trp_automatically_translated_slug_ru_ru":null,"_trp_automatically_translated_slug_et":null,"_trp_automatically_translated_slug_lv":null,"_trp_automatically_translated_slug_fr_fr":null,"_trp_automatically_translated_slug_en_us":null,"_wp_old_slug":null,"_trp_automatically_translated_slug_da_dk":null,"_trp_automatically_translated_slug_pl_pl":null,"_trp_automatically_translated_slug_es_es":null,"_trp_automatically_translated_slug_hu_hu":null,"_trp_automatically_translated_slug_fi":null,"_trp_automatically_translated_slug_ja":null,"_trp_automatically_translated_slug_lt_lt":null,"_elementor_edit_mode":null,"_elementor_template_type":null,"_elementor_version":null,"_elementor_pro_version":null,"_wp_page_template":null,"_elementor_page_settings":null,"_elementor_data":null,"_elementor_css":null,"_elementor_conditions":null,"_happyaddons_elements_cache":null,"_oembed_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_time_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_time_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_59808117857ddf57e478a31d79f76e4d":null,"_oembed_time_59808117857ddf57e478a31d79f76e4d":null,"_oembed_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_time_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_81002f7ee3604f645db4ebcfd1912acf":null,"_oembed_time_81002f7ee3604f645db4ebcfd1912acf":null,"_elementor_screenshot":null,"_oembed_7ea3429961cf98fa85da9747683af827":null,"_oembed_time_7ea3429961cf98fa85da9747683af827":null,"_elementor_controls_usage":null,"_elementor_page_assets":[],"_elementor_screenshot_failed":null,"theplus_transient_widgets":null,"_eael_custom_js":null,"_wp_old_date":null,"_trp_automatically_translated_slug_it_it":null,"_trp_automatically_translated_slug_pt_pt":null,"_trp_automatically_translated_slug_zh_cn":null,"_trp_automatically_translated_slug_nl_nl":null,"_trp_automatically_translated_slug_pt_br":null,"_trp_automatically_translated_slug_sv_se":null,"rank_math_analytic_object_id":null,"rank_math_internal_links_processed":"1","_trp_automatically_translated_slug_ro_ro":null,"_trp_automatically_translated_slug_sk_sk":null,"_trp_automatically_translated_slug_bg_bg":null,"_trp_automatically_translated_slug_sl_si":null,"litespeed_vpi_list":null,"litespeed_vpi_list_mobile":null,"rank_math_seo_score":null,"rank_math_contentai_score":null,"ilj_limitincominglinks":null,"ilj_maxincominglinks":null,"ilj_limitoutgoinglinks":null,"ilj_maxoutgoinglinks":null,"ilj_limitlinksperparagraph":null,"ilj_linksperparagraph":null,"ilj_blacklistdefinition":null,"ilj_linkdefinition":null,"_eb_reusable_block_ids":null,"rank_math_focus_keyword":"HTTP Caching","rank_math_og_content_image":null,"_yoast_wpseo_metadesc":null,"_yoast_wpseo_content_score":null,"_yoast_wpseo_focuskeywords":null,"_yoast_wpseo_keywordsynonyms":null,"_yoast_wpseo_estimated-reading-time-minutes":null,"rank_math_description":null,"surfer_last_post_update":null,"surfer_last_post_update_direction":null,"surfer_keywords":null,"surfer_location":null,"surfer_draft_id":null,"surfer_permalink_hash":null,"surfer_scrape_ready":null,"_thumbnail_id":"20014","footnotes":null,"_links":{"self":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/posts\/20021","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/comments?post=20021"}],"version-history":[{"count":0,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/posts\/20021\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/media\/20014"}],"wp:attachment":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/media?parent=20021"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/categories?post=20021"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/tags?post=20021"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}