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

如何在Cloud Function获取Firestore文档时启用文本压缩?

解决Cloud Function返回内容未压缩的Lighthouse警告

核心结论

Firebase Hosting确实会自动启用gzip/brotli压缩,但第二代Cloud Function默认不会自动对响应内容进行压缩,这就是你收到Lighthouse警告的原因。从你的响应头可以看到,返回内容没有Content-Encoding字段,而请求头已经明确告知客户端支持gzip, deflate, br压缩格式,导致传输了未压缩的384KiB数据。

解决方案:手动配置压缩

你可以通过两种方式实现响应压缩:

1. 使用Express中间件(推荐)

第二代Cloud Function支持Express风格的中间件,最简便的方式是使用compression包:

  • 首先安装依赖:
npm install compression
  • 修改你的Cloud Function代码:
const compression = require('compression');
const functions = require('firebase-functions');
const express = require('express');
const app = express();

// 启用压缩中间件
app.use(compression());

// 你的文档查询路由
app.get('/users/:userId/stories/:storyId', async (req, res) => {
  try {
    const storyPath = `users/${req.params.userId}/stories/${req.params.storyId}`;
    const doc = await db.doc(storyPath).get();
    if (!doc.exists) {
      res.status(404).send('No such document!');
    } else {
      // 返回JSON数据,中间件会自动压缩
      res.status(200).json(doc.data());
    }
  } catch (err) {
    console.error('Error getting document:', err);
    res.status(500).send('Error getting document');
  }
});

// 导出Cloud Function
exports.api = functions.https.onRequest(app);

2. 手动压缩响应内容

如果不想用中间件,可以用Node.js内置的zlib模块手动压缩JSON数据:

const zlib = require('zlib');

// 在你的函数处理逻辑中
const docData = doc.data();
const jsonStr = JSON.stringify(docData);

// 根据请求头选择压缩格式
const acceptEncoding = req.headers['accept-encoding'] || '';
if (acceptEncoding.includes('br')) {
  zlib.brotliCompress(jsonStr, (err, compressed) => {
    if (err) {
      res.status(500).send('Compression error');
      return;
    }
    res.setHeader('Content-Encoding', 'br');
    res.setHeader('Content-Type', 'application/json');
    res.status(200).send(compressed);
  });
} else if (acceptEncoding.includes('gzip')) {
  zlib.gzip(jsonStr, (err, compressed) => {
    if (err) {
      res.status(500).send('Compression error');
      return;
    }
    res.setHeader('Content-Encoding', 'gzip');
    res.setHeader('Content-Type', 'application/json');
    res.status(200).send(compressed);
  });
} else {
  // 不支持压缩,返回原始内容
  res.status(200).json(docData);
}

注意事项

  • 仅对文本类内容(比如JSON、HTML)进行压缩,二进制内容无需处理
  • 保留Vary: Accept-Encoding响应头(你的现有响应头已包含,无需修改),这能让CDN正确缓存不同压缩格式的内容
  • 使用res.json()代替res.send()返回JSON数据,能自动设置正确的Content-Type为application/json,比当前的text/html更适配返回内容类型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 19:13:14