2023年11月25日发(作者:)

Puppeteer⾃动化的性能优化与执⾏速度提升

前⾔

最近随着复杂的⾃动化任务的增加,robot 项⽬出现了很多问题,经常要⼈⼯智能,在上次清远漂流的时候,就是经常报警,⽽且基本都是

我⼈⼯智能解决的,厉害吧 。

Chromium 消耗最多的资源是 CPU,⼀是渲染需要⼤量计算,⼆是 Dom 的解析与渲染在不同的进程,进程间切换会给 CPU 造成压⼒

(进程多了之后特别明显)。

其次消耗最多的是内存,Chromium 是以多进程的⽅式运⾏,⼀个页⾯会⽣成⼀个进程,⼀个进程占⽤ 30M 左右的内存,⼤致估算

1000 个请求占⽤ 30G 内存,在并发⾼的时候内存瓶颈最先显现。

优化最终会落在内存和 CPU 上(所有软件的优化最终都要落到这⾥),通常来说因为并发造成的瓶颈需要优化内存,计算速度慢的问题要

优化 CPU。

所以这篇⽂章,我们谈谈如何优化Puppeteer的性能优化与执⾏速度。

Headless Chrome ,⽆头模式,浏览器的⽆界⾯形态,可以在不打开浏览器的前提下,在命令⾏中运⾏测试脚本,能够完全像真实浏

览器⼀样完成⽤户所有操作,不⽤担⼼运⾏测试脚本时浏览器受到外界的⼲扰,也不需要借助任何显⽰设备,使⾃动化测试更稳定。

优化点

优化 Chromium 启动项

1. 如果将Dom解析和渲染放到同⼀进程,肯定能提升时间(进程上下⽂切换的时间)。对应的配置是 single-process

2. 部分功能 disable 掉,⽐如 GPU、Sandbox、插件等,减少内存的使⽤和相关计算。

代码如下:

const browser = await (

{

headless:true,

const MAX_WSE = 4; //启动⼏个浏览器

let WSE_LIST = []; //存储browserWSEndpoint列表

init();

('/', function (req, res) {

let tmp = (()* MAX_WSE);

(async () => {

let browserWSEndpoint = WSE_LIST[tmp];

const browser = await t({browserWSEndpoint});

const page = await e();

await ('file://code/screen/');

await wport({

1. 如果要打开多个页⾯来执⾏任务时,打开的页⾯执⾏完任务之后,最好把其关闭,减少内存的占⽤。

场景及数据分析

因为 FB 变化多端,有很多的场景,⽽且有时候场景的元素重叠了,导致程序跑错流程,所以代码写了很多种场景的判断,⽽且有时候看到

都觉得⽆语。

植⼊ javascript 代码

iframe 较多时,浏览器经常卡到⽆法运⾏,所以可以考虑在代码⾥加了删除⽆⽤ iframe 的脚本。

不过,这各情况,在 robot 项⽬⾥⾯遇到的不多。

(async () => {

const browser = await ();

const page = await e();

await ('');

//注册⼀个 函数,在浏览器⾥运⾏

await Function('md5', text =>

Hash('md5').update(text).digest('hex')

);

//通过 te 在浏览器⾥执⾏删除⽆⽤的 iframe 代码

await te(async () => {

let iframes = mentsByTagName('iframe');

for(let i = 3; i < - 1; i++){

let iframe = iframes[i];

if(es("frameBody")){

我们在爬取⽹站的时候, ⼀般⽐较关⼼⽹站的加载速度, ⽽限制加载速度的⼤多数是静态⽂件, 包括 css, font, image。

为了优化爬⾍性能, 我们需要阻⽌浏览器加载这些不必要的⽂件, 这可以通过对请求进⾏拦截来实现。

⽽且做到 随机拦截 更好⼀点。

await uestInterception(true);

('request', req => {

设置⽤户数据⽬录,⽤户数据⽬录(User Data Directory)是 Chrome / Chromium ⽤来存放户插件、书签和 cookie 等信息的⽂件

夹。

现在已经开发了这个功能了的,线上任务机都还没⽤上,只有开发任务机和本地开发上⽤到⽽已。

不过开启这个功能会耗费磁盘内存,要加个功能:缓存达到 80% 左右,就⾃动删除本地的缓存。

配置优化

现在线上的任务机已经有 32 台了,⽽且任务机会越来越多。

如果某天要加⼀个环境变量什么的,我就要⼿动修改 32 次,如果增加到 100 台任务机,就更恐怖了。

场景的重现

robot 最耗时的就是场景的重现,往往都是要找到特定的号,去到特定的页⾯位置,才能补好场景的。

之前想过,robot 出现未知错误时,就保存 html、js、css 等⽂件,特定的元素是保留下来了,但是因为特定的账号没有登录,⼀打开

html ⽂件时,是重现不了特定的场景的,补不了场景。