You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS中延迟加载Stripe组件优化页面性能的方案咨询

NextJS集成Stripe Elements后移动端Pagespeed评分骤降的优化问题

我首次使用NextJS开发网站,原本移动端Pagespeed评分稳定在93-99区间,但集成Stripe Elements后评分骤降至约50。我尝试通过@stripe/stripe-js/pure路径导入Stripe:

import { loadStripe } from '@stripe/stripe-js/pure';

这种方式仍会在<head>中引入外部Stripe脚本<script src="https://js.stripe.com/v3"></script>,页面评分仅略有提升至58-63,未达预期效果。

我的Stripe集成基于React库,核心代码如下:

PurchaseSection组件

import React, { useEffect, useState } from 'react';
import { Elements } from '@stripe/react-stripe-js';

import ElementForm from './ElementForm';
import getStripe from '../lib/get-stripejs';

const PurchaseSection = () => {
  const [ stripePromise, setStripePromise ] = useState(null);
  const [ clientSecret, setClientSecret ] = useState('');

useEffect(() => {
    fetch('api/keys', {
        method: 'GET',
        headers: { 'Content-Type': 'application/json' },
    })
    .then((res) => res.json())
    .then((data) => {
        setStripePromise(getStripe(data.publishableKey));
    });
  }, []);

  useEffect(() => {
    fetch('api/create-payment-intent', {
      method: 'POST',
      header: { 'Content-Type': 'applcation/json' },
      body: JSON.stringify({
        productId: '34032255',
        productType: 'seminar'
      })
    })
    .then(async (res) => {
      const { clientSecret } = await res.json();
      setClientSecret(clientSecret);
    });
  }, [])

  return (  
    <section>
      {stripePromise && clientSecret && (
        <Elements stripe={stripePromise} options={{ clientSecret }}>
          <ElementForm />
        </Elements>
      )}
    </section>
  )
}

lib/get-stripejs

import { loadStripe } from '@stripe/stripe-js/pure';

let stripePromise;

const getStripe = (publishableKey) => {
    if (!stripePromise) {
        stripePromise = loadStripe(publishableKey);
    }
    return stripePromise;
}
 
export default getStripe

ElementForm组件

import React, { useState } from "react";
import { PaymentElement, useStripe, useElements } from '@stripe/react-stripe-js';


function ElementForm({ paymentIntent = null }) {
    const stripe = useStripe();
    const elements = useElements();

    const [ isProcessing, setIsProcessing ] = useState(false);

    async function handleSubmit(e) {
        // do stuff
    }

    return (
      <form id='payment-form' onSubmit={handleSubmit}>
        <div id='payment-element'>
          <PaymentElement />
        </div>
        <button disabled={isProcessing} type='submit'>
          {isProcessing ? 'Processing...' : 'Submit'}
        </button>
      </form>
    );
}

export default ElementForm

目前不确定问题出在<PaymentElement>、loadStripe方法,还是两者共同导致。我希望利用next/script提供的加载策略,但该策略似乎仅适用于带src的远程脚本,因此有两个疑问:

  • a) 是否可将next/script的加载策略直接应用于组件而非远程脚本?
  • b) 更通用地说,在NextJS中如何延迟加载所有Stripe相关内容?(注:<PurchaseSection>组件位于首屏下方,无需提前加载)

内容的提问来源于stack exchange,提问作者philolegein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 05:55:46