decoded-body-size-compressed.https.html (8072B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="timeout" content="long"/> 6 <title>PerformanceResourceTiming.decodedBodySize for compressed resources</title> 7 <link rel="help" href="https://www.w3.org/TR/resource-timing-2/#dom-performanceresourcetiming-decodedbodysize" /> 8 <script src="/resources/testharness.js"></script> 9 <script src="/resources/testharnessreport.js"></script> 10 <script src="/fetch/compression-dictionary/resources/compression-dictionary-util.sub.js"></script> 11 <script> 12 const waitForResourceTiming = (url) => { 13 return new Promise(resolve => { 14 const observer = new PerformanceObserver((list) => { 15 const entries = list.getEntries(); 16 for (const entry of entries) { 17 if (entry.name.includes(url)) { 18 observer.disconnect(); 19 resolve(entry); 20 } 21 } 22 }); 23 observer.observe({ entryTypes: ["resource"] }); 24 }); 25 }; 26 27 promise_test(async (t) => { 28 const url = "/resource-timing/resources/gzip_xml.py"; 29 const expectedDecodedSize = 125; 30 31 const timingPromise = waitForResourceTiming(url); 32 const response = await fetch(url); 33 await response.text(); 34 const entry = await timingPromise; 35 36 assert_equals(entry.decodedBodySize, expectedDecodedSize, 37 "decodedBodySize should match the uncompressed XML file size"); 38 assert_greater_than(entry.encodedBodySize, 0, 39 "encodedBodySize should be non-zero"); 40 }, "decodedBodySize for gzip-compressed XML resource"); 41 42 promise_test(async (t) => { 43 const url = "/resource-timing/resources/foo.text.br"; 44 const expectedDecodedSize = 10500; 45 const expectedEncodedSize = 15; 46 47 const timingPromise = waitForResourceTiming(url); 48 const response = await fetch(url); 49 await response.text(); 50 const entry = await timingPromise; 51 52 assert_equals(entry.decodedBodySize, expectedDecodedSize, 53 "decodedBodySize should match the uncompressed brotli file size"); 54 assert_equals(entry.encodedBodySize, expectedEncodedSize, 55 "encodedBodySize should match the compressed brotli file size"); 56 }, "decodedBodySize for brotli-compressed text resource"); 57 58 promise_test(async (t) => { 59 const url = "/resource-timing/resources/foo.text.gz"; 60 const expectedDecodedSize = 10500; 61 const expectedEncodedSize = 57; 62 63 const timingPromise = waitForResourceTiming(url); 64 const response = await fetch(url); 65 await response.text(); 66 const entry = await timingPromise; 67 68 assert_equals(entry.decodedBodySize, expectedDecodedSize, 69 "decodedBodySize should match the uncompressed gzip file size"); 70 assert_equals(entry.encodedBodySize, expectedEncodedSize, 71 "encodedBodySize should match the compressed gzip file size"); 72 }, "decodedBodySize for gzip-compressed text resource"); 73 74 promise_test(async (t) => { 75 const url = "/resource-timing/resources/compressed-js.py?content_encoding=gzip"; 76 const expectedDecodedSize = 53; 77 78 const timingPromise = waitForResourceTiming(url); 79 const response = await fetch(url); 80 await response.text(); 81 const entry = await timingPromise; 82 83 assert_equals(entry.decodedBodySize, expectedDecodedSize, 84 "decodedBodySize should match the uncompressed JS file size"); 85 assert_not_equals(entry.encodedBodySize, entry.decodedBodySize, 86 "encodedBodySize should differ from decodedBodySize for gzip-compressed JS"); 87 assert_greater_than(entry.encodedBodySize, 0, 88 "encodedBodySize should be non-zero"); 89 }, "decodedBodySize for dynamically gzip-compressed JS resource"); 90 91 promise_test(async (t) => { 92 const url = "/resource-timing/resources/compressed-js.py?content_encoding=deflate"; 93 const expectedDecodedSize = 53; 94 95 const timingPromise = waitForResourceTiming(url); 96 const response = await fetch(url); 97 await response.text(); 98 const entry = await timingPromise; 99 100 assert_equals(entry.decodedBodySize, expectedDecodedSize, 101 "decodedBodySize should match the uncompressed JS file size"); 102 assert_not_equals(entry.encodedBodySize, entry.decodedBodySize, 103 "encodedBodySize should differ from decodedBodySize for deflate-compressed JS"); 104 assert_greater_than(entry.encodedBodySize, 0, 105 "encodedBodySize should be non-zero"); 106 }, "decodedBodySize for deflate-compressed JS resource"); 107 108 promise_test(async (t) => { 109 const url = "/resource-timing/resources/compressed-js.py?content_encoding=identity"; 110 const expectedSize = 53; 111 112 const timingPromise = waitForResourceTiming(url); 113 const response = await fetch(url); 114 await response.text(); 115 const entry = await timingPromise; 116 117 assert_equals(entry.decodedBodySize, expectedSize, 118 "decodedBodySize should match file size for uncompressed resource"); 119 assert_equals(entry.encodedBodySize, expectedSize, 120 "encodedBodySize should equal decodedBodySize for uncompressed resource"); 121 }, "decodedBodySize equals encodedBodySize for uncompressed resource"); 122 123 compression_dictionary_promise_test(async (t) => { 124 const registerDictionaryUrl = '/fetch/compression-dictionary/resources/register-dictionary.py'; 125 const compressedDataUrl = '/fetch/compression-dictionary/resources/compressed-data.py'; 126 127 const dict = await (await fetch(registerDictionaryUrl)).text(); 128 assert_equals(dict, kDefaultDictionaryContent); 129 130 await new Promise(resolve => t.step_timeout(resolve, 500)); 131 132 const url = `${compressedDataUrl}?content_encoding=dcb`; 133 const expectedDecodedSize = 52; 134 const expectedEncodedSize = 75; 135 136 const timingPromise = waitForResourceTiming(url); 137 const response = await fetch(url); 138 const text = await response.text(); 139 assert_equals(text, kExpectedCompressedData, 140 "The resource should decompress correctly"); 141 const entry = await timingPromise; 142 143 assert_equals(entry.decodedBodySize, expectedDecodedSize, 144 "decodedBodySize should match the uncompressed data size (52 bytes)"); 145 assert_equals(entry.encodedBodySize, expectedEncodedSize, 146 "encodedBodySize should match the dictionary-compressed brotli size (75 bytes including dictionary hash)"); 147 }, "decodedBodySize for dictionary-compressed brotli (dcb) resource"); 148 149 compression_dictionary_promise_test(async (t) => { 150 const registerDictionaryUrl = '/fetch/compression-dictionary/resources/register-dictionary.py'; 151 const compressedDataUrl = '/fetch/compression-dictionary/resources/compressed-data.py'; 152 153 const dict = await (await fetch(registerDictionaryUrl)).text(); 154 assert_equals(dict, kDefaultDictionaryContent); 155 156 await new Promise(resolve => t.step_timeout(resolve, 500)); 157 158 const url = `${compressedDataUrl}?content_encoding=dcz`; 159 const expectedDecodedSize = 52; 160 const expectedEncodedSize = 83; 161 162 const timingPromise = waitForResourceTiming(url); 163 const response = await fetch(url); 164 const text = await response.text(); 165 assert_equals(text, kExpectedCompressedData, 166 "The resource should decompress correctly"); 167 const entry = await timingPromise; 168 169 assert_equals(entry.decodedBodySize, expectedDecodedSize, 170 "decodedBodySize should match the uncompressed data size (52 bytes)"); 171 assert_equals(entry.encodedBodySize, expectedEncodedSize, 172 "encodedBodySize should match the dictionary-compressed zstd size (83 bytes including dictionary hash)"); 173 }, "decodedBodySize for dictionary-compressed zstd (dcz) resource"); 174 175 </script> 176 </head> 177 <body> 178 <h1>Description</h1> 179 <p> 180 This test validates that PerformanceResourceTiming.decodedBodySize correctly reports 181 the size of resources after removing content encoding (gzip, brotli, deflate, and 182 compression dictionaries with dcb and dcz), and that it differs from encodedBodySize 183 for compressed resources. 184 </p> 185 </body> 186 </html>