如何加速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
相关产品推荐
相关产品推荐

