Javascript 使用下一个JS延迟脚本
我正在一个项目中使用NextJS,我正在使用Google的PageSpeedInsights工具进行一些优化。我的网站性能的主要负面因素之一是第三方脚本,主要是谷歌标签脚本(它也加载我的谷歌分析)和谷歌地图API脚本。到目前为止,我已经尝试了几种方法来抵消这两个库的加载,但我仍然从该工具中获得以下消息: 删除未使用的JavaScriptJavascript 使用下一个JS延迟脚本,javascript,reactjs,next.js,Javascript,Reactjs,Next.js,我正在一个项目中使用NextJS,我正在使用Google的PageSpeedInsights工具进行一些优化。我的网站性能的主要负面因素之一是第三方脚本,主要是谷歌标签脚本(它也加载我的谷歌分析)和谷歌地图API脚本。到目前为止,我已经尝试了几种方法来抵消这两个库的加载,但我仍然从该工具中获得以下消息: 删除未使用的JavaScript https://maps.googleapis.com/maps/api/js?key=asdafsafasafasfasf&libraries=pla
https://maps.googleapis.com/maps/api/js?key=asdafsafasafasfasf&libraries=places&language=en®ion=US
(maps.googleapis.com)
https://www.googletagmanager.com/gtag/js?id=UA-123123-2
(www.googletagmanager.com)
我需要将这些脚本加载到站点的任何地方,因此我尝试延迟加载脚本,直到页面上的所有其他内容都加载完毕。以下是我最初拥有的:
\u document.js
import Document, { Head, Main, NextScript, Html } from "next/document";
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
<Html lang="en">
<Head>
<script
defer
src={`https://www.googletagmanager.com/gtag/js?id=UA-123123-2`}
/>
<script
defer
src="https://maps.googleapis.com/maps/api/js?key=asdafsafasafasfasf&libraries=places&language=en®ion=US"
/>
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-123123-2');
`,
}}
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
import App from "next/app";
import ScriptLoader from "next/dist/client/experimental-script.js";
export default class NextApp extends App {
render() {
return (<>
<ScriptLoader
strategy="defer"
src="https://www.googletagmanager.com/gtag/js?id=UA-123123-2"
/>
<ScriptLoader
strategy="defer"
src="https://maps.googleapis.com/maps/api/js?key=asdafsafasafasfasf&libraries=places&language=en®ion=US"
/>
</>)
}
}
然而,它仍然给我同样的错误信息。我不知道现在该试什么!是否有其他人遇到此问题并找到了解决方法
谢谢我最近正在用更复杂的GTM配置处理同样的问题。我可以分享我的方法 首先,在Lighthouse中,“删除未使用的JavaScript”并不意味着不使用整个文件。它实际上只是告诉您,给定文件中有大量未使用的代码。如果是某个第三方文件,我们可能对此无能为力 此外,每个JavaScript文件(包括分析)都会对性能产生影响。理想情况下,只有在成本合理的情况下(基本分析、应用程序监控服务等…)才支付费用 目标 目标不是解决“删除未使用的JavaScript”。真正的目标应该是通过延迟加载JavaScript来减少JavaScript的影响,以便尽可能快地加载其他更重要的页面内容。 异步标记 GTM本身并没有很大的性能足迹。这实际上取决于GTM容器中的内容。我认为用
async
标记加载GTM是可以的
谷歌地图API可以通过GTM异步加载。我们可以更精确地决定何时加载它
GTM加载
对于不需要立即交付的脚本,例如Google Map API,您可能不希望将它们加载到加载的容器上,因为这将占用宝贵的资源,可以用来加载真实的页面内容。您应该考虑将其移动到<代码>窗口加载。在这一点上,页面已经被完全加载,对谷歌网站核心Vita的影响应该是最小的
对于分析,理想情况下,应该尽早加载它们,以便更精确地捕获数据。但是,这可能会根据业务需求而改变。对于我的组织,我们将一些分析移到窗口加载
阶段。原因是我们希望有更好的页面加载性能,并且我们并不真正关心在页面加载之前反弹的用户
如果需要进一步的延迟,我们可以创建一个额外的触发器,在超时几毫秒后触发。有关更多详细信息,请参阅此
潜在的解决方案
总之,这是一种我愿意采用的方法。这与我的团队在我们的项目中使用的类似
- 仅使用
async
属性在Next.js
中加载GTM
- 将谷歌分析和谷歌地图API移至GTM
- 在对业务/项目/用户仍有意义的情况下,尽可能延迟加载时间
我希望这是有意义的,是有益的
参考资料
import Document, { Head, Main, NextScript, Html } from "next/document";
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
<Html lang="en">
<Head>
<script
defer
src={`https://www.googletagmanager.com/gtag/js?id=UA-123123-2`}
/>
<script
defer
src="https://maps.googleapis.com/maps/api/js?key=asdafsafasafasfasf&libraries=places&language=en®ion=US"
/>
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-123123-2');
`,
}}
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
import App from "next/app";
import ScriptLoader from "next/dist/client/experimental-script.js";
export default class NextApp extends App {
render() {
return (<>
<ScriptLoader
strategy="defer"
src="https://www.googletagmanager.com/gtag/js?id=UA-123123-2"
/>
<ScriptLoader
strategy="defer"
src="https://maps.googleapis.com/maps/api/js?key=asdafsafasafasfasf&libraries=places&language=en®ion=US"
/>
</>)
}
}
谷歌分析/Gtag
根据我自己的经验,我不得不遗憾地告诉你,延迟分析加载不是一个好主意,当调用一个不存在的函数时,常常会导致意外错误。所以最好在一开始就加载它,即使谷歌因为你使用他们自己的脚本而惩罚你,这很糟糕。因此,我认为您最初通过定制的document.js文件加载gtag的方法很好
谷歌地图
import Document, { Head, Main, NextScript, Html } from "next/document";
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
<Html lang="en">
<Head>
<script
defer
src={`https://www.googletagmanager.com/gtag/js?id=UA-123123-2`}
/>
<script
defer
src="https://maps.googleapis.com/maps/api/js?key=asdafsafasafasfasf&libraries=places&language=en®ion=US"
/>
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-123123-2');
`,
}}
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
import App from "next/app";
import ScriptLoader from "next/dist/client/experimental-script.js";
export default class NextApp extends App {
render() {
return (<>
<ScriptLoader
strategy="defer"
src="https://www.googletagmanager.com/gtag/js?id=UA-123123-2"
/>
<ScriptLoader
strategy="defer"
src="https://maps.googleapis.com/maps/api/js?key=asdafsafasafasfasf&libraries=places&language=en®ion=US"
/>
</>)
}
}
感谢上帝,谷歌地图与众不同。有一个名为npm的包。这使得动态加载贴图成为可能,或者更容易。除此之外,您还可以利用JavaScript的功能。您可以创建一个自定义加载函数,该函数只能在满足某些条件后启动。它可能是这样的:
const myCustomLoadFunction = async () => {
try {
const { Loader } = await import("@googlemaps/js-api-loader");
const loader = new Loader({
apiKey: "YOUR_API_KEY",
version: "weekly",
// ...additionalOptions,
});
const mapOptions = {
center: { lat: 0, lng: 0 },
zoom: 4,
};
await loader.load();
new google.maps.Map(document.getElementById("map"), mapOptions);
} catch (e) {
// do something
}
};
您可以将其放置在useffect
钩子中,甚至在用户悬停在某个位置或单击某个对象时调用它,从而将导入延迟更长时间。我提供了此选项,因为它尚未出现在此处。这并不意味着这个解决方案是最好的。加载DOM内容后开始加载脚本的方法。我认为它可以插入\u document.js而不是上述三个脚本
我使用setTimeout
将此任务放入事件队列,0表示它将尽快发生
<script
dangerouslySetInnerHTML={{
__html: `
document.addEventListener("DOMContentLoaded", function(event) {
setTimeout(function() {
var gtag = document.createElement('script');
gtag.type = 'text/javascript';
gtag.async = true;
var gmaps = gtag.cloneNode(false);
gtag.src = "https://www.googletagmanager.com/gtag/js?id=UA-123123-2"
gmaps.src = "https://maps.googleapis.com/maps/api/js?key=asdafsafasafasfasf&libraries=places&language=en®ion=US"
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gtag, s);
s.parentNode.insertBefore(gmaps, s);
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-123123-2');
}, 0)
});
`,
}}
/>
如果我错了,请纠正我的错误,但是延迟脚本加载不会帮助您处理那些外部脚本中未使用的JavaScript。无论何时加载脚本,您仍然会使用相同的代码。在页面加载速度方面,我可以想象Google并不关心DOM加载完所有其他内容后加载的脚本,否?在这种情况下,您可能应该尝试使用async
属性。我尝试了async,但不幸的是,它具有相同的效果。当尽早加载时,分析效果最好。此外,所有分析都会损害性能,因此这始终是一种折衷。这里重要的一点是,用户在每个域中加载此脚本一次。如果可能的话,您可以使用更轻的分析工具,比如Fathom