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

自行编译的Chromium二进制文件JS执行速度慢于官方预编译版的原因排查求助

自行编译的Chromium二进制文件JS执行速度慢于官方预编译版的原因排查求助

我最近碰到个棘手的问题:用Puppeteer在无头Chromium里跑JS处理HTML文件时,发现官方预编译的Chromium(对应Linux_x64/1148123版本包)跑同样的任务只需要**300ms**,但我自己下载115.0.5790.102源码、用`disable_fieldtrial_testing_config=true`和`is_debug=false`编译出来的二进制,执行时间居然要**840ms**,而且编译出来的Chrome二进制还比官方版大了70MB左右。

我怀疑是不是漏加了关键的编译标志?有没有大佬能给点思路,为啥自己编译的版本执行速度会慢这么多?

我特意做了一套测试用例来复现问题:

  • 核心测试逻辑是内联页面元素的计算样式,能直接复现耗时差异
  • 配套了Node.js脚本用来启动Chromium、加载测试页面并打印处理耗时

下面是相关内容:

核心测试逻辑说明

测试的核心是运行一个样式内联脚本:遍历页面所有元素,把计算后的CSS样式内联到元素的style属性中,这个过程的耗时是我主要的观测指标。

Node.js启动与测试脚本

const puppeteer = require('puppeteer');
const path = require('path');
const fs = require('fs');
const os = require('os');

/**
 * Test script to run the computedStyleInliner script in Chromium using Puppeteer
 * This script loads the fiction story HTML file and executes the style inliner,
 * then captures the results for analysis.
 */
const Platform = {
  DARWIN: "darwin",
  MAC: "mac",
  LINUX: "linux",
  WIN32: "win32",
  WIN64: "win64",
};

function getPlatform() {
  const ARCH_X64 = 'x64';
  const platform = os.platform();
  if (platform === Platform.DARWIN) return Platform.MAC;
  else if (platform === Platform.LINUX) return Platform.LINUX;
  else if (platform === Platform.WIN32) return (os.arch() === ARCH_X64 ? Platform.WIN64 : Platform.WIN32);
  else throw new Error('Unsupported platform: ' + platform);
}

function getChromiumExecutablePath() {
  const folderPath = process.env.CHROMIUM_PATH;
  const platform = getPlatform();
  let executablePath = '';
  if (platform === Platform.MAC)
    executablePath = path.join(folderPath, 'Chromium.app', 'Contents', 'MacOS', 'Chromium');
  else if (platform === Platform.LINUX) {
    executablePath = path.join(folderPath, 'chrome-wrapper');
  } else if (platform === Platform.WIN32 || platform === Platform.WIN64)
    executablePath = path.join(folderPath, 'chrome.exe');
  else throw new Error('Unsupported platform: ' + platform);
  return executablePath;
}

async function testComputedStyleInliner() {
  console.log('Starting Computed Style Inliner test...');
  let browser;
  try {
    // Launch Chromium browser
    browser = await puppeteer.launch({
      executablePath: getChromiumExecutablePath(),
      headless: process.env.HEADLESS === 'true', // Set to true for headless mode
      devtools: false,
      protocolTimeout: 0,
      args: [
        '--no-sandbox',
        '--disable-setuid-sandbox',
        '--disable-dev-shm-usage',
        '--disable-accelerated-2d-canvas',
        '--no-first-run',
        '--no-zygote',
        '--disable-gpu',
        '--auto-open-devtools-for-tabs'
      ]
    });

    const page = await browser.newPage();
    // Set viewport size
    await page.setViewport({ width: 1200, height: 800 });

    // Get the absolute path to the fiction story HTML file
    const htmlFilePath = path.resolve(__dirname, 'fiction-story.html');
    const fileUrl = `file://${htmlFilePath}`;
    console.log(`Loading HTML file: ${fileUrl}`);

    // Check if the HTML file exists
    if (!fs.existsSync(htmlFilePath)) {
      throw new Error(`HTML file not found: ${htmlFilePath}`);
    }

    // Navigate to the HTML file
    await page.goto(fileUrl, { waitUntil: 'networkidle0' });
    console.log('Page loaded successfully');

    // Wait a moment for any initial rendering
    await page.waitForTimeout(1000);

    // Count elements before style inlining
    const elementCountBefore = await page.evaluate(() => {
      return document.querySelectorAll('*').length;
    });
    console.log(`Total elements found: ${elementCountBefore}`);

    // Check if the computedStyleInliner script is loaded
    const scriptLoaded = await page.evaluate(() => {
      return typeof inlineComputedStyles !== 'undefined';
    });

    let time = 0;
    if (!scriptLoaded) {
      console.log('ComputedStyleInliner script not found as global function, executing inline...');
      // Read and execute the computedStyleInliner script
      const scriptPath = path.resolve(__dirname, 'computedStyleInliner.js');
      if (!fs.existsSync(scriptPath)) {
        throw new Error(`ComputedStyleInliner script not found: ${scriptPath}`);
      }
      const scriptContent = fs.readFileSync(scriptPath, 'utf8');
      // 核心耗时统计在这里:执行样式内联脚本
      time = await page.evaluate(scriptContent);
      console.log('ComputedStyleInliner script executed with time:' + time);
    } else {
      console.log('ComputedStyleInliner script already loaded');
    }

    // Wait a moment for any final processing
    await page.waitForTimeout(500);

    // Count elements with inline styles after processing
    const elementsWithInlineStyles = await page.evaluate(() => {
      const elements = document.querySelectorAll('*');
      let count = 0;
      elements.forEach(el => {
        if (el.getAttribute('style') && el.getAttribute('style').trim() !== '') {
          count++;
        }
      });
      return count;
    });
    console.log(`Elements with inline styles after processing: ${elementsWithInlineStyles}`);

  } catch (error) {
    console.error('Error during test execution:', error);
  } finally {
    // 确保浏览器关闭
    if (browser) {
      await browser.close();
    }
  }
}

testComputedStyleInliner();

测试运行说明

  1. 准备好测试用的fiction-story.html(任意包含多元素的HTML文件即可)和computedStyleInliner.js(实现inlineComputedStyles函数并返回执行耗时),放在脚本同目录
  2. 设置环境变量CHROMIUM_PATH指向你编译的Chromium二进制文件所在目录
  3. 运行Node.js脚本,观测控制台输出的执行耗时

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 03:13:04