red*_* 87 5 javascript reactjs next.js
我在一个项目中使用 Next JS,我正在使用 Google 的 Page Speed Insights 工具进行一些优化。对我的网站性能产生负面影响的主要因素之一是 3rd 方脚本,主要是 Google Tag 脚本(也加载了我的 Google Analytics)和 Google 地图 API 脚本。到目前为止,我已经尝试了几种方法来抵消这两个库的加载,但我仍然从该工具中收到以下消息:
删除未使用的 JavaScript
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)
Run Code Online (Sandbox Code Playgroud)
我需要在网站上的任何地方加载这些脚本,所以我试图延迟脚本的加载,直到页面上的所有其他内容都完成加载。这是我最初拥有的:
_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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我只是defer像往常一样使用道具加载脚本。然而,使用这种方法谷歌页面速度洞察仍然给我同样的信息。然后我尝试了一种不同的方法,使用 Next JS 中的一个实验组件,该组件ScriptLoader旨在允许人们推迟脚本。这是该组件的链接:
https://github.com/vercel/next.js/discussions/18172
这是我的实现:
_app.js
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"
/>
</>)
}
}
Run Code Online (Sandbox Code Playgroud)
然而,它仍然给我同样的错误信息。我不知道现在该尝试什么!有没有其他人遇到过这个问题并找到了解决方法?
谢谢
谷歌分析/Gtag
根据我自己的经验,我必须不幸地告诉您,延迟加载分析并不是一个好主意,并且在调用尚不存在的函数时通常会导致意外错误。因此,最好在一开始就加载它,即使谷歌因为使用他们自己的脚本而惩罚你,这很糟糕。所以我认为您通过自定义_document.js文件加载gtag的初始方法很好。
谷歌地图
感谢上帝,谷歌地图的情况有所不同。有一个名为Google Maps JavaScript API Loader的 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
}
};
Run Code Online (Sandbox Code Playgroud)
您可以将其放在useEffect钩子中,甚至可以在用户将鼠标悬停在某处或单击某物时调用它,从而将导入延迟更长时间。
我最近正在使用更复杂的 GTM 配置处理同样的问题。我可以分享我的方法。
首先,在 Lighthouse 中,“删除未使用的 JavaScript”并不意味着整个文件不被使用。它实际上只是告诉您给定文件中有很大一部分未使用的代码。如果它是某个第三方文件,我们可能无法对其采取任何措施。
此外,每个 JavaScript 文件(包括分析)都会对性能产生影响。理想情况下,仅在成本合理时才支付价格(基本分析、应用程序监控服务等......)。
目标
目标不是解决“删除未使用的 JavaScript”。真正的目标应该是通过推迟加载 JavaScript 来减少 JavaScript 的影响,以便可以尽快加载其他更重要的页面内容。
异步标签
GTM 本身并没有很大的性能占用。这实际上取决于 GTM 容器内的内容。我认为 GTM 加载async标签就可以了。
Google Maps API 可以通过 GTM 异步加载。我们可以更准确地决定何时加载它。
加载中
对于不需要立即交付的脚本,例如 Google Map API,您可能不想加载它们,Container Loaded因为它将占用可用于加载真实页面内容的宝贵资源。您应该考虑将其移至Window Loaded. 此时,页面已完全加载,对 Google Web Core Vita 的影响应该是最小的。
对于分析,理想情况下,应尽早加载它们以更准确地捕获数据。但是,这可能会根据业务需求而改变。对于我的组织,我们将一些分析转移到Window Loaded阶段。原因是我们希望获得更好的页面加载性能,并且我们并不真正关心在页面加载之前跳出的用户。
如果需要进一步延迟,我们可以创建一个额外的触发器,在几毫秒的超时后触发。更详细的内容可以参考这篇博文
一个潜在的解决方案
总之,这是我会采用的方法。它与我的团队在项目中使用的类似。
Next.js仅加载带有属性的GTM async。我希望它有意义并且有帮助。
参考
| 归档时间: |
|
| 查看次数: |
1175 次 |
| 最近记录: |