Next.js 12.3集成GTM后如何消除未使用JS以优化性能?
如何将Next.js中GTM导致的未使用JS耗时降至零?
你当前在Next.js 12.3.0中集成GTM的方式功能正常,但afterInteractive策略会在页面交互后立即加载GTM脚本,而GTM容器可能包含大量当前页面不需要的标签代码,这就是未使用JS耗时的核心来源。以下是几种可行的优化方案:
1. 切换脚本加载策略为lazyOnload
将_app.tsx中Script组件的strategy从afterInteractive改为lazyOnload,该策略会在页面完全加载、浏览器进入空闲状态后才加载脚本,完全不影响首屏性能,同时能保留GTM的全部统计功能:
import Script from "next/script"; <Script id="gtag-base" strategy="lazyOnload" dangerouslySetInnerHTML={{ __html: ` (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer', '${process.env.NEXT_PUBLIC_GTM_KEY}'); `, }} />
2. 精简GTM容器内部代码
GTM后台的冗余配置是未使用JS的主要来源,直接在GTM控制台优化:
- 清理所有未使用的标签、触发器和变量,只保留当前业务必需的配置
- 启用标签延迟加载:在容器设置中开启延迟加载,让非关键标签在页面空闲时触发
- 确保容器压缩选项已启用:GTM默认会压缩输出代码,进一步减少冗余体积
3. 按路由条件加载GTM
如果不是所有页面都需要GTM统计,可以根据路由判断是否加载脚本,比如仅在非首页加载:
import Script from "next/script"; import { useRouter } from "next/router"; export default function MyApp({ Component, pageProps }) { const router = useRouter(); // 示例:仅在非首页加载GTM const loadGTM = router.pathname !== "/"; return ( <> {loadGTM && ( <Script id="gtag-base" strategy="lazyOnload" dangerouslySetInnerHTML={{ __html: ` (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer', '${process.env.NEXT_PUBLIC_GTM_KEY}'); `, }} /> )} <Component {...pageProps} /> </> ); }
4. 动态导入GTM组件(禁用SSR)
把GTM脚本封装成独立组件,通过Next.js的动态导入禁用SSR,确保脚本仅在客户端加载,且不占用服务端资源:
// components/GTMScript.tsx import Script from "next/script"; export default function GTMScript() { return ( <Script id="gtag-base" strategy="lazyOnload" dangerouslySetInnerHTML={{ __html: ` (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer', '${process.env.NEXT_PUBLIC_GTM_KEY}'); `, }} /> ); } // _app.tsx import dynamic from "next/dynamic"; // 禁用SSR,仅客户端加载 const GTMScript = dynamic(() => import("../components/GTMScript"), { ssr: false }); export default function MyApp({ Component, pageProps }) { return ( <> <GTMScript /> <Component {...pageProps} /> </> ); }
以上方案组合使用,基本可以将GTM导致的未使用JS耗时降至接近零,同时保留所需的统计功能。
内容的提问来源于stack exchange,提问作者mohsin hussain
相关产品推荐
相关产品推荐

