公司的文章页面使用google PageSpeed Insights 分析过后,在移动端的表现分数很低,经过其分析,结果如下
从google分析给出的优化建议上来看,关键原因在于页面中使用了第3方youtube视频播放插件阻塞了页面的加载加载进程
google官方也给出了相关的解释Loading Third-Party JavaScript 以下是部分摘录
Loading Third-Party JavaScript
Third-party scripts provide a wide range of useful functionality, making the web more dynamic, interactive, and interconnected. These scripts may be crucial to your website's functionality or revenue stream. But third-party scripts also come with many risks that should be taken into consideration to minimize their impact while still providing value.
Why do you need to be careful about third-party scripts?
- They can be a performance concern
- They can be a privacy concern
- They might be a security concern
- They can be unpredictable and change without you knowing
- They can have unintended consequences
Ideally, you’ll want to ensure third-party script is not impacting the critical rendering path. In this guide, we’ll walk through how to find and fix issues related to loading third-party JavaScript.
What do we mean by third-party scripts?
Third-party JavaScript often refers to scripts that can be embedded into any site directly from a third-party vendor. These scripts can include ads, analytics, widgets and other scripts that make the web more dynamic and interactive.
Examples of third-party scripts include:
- Social sharing buttons (e.g Twitter, Facebook, G+)
- Video player embeds (e.g YouTube, Vimeo)
- Advertising iframes
- Analytics & metrics scripts
- A/B testing scripts for experiments
- Helper libraries (e.g date formatting, animation, functional libraries etc)
One example of this is the YouTube video player embed script that allows you to embed a video into your page.
Unfortunately, embedding third-party scripts means we often rely on them to be fast in order to avoid slowing our pages down. Third-party scripts are a predominant cause of performance slowdowns and are often caused by resources outside of your control.
These issues can include:
Firing too many network requests to multiple servers. The more requests a site has to make, the longer it can take to load.
Sending too much JavaScript that keeps the main thread busy. Too much JavaScript can block DOM construction, delaying how quickly pages can render. CPU-intensive script parsing and execution can delay user interaction and cause battery drain.
Sending large, unoptimized image files or videos. This can consume data and cost users money.
Third-party scripts loaded without care can be a single-point of failure (SPOF)
Insufficient HTTP caching, forcing resources to be fetched from the network often
Lack of sufficient server compression of resources
Blocking content display until they complete processing. This can also be true for async A/B testing scripts.
Use of legacy APIs (e.g document.write()) known to be harmful to the user experience
Excessive DOM elements or expensive CSS selectors.
Including multiple third party embeds can lead to multiple frameworks and libraries being pulled in several times. This is wasteful and exacerbates the performance issues.
Third-party scripts often use embed techniques that can block window.onload if their servers respond slowly, even if the embed is using async or defer.
Context is important and the solution to costly third-parties can depend on your site and ability to configure how third-party code is being loaded. Thankfully a number of solutions and tools exist to find and fix issues with third party resources.
How do you load third-party script efficiently?
If a third-party script is slowing down your page load, you have several options to improve performance:
Load the script using the async or defer attribute to avoid blocking document parsing.
Consider self-hosting the script if the third-party server is slow.
Consider removing the script if it doesn't add clear value to your site.
Consider Resource Hints like
<link rel=preconnect>
or<link rel=dns-prefetch>
to perform a DNS lookup for domains hosting third-party scripts.
Use async or defer
JavaScript execution is parser blocking. This means when the browser encounters a script it must pause DOM construction, hand this over to the JavaScript engine and allow script execution before proceeding with DOM construction.
The async and defer attributes change this behavior.
With async, the browser downloads the script asynchronously while it continues to parse the HTML document. When the script finishes downloading, parsing is blocked while the script executes.
With defer, the browser downloads the script asynchronously while it continues to parse the HTML document. The script doesn't run until the parsing is complete.
If that's too many words, here's a pretty picture:
In general, you should always use async or defer for third party scripts (unless the script does something necessary for the critical rendering path):
Use async if it's important to have the script run earlier in the loading process. This might include some analytics scripts, for example.
Use defer for less critical resources. A video player that's below-the-fold, for example.
Note: If performance is your primary concern, you could wait until your page has reached a key user moment (such as after the critical content has loaded) before adding async scripts. You should also take care not to
async
load libraries like jQuery just because they are coming from a third-party CDN.
Note: In Blink-based browsers,
async
anddefer
currently lower the priority of the network request for resources so it can cause it to load significantly later than it would as a blocking script. This is useful to know in particular for analytics scripts.
Should you ever load third-party scripts without async
or defer
? You could make a case for this if the script is a crucial part of your site functionality. For example, if you're loading your main UI library or framework from a CDN, it will be badged as "third-party script" in DevTools, but should be treated as an essential part of your site, not an add-on.
Note that not all scripts work if loaded asynchronously. Check the docs for any third-party scripts you're using. If you're using a script that can't be loaded asynchronously, you might want to consider an alternative, or eliminating the script if possible. Some third parties may highly recommend to load their scripts sync (to get ahead of other scripts), even if they would work fine async so do due diligence when evaluating strategies for loading third-party scripts.
Note:
async
is not a silver bullet. If a marketing team wants to load a large number of tracking scripts on a page, this number will still introduce bottlenecks that can impact how soon users can engage with a page on load.
Use Resource Hints to reduce connection setup time
Establishing connections to third-party origins can take a significant amount of time - particularly on slow networks. Many steps can add up to delays including DNS lookups, redirects, and potentially several round trips to each third-party server to handle the request.
You can use Resource Hints like to perform a DNS lookup for domains hosting third-party scripts. When the request for them is finally made, time can be saved as the DNS lookup has already been carried out.
<link rel="dns-prefetch" href="http://example.com">
If the third-party domain you are referencing uses HTTPS, you may also consider as this will both perform the DNS lookup and resolve TCP round-trips and handle TLS negotiations. These other steps can be very slow as they involve looking at SSL certificates for verification, so consider Resource Hints seriously if you find third-party setup time to be an issue.
<link rel="preconnect" href="https://cdn.example.com">
"Sandbox" scripts with an iframe
There are cases where third-party scripts can be loaded directly into an iframe. By restricting such scripts to iframes, they won’t block execution of the main page. This is the same approach that AMP takes to keeping JavaScript out of the critical path. Note that this approach will still block the onload
event so try not to attach critical functionality to onload
.
Note: Chrome is also exploring support for Feature Policy - a set of policies allowing a developer to selectively disable access to certain browser features. This can prevent third-party content introducing unwanted behaviors to a site.
Lazy-load Third Party Resources
Embedded third-party resources (such as ads or videos) can be a big contributor to slow page speed when constructed poorly. Lazy-loading can be used to only load embedded resources when necessary. For example, serving an ad in the footer only when a user scrolls down the page. Another pattern is lazy-loading content after the main page content loads but before a user might otherwise interact with the page.
Note: LazySizes is a popular JavaScript library for lazy-loading images and iframes. It supports YouTube embeds and widgets. Care does need to be taken when lazy-loading any resources as this technique is often powered by JavaScript and can be subject to issues on flaky network connections.
DoubleClick have guidance on how to lazy-load ads in their official documentation. If used properly, lazy loading can increase the overall viewability percentage of an ad. For example, Mediavine switched to lazy-loading ads and saw a 200% improvement in page load speed.
Efficient lazy-loading with Intersection Observer
Historically, solutions for detecting if an element is visible in the viewport (in order to lazy-load its content) have been error-prone, often causing the browser to become sluggish. Solutions have often listened for scroll or resize events, then used DOM APIs like getBoundingClientRect() to calculate where elements are relative to the viewport. This works, but is not efficient.
IntersectionObserver is a browser API that allows us to efficiently detect when an observed element enters or exits the browser's viewport. Learn more about how to use it for lazy-loading resources. LazySizes also has optional support for IntersectionObserver.
最后
Youtube视频插件处理
我们文章页使用了iframe引入youtube视频,采用延迟加载的方案,一开始iframe的src为空,页面加载完后再给iframe的src赋值视频地址即可。facebook插件也是同样的处理方案
<iframe width="640" height="360" yt-src="https://www.youtube.com/embed/Pl0t2Kz-ccY" frameborder="0"
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
$(function() {
// 定时器防止进程阻塞
setTimeout(function() {
// facebook like plugin Delay loading to prevent blocking process
$.fbLike()
var yturl = $("iframe[yt-src]").attr("yt-src")
// youtube video Delay loading to prevent blocking process
$("iframe[yt-src]").attr("src", yturl)
}, 3000)
})