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

如何加速Netlify上Node.js中Nodemailer的邮件发送速度?

邮件发送耗时优化问题(Netlify Node.js环境)

在Netlify上运行的Node.js代码中,邮件发送环节耗时极长,发送两封邮件有时需要5到12秒。我并不关心Nodemailer的返回结果,但尝试移除最后try块中的await并将sendEmail改为同步函数后,邮件无法发送,推测是函数返回200后进程就停止运行导致的。求加速这一过程的方法。

相关代码

主函数代码

const sendEmail = require('./sendmail')
async function checkout() {
    try {
        await someFunction()
    } catch(e) {}
    try {
        await someOtherFunction()
    } catch(e) {}
    try {
        await sendEmail.sendCustomer(subject, body, to)  // await or not?
        await sendEmail.sendOurself(subject, body, to)   // await or not?
    }
    finally {
        return {
            statusCode: 200
        }
    }
}

邮件发送函数代码

const nodemailer = require('nodemailer')
async function sendEmail(subject, body, to) {

    const transporter = nodemailer.createTransport({
        host: HOST,
        port: PORT,
        secure: SECURE,
        auth: { user: AUTH.user, pass: AUTH.pass,}
    });

    const mailOptions = {
        from: AUTH.user,
        to: to,
        subject: subject,
        html: body,
    };

    return await transporter.sendMail(mailOptions)
};

exports.sendEmail = sendEmail

优化方案

1. 复用邮件传输对象(Transporter)

当前代码每次调用sendEmail都会重新创建transporter,重复建立邮件服务器连接是耗时的核心原因之一。将transporter的创建移到模块顶层,仅初始化一次:

const nodemailer = require('nodemailer')

// 模块加载时仅创建一次transporter,复用连接池
const transporter = nodemailer.createTransport({
    host: HOST,
    port: PORT,
    secure: SECURE,
    auth: { user: AUTH.user, pass: AUTH.pass }
});

async function sendEmail(subject, body, to) {
    const mailOptions = {
        from: AUTH.user,
        to: to,
        subject: subject,
        html: body,
    };

    // 直接返回Promise,无需额外await
    return transporter.sendMail(mailOptions)
};

exports.sendEmail = sendEmail

2. 并行发送两封邮件

原来的代码串行发送两封邮件,耗时是两者之和。改用Promise.all并行发送,能将耗时压缩到接近单封邮件的发送时间:

async function checkout() {
    try {
        await someFunction()
    } catch(e) {}
    try {
        await someOtherFunction()
    } catch(e) {}
    try {
        // 并行执行两个邮件发送任务
        await Promise.all([
            sendEmail.sendCustomer(subject, body, to),
            sendEmail.sendOurself(subject, body, to)
        ])
    } catch(e) {
        // 捕获错误,避免影响主流程返回
        console.error('邮件发送失败:', e)
    } finally {
        return {
            statusCode: 200
        }
    }
}

3. 异步非阻塞返回(不等待邮件发送完成)

如果不需要确保邮件发送完成再返回响应,可以启动邮件发送任务后直接返回200,同时捕获错误避免未处理Promise告警:

async function checkout() {
    try {
        await someFunction()
    } catch(e) {}
    try {
        await someOtherFunction()
    } catch(e) {}
    // 启动邮件发送任务但不等待完成,捕获错误避免控制台异常
    Promise.all([
        sendEmail.sendCustomer(subject, body, to),
        sendEmail.sendOurself(subject, body, to)
    ]).catch(err => console.error('邮件发送出错:', err))
    // 直接返回响应,无需等待邮件发送
    return {
        statusCode: 200
    }
}

注意:Netlify函数在返回响应后会保留短暂的执行时间用于收尾异步任务,但如果邮件发送耗时超过这个缓冲时间,可能会被终止。如果需要绝对确保邮件发送成功,建议结合Netlify Background Functions处理异步任务,但如果只是追求响应速度,上述方法足够。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:15:44