tag:webdev.shared.arty.name,2011:index.atomЗаписи о веб-разработке, рекомендованные Артемием ТрегубенкоАртемий Трегубенкоme@arty.namehttps://arty.name2020-10-22T18:23:52Zhttps://macwright.com/2020/10/28/if-not-spas.html2020-10-31T10:25:24Z2020-10-31T10:25:24ZIf Not Single Page Apps (SPAs) Then What?
<span class="mainlink"></span> — If you’re not a fan of the SPA approach, what else can you do? Turns out there are numerous modern alternatives from <a target="_blank" href="https://javascriptweekly.com/link/97848/web">Stimulus</a> to <a target="_blank" href="https://javascriptweekly.com/link/97881/web">RedwoodJS.</a>
https://blog.bitsrc.io/wouter-a-minimalist-alternative-to-react-router-2756690c2b772020-10-28T20:09:10Z2020-10-28T20:09:10ZWouter: A Minimalist Alternative to React Router
<span class="mainlink"></span> — Not a day goes by when we don’t encounter the 80/20 rule: deliver the 20% which meets 80% of the need. If you think <a target="_blank" href="https://react.statuscode.com/link/97491/web">React Router</a> might benefit from this approach, then you want to give <a target="_blank" href="https://react.statuscode.com/link/97492/web">Wouter</a> a try for your next React/<a target="_blank" href="https://react.statuscode.com/link/97493/web">Preact</a> project. It’s the 20% you need.
https://javascriptweekly.com/link/97406/web2020-10-23T18:22:44Z2020-10-23T18:22:44ZSkypack Discover: A Way to Discover and Test Recommended JS Packages
<span class="mainlink"></span> — From the same folks as the <a target="_blank" href="https://javascriptweekly.com/link/97407/web">Snowpack</a> build tool, <a target="_blank" href="https://javascriptweekly.com/link/97408/web">Skypack</a> is basically a search engine for npm packages, but it’s added a ‘Discover’ feature which helps you pick the best options for you. You can then import them ES module style.
https://developers.google.com/web/updates/2020/10/http-cache-partitioning2020-10-22T18:23:52Z2020-10-22T18:23:52ZEiji KitamuraGaining security and privacy by partitioning the cache
<blockquote>Артемий Трегубенко: «So long, javascript CDNs!»</blockquote>
<h1 id="gaining-security-and-privacy-by-partitioning-the-cache">Gaining security and privacy by partitioning the cache</h1>
<p>In general, caching can improve performance by storing data so future requests
for the same data are served faster. For example, a cached resource from the
network can avoid a round trip to the server. A cached computational result can
omit the time to do the same calculation.</p>
<p>In Chrome, the cache mechanism is used in various ways and HTTP Cache is one example.</p>
<h2 id="how-chrome-s-http-cache-currently-works">How Chrome's HTTP Cache currently works</h2>
<p>As of version 85, Chrome caches resources fetched from the network, using their
respective resource URLs as the cache key. (A cache key is used to identify a
cached resource.)</p>
<p>The following example illustrates how a single image is cached and treated in
three different contexts:</p>
<figure class="attempt-left">
<img src="https://developers.google.com/web/updates/images/2020/10/http-cache-partitioning-1.png">
<figcaption>
<b>Cache Key</b>: { <code><a href="https://x.example/doge.png">https://x.example/doge.png</a></code> }
</figcaption>
</figure>
<p>A user visits a page (<code>https://a.example</code>) that requests an image
(<code>https://x.example/doge.png</code>). The image is requested from the network and
cached using <code>https://x.example/doge.png</code> as the key.</p>
<div class="clearfix"></div>
<figure class="attempt-left">
<img src="https://developers.google.com/web/updates/images/2020/10/http-cache-partitioning-2.png">
<figcaption>
<b>Cache Key</b>: { <code><a href="https://x.example/doge.png">https://x.example/doge.png</a></code> }
</figcaption>
</figure>
<p>The same user visits another page (<code>https://b.example</code>), which requests the same
image (<code>https://x.example/doge.png</code>).<br>The browser checks its HTTP Cache to see
if it already has this resource cached, using the image URL as the key. The
browser finds a match in its Cache, so it uses the cached version of the
resource.</p>
<div class="clearfix"></div>
<figure class="attempt-left">
<img src="https://developers.google.com/web/updates/images/2020/10/http-cache-partitioning-3.png">
<figcaption>
<b>Cache Key</b>: { <code><a href="https://x.example/doge.png">https://x.example/doge.png</a></code> }
</figcaption>
</figure>
<p>It doesn't matter if the image is loaded from within an iframe. If the user
visits another website (<code>https://c.example</code>) with an iframe
(<code>https://d.example</code>) and the iframe requests the same image
(<code>https://x.example/doge.png</code>), the browser can still load the image from its
cache because the cache key is the same across all of the pages.</p>
<div class="clearfix"></div>
<p>This mechanism has been working well from a performance perspective for a long
time. However, the time a website takes to respond to HTTP requests can reveal
that the browser has accessed the same resource in the past, which opens the
browser to security and privacy attacks, like the following:</p>
<ul>
<li><strong>Detect if a user has visited a specific site</strong>: An adversary can detect a
user's browsing history by checking if the cache has a resource which might be
specific to a particular site or cohort of sites.</li>
<li><strong><a href="https://portswigger.net/daily-swig/new-xs-leak-techniques-reveal-fresh-ways-to-expose-user-information">Cross-site search
attack</a></strong>:
An adversary can detect if an arbitrary string is in the user's search results
by checking whether a 'no search results' image used by a particular website
is in the browser's cache.</li>
<li><strong>Cross-site tracking</strong>: The cache can be used to store cookie-like
identifiers as a cross-site tracking mechanism.</li>
</ul>
<p>To mitigate these risks, Chrome will partition its HTTP cache starting in Chrome 86.</p>
<h2 id="how-will-cache-partitioning-affect-chrome-s-http-cache-">How will cache partitioning affect Chrome's HTTP Cache?</h2>
<p>With cache partitioning, cached resources will be keyed using a new "Network
Isolation Key" in addition to the resource URL. The Network Isolation Key is
composed of the top-level site and the current-frame site.</p>
<p>Note: The "site" is recognized using "<a href="https://web.dev/same-site-same-origin/">scheme://eTLD+1</a>" so if requests are from
different pages, but they have the same scheme and effective top-level domain+1
they will use the same cache partition. To learn more about this, read
<a href="https://web.dev/same-site-same-origin/">Understanding "same-site" and
"same-origin"</a>.</p>
<p>Look again at the previous example to see how cache partitioning works in
different contexts:</p>
<figure class="attempt-left">
<img src="https://developers.google.com/web/updates/images/2020/10/http-cache-partitioning-1.png">
<figcaption>
<b>Cache Key</b>: { <code><a href="https://a.example/">https://a.example</a></code>, <code><a href="https://a.example/">https://a.example</a></code>, <code><a href="https://x.example/doge.png">https://x.example/doge.png</a></code> }
</figcaption>
</figure>
<p>A user visits a page (<code>https://a.example</code>) which requests an image
(<code>https://x.example/doge.png</code>). In this case, the image is requested from the
network and cached using a tuple consisting of <code>https://a.example</code> (the top-level site),
<code>https://a.example</code> (the current-frame site), and <code>https://x.example/doge.png</code> (the
resource URL) as the key. (Note that when the resource request is from the
top-level -frame, the top-level site and current-frame site in the Network
Isolation Key are the same.)</p>
<div class="clearfix"></div>
<figure class="attempt-left">
<img src="https://developers.google.com/web/updates/images/2020/10/http-cache-partitioning-2.png">
<figcaption>
<b>Cache Key</b>: { <code><a href="https://b.example/">https://b.example</a></code>, <code><a href="https://b.example/">https://b.example</a></code>, <code><a href="https://x.example/doge.png">https://x.example/doge.png</a></code> }
</figcaption>
</figure>
<p>The same user visits a different page (<code>https://b.example</code>) which requests the
same image (<code>https://x.example/doge.png</code>). Though the same image was loaded in
the previous example, since the key doesn't match it will not be a cache hit.</p>
<p>The image is requested from the network and cached using a tuple consisting of <code>https://b.example</code>,
<code>https://b.example</code>, and <code>https://x.example/doge.png</code> as the key.</p>
<div class="clearfix"></div>
<figure class="attempt-left">
<img src="https://developers.google.com/web/updates/images/2020/10/http-cache-partitioning-6.png">
<figcaption>
<b>Cache Key</b>: { <code><a href="https://a.example/">https://a.example</a></code>, <code><a href="https://a.example/">https://a.example</a></code>, <code><a href="https://x.example/doge.png">https://x.example/doge.png</a></code> }
</figcaption>
</figure>
<p>Now the user comes back to <code>https://a.example</code> but this time the image
(<code>https://x.example/doge.png</code>) is embedded in an iframe. In this case, the
key is a tuple containing <code>https://a.example</code>, <code>https://a.example</code>, and <code>https://x.example/doge.png</code>
and a cache hit occurs. (Note that when the top-level site and the iframe are
the same site, the resource cached with the top-level frame can be used.</p>
<div class="clearfix"></div>
<figure class="attempt-left">
<img src="https://developers.google.com/web/updates/images/2020/10/http-cache-partitioning-4.png">
<figcaption>
<b>Cache Key</b>: { <code><a href="https://a.example/">https://a.example</a></code>, <code><a href="https://c.example/">https://c.example</a></code>, <code><a href="https://x.example/doge.png">https://x.example/doge.png</a></code> }
</figcaption>
</figure>
<p>The user is back at <code>https://a.example</code> but this time the image is hosted in an
iframe from <code>https://c.example</code>.</p>
<p>In this case, the image is downloaded from the network because there is no
resource in the cache that matches the key consisting of <code>https://a.example</code>,
<code>https://c.example</code>, and <code>https://x.example/doge.png</code>.</p>
<div class="clearfix"></div>
<figure class="attempt-left">
<img src="https://developers.google.com/web/updates/images/2020/10/http-cache-partitioning-7.png">
<figcaption>
<b>Cache Key</b>: { <code><a href="https://a.example/">https://a.example</a></code>, <code><a href="https://c.example/">https://c.example</a></code>, <code><a href="https://x.example/doge.png">https://x.example/doge.png</a></code> }
</figcaption>
</figure>
<p>What if the domain contains a subdomain or a port number? The user visits
<code>https://subdomain.a.example</code>, which embeds an iframe
(<code>https://c.example:8080</code>), which requests the image.</p>
<p>Because the key is created based on "scheme://eTLD+1", subdomains and port
numbers are ignored. Hence a cache hit occurs.</p>
<div class="clearfix"></div>
<figure class="attempt-left">
<img src="https://developers.google.com/web/updates/images/2020/10/http-cache-partitioning-5.png">
<figcaption>
<b>Cache Key</b>: { <code><a href="https://a.example/">https://a.example</a></code>, <code><a href="https://c.example/">https://c.example</a></code>, <code><a href="https://x.example/doge.png">https://x.example/doge.png</a></code> }
</figcaption>
</figure>
<p>What if the iframe is nested multiple times? The user visits
<code>https://a.example</code>, which embeds an iframe (<code>https://b.example</code>), which embeds
yet another iframe (<code>https://c.example</code>), which finally requests the image.</p>
<p>Because the key is taken from the top-frame (<code>https://a.example</code>) and the
immediate frame which loads the resource (<code>https://c.example</code>), a cache hit
occurs.</p>
<div class="clearfix"></div>
<h2 id="faqs">FAQs</h2>
<h3 id="is-it-already-enabled-on-my-chrome-how-can-i-check-">Is it already enabled on my Chrome? How can I check?</h3>
<p>The feature is being rolled out through late 2020. To check whether your Chrome instance
already supports it:</p>
<ol>
<li>Open <code>chrome://net-export/</code> and press <strong>Start Logging to Disk</strong>.</li>
<li>Specify where to save the log file on your computer.</li>
<li>Browse the web on Chrome for a minute.</li>
<li>Go back to <code>chrome://net-export/</code> and press <strong>Stop Logging</strong>.</li>
<li>Go to <code>https://netlog-viewer.appspot.com/#import</code>.</li>
<li>Press <strong>Choose File</strong> and pass the log file you saved. </li>
</ol>
<p>You will see the output of the log file.</p>
<p>On the same page, find <code>SplitCacheByNetworkIsolationKey</code>. If it is followed by
<code>Experiment_[****]</code>, HTTP Cache partitioning is enabled on your Chrome. If it is
followed by <code>Control_[****]</code> or <code>Default_[****]</code>, it is not enabled.</p>
<h3 id="how-can-i-test-http-cache-partitioning-on-my-chrome-">How can I test HTTP Cache partitioning on my Chrome?</h3>
<p>To test HTTP Cache partitioning on your Chrome, you need to launch Chrome with a
command line flag: <code>--enable-features=SplitCacheByNetworkIsolationKey</code>. Follow
the instruction at <a href="https://www.chromium.org/developers/how-tos/run-chromium-with-flags">Run Chromium with
flags</a> to
learn how to launch Chrome with a command line flag on your platform.</p>
<h3 id="as-a-web-developer-are-there-any-action-i-should-take-in-response-to-this-change-">As a web developer, are there any action I should take in response to this change?</h3>
<p>This is not a breaking change, but it may impose performance considerations for
some web services.</p>
<p>For example, those that serve large volumes of highly cacheable resources across
many sites (such as fonts and popular scripts) may see an increase in their
traffic. Also, those who consume such services may have an increased reliance on
them.</p>
<p>(There's a proposal to enable shared libraries in a privacy-preserving way
called <a href="https://docs.google.com/document/d/1lQykm9HgzkPlaKXwpQ9vNc3m2Eq2hF4TY-Vup5wg4qg/edit#">Web Shared
Libraries</a>
(<a href="https://www.youtube.com/watch?v=cBY3ZcHifXw">presentation video</a>), but it's
still under consideration.)</p>
<h3 id="what-is-the-impact-of-this-behavioral-change-">What is the impact of this behavioral change?</h3>
<p>The overall cache miss rate increases by about 3.6%, changes to the FCP (First
Contentful Paint) are modest (~0.3%), and the overall fraction of bytes loaded
from the network increases by around 4%. You can learn more about the impact on
performance in <a href="https://github.com/shivanigithub/http-cache-partitioning#impact-on-metrics">the HTTP cache partitioning
explainer</a>.</p>
<h3 id="is-this-standardized-do-other-browsers-behave-differently-">Is this standardized? Do other browsers behave differently?</h3>
<p>"HTTP cache partitions" is <a href="https://fetch.spec.whatwg.org/#http-cache-partitions">standardized in the fetch
spec</a> though browsers
behave differently:</p>
<ul>
<li><strong>Chrome</strong>: Uses top-level scheme://eTLD+1 and frame scheme://eTLD+1</li>
<li><strong>Safari</strong>: Uses <a href="https://webkit.org/blog/8613/intelligent-tracking-prevention-2-1/">top-level eTLD+1</a></li>
<li><strong>Firefox</strong>: <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1536058">Planning to
implement</a> with
top-level scheme://eTLD+1 and considering including a second key like Chrome</li>
</ul>
<h3 id="how-is-fetch-from-workers-treated-">How is fetch from workers treated?</h3>
<p>Dedicated workers use the same key as their current frame. Service workers and
shared workers are more complicated since they may be shared among multiple
top-level sites. The solution for them is currently under discussion.</p>
<h2 id="resources">Resources</h2>
<ul>
<li><a href="https://docs.google.com/document/d/1V8sFDCEYTXZmwKa_qWUfTVNAuBcPsu6FC0PhqMD6KKQ/edit#heading=h.oixrt0wpp8h5">Storage Isolation
Project</a></li>
<li><a href="https://github.com/shivanigithub/http-cache-partitioning">Explainer - Partition the HTTP Cache</a></li>
</ul>
<h2 id="feedback">Feedback</h2>