SMASHINGMAGAZINE.COM
Tight Mode: Why Browsers Produce Different Performance Results
This article is a sponsored by DebugBearI was chatting with DebugBears Matt Zeunert and, in the process, he casually mentioned this thing called Tight Mode when describing how browsers fetch and prioritize resources. I wanted to nod along like I knew what he was talking about but ultimately had to ask: What the heck is Tight mode?What I got back were two artifacts, one of them being the following video of Akamai web performance expert Robin Marx speaking at We Love Speed in France a few weeks ago:Tight Mode discriminates resources, taking anything and everything marked as High and Medium priority. Everything else is constrained and left on the outside, looking in until the body is firmly attached to the document, signaling that blocking scripts have been executed. Its at that point that resources marked with Low priority are allowed in the door during the second phase of loading.Theres a big caveat to that, but well get there. The important thing to note is thatChrome And Safari Enforce Tight ModeYes, both Chrome and Safari have some working form of Tight Mode running in the background. That last image illustrates Chromes Tight Mode. Lets look at Safaris next and compare the two.Look at that! Safari discriminates High-priority resources in its initial fetch, just like Chrome, but we get wildly different loading behavior between the two browsers. Notice how Safari appears to exclude the first five PNG images marked with Medium priority where Chrome allows them. In other words, Safari makes all Medium- and Low-priority resources wait in line until all High-priority items are done loading, even though were working with the exact same HTML. You might say that Safaris behavior makes the most sense, as you can see in that last image that Chrome seemingly excludes some High-priority resources out of Tight Mode. Theres clearly some tomfoolery happening there that well get to.Wheres Firefox in all this? It doesnt take any extra tightening measures when evaluating the priority of the resources on a page. We might consider this the classic waterfall approach to fetching and loading resources.Chrome And Safari Trigger Tight Mode DifferentlyRobin makes this clear as day in his talk. Chrome and Safari are both Tight Mode proponents, yet trigger it under differing circumstances that we can outline like this: Chrome Safari Tight Mode triggered While blocking JS in the <head> is busy. While blocking JS or CSS anywhere is busy. Notice that Chrome only looks at the document <head> when prioritizing resources, and only when it involves JavaScript. Safari, meanwhile, also looks at JavaScript, but CSS as well, and anywhere those things might be located in the document regardless of whether its in the <head> or <body>. That helps explain why Chrome excludes images marked as High priority in Figure 2 from its Tight Mode implementation it only cares about JavaScript in this context.So, even if Chrome encounters a script file with fetchpriority="high" in the document body, the file is not considered a High priority and it will be loaded after the rest of the items. Safari, meanwhile, honors fetchpriority anywhere in the document. This helps explain why Chrome leaves two scripts on the table, so to speak, in Figure 2, while Safari appears to load them during Tight Mode.Thats not to say Safari isnt doing anything weird in its process. Given the following markup:<head> <!-- two high-priority scripts --> <script src="script-1.js"></script> <script src="script-1.js"></script> <!-- two low-priority scripts --> <script src="script-3.js" defer></script> <script src="script-4.js" defer></script></head><body> <!-- five low-priority scripts --> <img src="image-1.jpg"> <img src="image-2.jpg"> <img src="image-3.jpg"> <img src="image-4.jpg"> <img src="image-5.jpg"></body>you might expect that Safari would delay the two Low-priority scripts in the <head> until the five images in the <body> are downloaded. But thats not the case. Instead, Safari loads those two scripts during its version of Tight Mode.Chrome And Safari ExceptionsI mentioned earlier that Low-priority resources are loaded in during the second phase of loading after Tight Mode has been completed. But I also mentioned that theres a big caveat to that behavior. Lets touch on that now.According to Patricks article, we know that Tight Mode is the initial phase and constraints loading lower-priority resources until the body is attached to the document (essentially, after all blocking scripts in the head have been executed). But theres a second part to that definition that I left out:In tight mode, low-priority resources are only loaded if there are less than two in-flight requests at the time that they are discovered.A-ha! So, there is a way for low-priority resources to load in Tight Mode. Its when there are less than two in-flight requests happening when theyre detected.Wait, what does in-flight even mean?Thats whats meant by less than two High- or Medium-priority items being requested. Robin demonstrates this by comparing Chrome to Safari under the same conditions, where there are only two High-priority scripts and ten regular images in the mix:<head> <!-- two high-priority scripts --> <script src="script-1.js"></script> <script src="script-1.js"></script></head><body> <!-- ten low-priority images --> <img src="image-1.jpg"> <img src="image-2.jpg"> <img src="image-3.jpg"> <img src="image-4.jpg"> <img src="image-5.jpg"> <!-- rest of images --> <img src="image-10.jpg"></body>Lets look at what Safari does first because its the most straightforward approach:Nothing tricky about that, right? The two High-priority scripts are downloaded first and the 10 images flow in right after. Now lets look at Chrome:We have the two High-priority scripts loaded first, as expected. But then Chrome decides to let in the first five images with Medium priority, then excludes the last five images with Low priority. What. The. Heck.The reason is a noble one: Chrome wants to load the first five images because, presumably, the Largest Contentful Paint (LCP) is often going to be one of those images and Chrome is hedging bets that the web will be faster overall if it automatically handles some of that logic. Again, its a noble line of reasoning, even if it isnt going to be 100% accurate. It does muddy the waters, though, and makes understanding Tight Mode a lot harder when we see Medium- and Low-priority items treated as High-priority citizens.Even muddier is that Chrome appears to only accept up to two Medium-priority resources in this discriminatory process. The rest are marked with Low priority.Thats what we mean by less than two in-flight requests. If Chrome sees that only one or two items are entering Tight Mode, then it automatically prioritizes up to the first five non-critical images as an LCP optimization effort.Truth be told, Safari does something similar, but in a different context. Instead of accepting Low-priority items when there are less than two in-flight requests, Safari accepts both Medium and Low priority in Tight Mode and from anywhere in the document regardless of whether they are located in the <head> or not. The exception is any asynchronous or deferred script because, as we saw earlier, those get loaded right away anyway.How To Manipulate Tight ModeThis might make for a great follow-up article, but this is where Ill refer you directly to Robins video because his first-person research is worth consuming directly. But heres the gist:We have these high-level features that can help influence priority, including resource hints (i.e., preload and preconnect), the Fetch Priority API, and lazy-loading techniques.We can indicate fetchpriority=`"high"andfetchpriority="low"` on items.<img src="lcp-image.jpg" fetchpriority="high"><link rel="preload" href="defer.js" as="script" fetchpriority="low"Using fetchpriority="high" is one way we can get items lower in the source included in Tight Mode. Using fetchpriority="low is one way we can get items higher in the source excluded from Tight Mode.For Chrome, this works on images, asynchronous/deferred scripts, and scripts located at the bottom of the <body>.For Safari, this only works on images.Again, watch Robins talk for the full story starting around the 28:32 marker.Thats Tight ModeIts bonkers to me that there is so little information about Tight Mode floating around the web. I would expect something like this to be well-documented somewhere, certainly over at Chrome Developers or somewhere similar, but all we have is a lightweight Google Doc and a thorough presentation to paint a picture of how two of the three major browsers fetch and prioritize resources. Let me know if you have additional information that youve either published or found Id love to include them in the discussion.
0 التعليقات
0 المشاركات
45 مشاهدة