html-pdf 在 firebase 云函数中运行速度很慢
html-pdf runs very slow in firebase cloud functions
我开发了一个功能,可以获取一页 HTML,使用 htmp-pdf 包将其转换为 PDF 并上传到 firebase 存储。当我从我的电脑 运行 这个功能需要不到 5 秒,但是当我从 firebase 功能 运行 它需要最多 6 分钟。这是代码:
pdf.create(estadoCuenta, { orientation: 'portrait', type: 'pdf', timeout: '360000' }).toStream(function(err, stream) {
console.log('Nombre del archivo generado: ' + file.name);
stream.pipe(file.createWriteStream({
metadata: {
contentType: 'application/pdf',
metadata: {
origin: 'created by ...'
}
},
public: true,
validation: "md5"
}))
.on('error', function(err) {
console.log('error en la carga de archivo: ' + err);
})
.on('finish', function() {
// The file upload is complete.
let estadoCuentaPDF = file.name.replace('/','%2F');
console.log('estadoCuentaPDF:' + estadoCuentaPDF);
});
});
变量“estadoCuenta”包含要转换的html。
这是我的 package.json:
{
"name": "dialogflowFirebaseFulfillment",
"description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
"version": "0.0.1",
"author": "xxx",
"repository": "https://yyy@bitbucket.org/zzz/www.git",
"license": "xxx",
"private": true,
"scripts": {
"start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
"deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
},
"engines": {
"node": "10"
},
"dependencies": {
"-": "0.0.1",
"@google-cloud/firestore": "^3.7.5",
"actions-on-google": "^2.10.0",
"cors": "^2.8.5",
"dialogflow": "^1.2.0",
"dialogflow-fulfillment": "^0.6.1",
"dotenv": "^8.2.0",
"envfile": "^6.9.0",
"express": "^4.17.1",
"firebase-admin": "^8.0.0",
"firebase-functions": "^3.6.1",
"firebase-tools": "^7.4.0",
"html-pdf": "^2.2.0",
"isomorphic-fetch": "^2.2.1",
"node-env-file": "^0.1.8",
"nodejs-base64": "^1.0.3",
"nodemailer": "^6.3.0",
"pg": "^7.18.2",
"string-similarity": "^3.0.0",
"twilio": "^3.31.1",
"unirest": "^0.6.0"
}
}
这是因为分配给函数的计算资源无法与您的本地设备相媲美。
云函数的 CPU 速度与分配的内存成正比 document,请尝试为您的函数设置 2GB 内存。
处理资源越多,您的功能就会越快。
如果函数没有在您可接受的时间内响应,下一步是使用另一个无服务器产品,例如 App Engine or Cloud Run,它允许您为应用程序设置更多资源。
这些更改将影响您的帐单。
我调整了您的示例,它适用于非常小的 HTML 文件和 256MB 的内存分配。我保留了您的包裹以尝试重现您的使用情况。我使用了一个内联的非常小的 HTML 文档,我使用了 Node.JS 12 并且我替换了例如file
与 fs
。我不是一个 Node.JS 开发人员,所以对糟糕的代码表示歉意。
/* jshint esversion: 6 */
/* globals exports,require */
const pdf = require("html-pdf");
const fs = require("fs");
const estadoCuenta = `<html><head><title>Whosebug: 63688028</title></head><body><div id="content">Hello Freddie!</div></body></html>`;
const convertor = (req, res) => {
// Write it
const options = { orientation: 'portrait', type: 'pdf', timeout: '360000' };
pdf.create(estadoCuenta, options).toStream(function (err, stream) {
var writeStream = fs.createWriteStream("/tmp/file.pdf");
stream.pipe(writeStream).on('error', function (err) {
console.log(`[stream.pipe] Error: ${err}`);
}).on('finish', function () {
// Read it
var readStream = fs.createReadStream('/tmp/file.pdf');
var filename = encodeURIComponent("converted.pdf");
res.setHeader('Content-disposition', `inline; filename="${filename}"`);
res.setHeader('Content-type', 'application/pdf');
readStream.pipe(res);
console.log(`Done`);
});
});
};
exports.convertor = convertor;
为了本地调试,我附加了以下内容:
const express = require("express");
const app = express();
const port = 3000;
app.get("/", convertor);
app.listen(port, () => {
console.log(`Listening: http://localhost:${port}`);
});
package.json
中有许多依赖项,我假设您需要它们。部署到 Cloud Functions 时不需要导入 express
。
注意 html-pdf
包括一个严重的漏洞:
=== npm audit security report ===
Manual Review
Some vulnerabilities require your attention to resolve
Visit https://go.npm.me/audit-guide for additional guidance
Critical Arbitrary File Read
Package html-pdf
Patched in No patch available
Dependency of html-pdf
Path html-pdf
More info https://npmjs.com/advisories/1095
found 1 critical severity vulnerability in 750 scanned packages
1 vulnerability requires manual review. See the full report for details.
我开发了一个功能,可以获取一页 HTML,使用 htmp-pdf 包将其转换为 PDF 并上传到 firebase 存储。当我从我的电脑 运行 这个功能需要不到 5 秒,但是当我从 firebase 功能 运行 它需要最多 6 分钟。这是代码:
pdf.create(estadoCuenta, { orientation: 'portrait', type: 'pdf', timeout: '360000' }).toStream(function(err, stream) {
console.log('Nombre del archivo generado: ' + file.name);
stream.pipe(file.createWriteStream({
metadata: {
contentType: 'application/pdf',
metadata: {
origin: 'created by ...'
}
},
public: true,
validation: "md5"
}))
.on('error', function(err) {
console.log('error en la carga de archivo: ' + err);
})
.on('finish', function() {
// The file upload is complete.
let estadoCuentaPDF = file.name.replace('/','%2F');
console.log('estadoCuentaPDF:' + estadoCuentaPDF);
});
});
变量“estadoCuenta”包含要转换的html。
这是我的 package.json:
{
"name": "dialogflowFirebaseFulfillment",
"description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
"version": "0.0.1",
"author": "xxx",
"repository": "https://yyy@bitbucket.org/zzz/www.git",
"license": "xxx",
"private": true,
"scripts": {
"start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
"deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
},
"engines": {
"node": "10"
},
"dependencies": {
"-": "0.0.1",
"@google-cloud/firestore": "^3.7.5",
"actions-on-google": "^2.10.0",
"cors": "^2.8.5",
"dialogflow": "^1.2.0",
"dialogflow-fulfillment": "^0.6.1",
"dotenv": "^8.2.0",
"envfile": "^6.9.0",
"express": "^4.17.1",
"firebase-admin": "^8.0.0",
"firebase-functions": "^3.6.1",
"firebase-tools": "^7.4.0",
"html-pdf": "^2.2.0",
"isomorphic-fetch": "^2.2.1",
"node-env-file": "^0.1.8",
"nodejs-base64": "^1.0.3",
"nodemailer": "^6.3.0",
"pg": "^7.18.2",
"string-similarity": "^3.0.0",
"twilio": "^3.31.1",
"unirest": "^0.6.0"
}
}
这是因为分配给函数的计算资源无法与您的本地设备相媲美。
云函数的 CPU 速度与分配的内存成正比 document,请尝试为您的函数设置 2GB 内存。
处理资源越多,您的功能就会越快。
如果函数没有在您可接受的时间内响应,下一步是使用另一个无服务器产品,例如 App Engine or Cloud Run,它允许您为应用程序设置更多资源。
这些更改将影响您的帐单。
我调整了您的示例,它适用于非常小的 HTML 文件和 256MB 的内存分配。我保留了您的包裹以尝试重现您的使用情况。我使用了一个内联的非常小的 HTML 文档,我使用了 Node.JS 12 并且我替换了例如file
与 fs
。我不是一个 Node.JS 开发人员,所以对糟糕的代码表示歉意。
/* jshint esversion: 6 */
/* globals exports,require */
const pdf = require("html-pdf");
const fs = require("fs");
const estadoCuenta = `<html><head><title>Whosebug: 63688028</title></head><body><div id="content">Hello Freddie!</div></body></html>`;
const convertor = (req, res) => {
// Write it
const options = { orientation: 'portrait', type: 'pdf', timeout: '360000' };
pdf.create(estadoCuenta, options).toStream(function (err, stream) {
var writeStream = fs.createWriteStream("/tmp/file.pdf");
stream.pipe(writeStream).on('error', function (err) {
console.log(`[stream.pipe] Error: ${err}`);
}).on('finish', function () {
// Read it
var readStream = fs.createReadStream('/tmp/file.pdf');
var filename = encodeURIComponent("converted.pdf");
res.setHeader('Content-disposition', `inline; filename="${filename}"`);
res.setHeader('Content-type', 'application/pdf');
readStream.pipe(res);
console.log(`Done`);
});
});
};
exports.convertor = convertor;
为了本地调试,我附加了以下内容:
const express = require("express");
const app = express();
const port = 3000;
app.get("/", convertor);
app.listen(port, () => {
console.log(`Listening: http://localhost:${port}`);
});
package.json
中有许多依赖项,我假设您需要它们。部署到 Cloud Functions 时不需要导入 express
。
注意 html-pdf
包括一个严重的漏洞:
=== npm audit security report ===
Manual Review
Some vulnerabilities require your attention to resolve
Visit https://go.npm.me/audit-guide for additional guidance
Critical Arbitrary File Read
Package html-pdf
Patched in No patch available
Dependency of html-pdf
Path html-pdf
More info https://npmjs.com/advisories/1095
found 1 critical severity vulnerability in 750 scanned packages
1 vulnerability requires manual review. See the full report for details.