V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
huabinglan
V2EX  ›  程序员

基于 puppeteer 的高性能 SPA SEO 解决方案

  •  
  •   huabinglan · 2020-12-15 00:52:59 +08:00 · 1166 次点击
    这是一个创建于 1438 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这是什么?

    这是一个高性能的基于puppeteerSSR方案, 他使用 Headless Chrome 从网页中生成 html,然后以 http 的方法返回 html 内容

    解决了什么问题

    很多公司和开发者使用 JavaScript 框架(包括 AngularJS,BackboneJS,ReactJS, VueJS)开发应用程序和网站。组件化对开发者和开发效率都是非常友好的(对比 MVC),但很多搜索引擎,社交媒体,爬虫不支持抓取 JavaScript 的网页,也就无法做网站 SEO 。

    通过 UserAgent 判断,如果是来自于爬虫, 则通过 nginx(tomcat, Apache)等反向代理到本服务,则可以把渲染好的 html 网页内容传递给搜索引擎, 从而间接实现 SEO, 这样,既可以保持纯粹的前端开始思路, 还能节省 SSR 造成的服务器负担

    也可以使用在爬虫采集, 生成网页截图,生成网页 PDF 等场景

    github

    https://github.com/zuoyanart/sparender

    新项目, 欢迎 star

    使用

    git clone  https://github.com/zuoyanart/sparender
    cd sparender
    npm i
    npm start
    

    查看效果

    http://127.0.0.1:3001/render?url=http://www.example.com
    

    功能

    • puppeteer 连接池
    • render 并发限制
    • log4j 日志
    • 已集成任务调度
    • 生产,开发环境配置
    • redis 缓存
    • 自动来路, 如果来自移动端则自动设置请求 UA 和 viewpoint(使用 iphoneX 的环境参数)

    性能对比

    服务器: 1H2G1M (别打我, 阿里云自用的) 并发:10 运行时间:40S

    项目配置: 不使用缓存, 屏蔽图片,字体,多媒体等

    请求地址: http://xxxx/render?url=https://www.baidu.com

    单次渲染 并发 QPS
    prerender 2054ms 0.03
    sparender 476ms 0.3
    • ps: 初步测试,因为服务器和带宽真不怎么样, 在 QPS 上的表现在高配服务器上可能变数很大, 不过单次渲染的差距还是比较明显(在我笔记本上测试也基本上是 5 倍的差距)

    • 关于性能还需进一步测试

    渲染方式对比

    以下内容摘自 https://markdowner.net/article/73058307795021824, 并根据自己经验做了部分改动

    方式 优点 缺点
    CSR 客户端渲染 SPA 的优点(用户体验较好) * SEO 不友好(爬虫如果没有执行 js 的能力,如百度,获取到的页面是空的,不利于网站推广)
    首屏加载慢(到达浏览器端后再加载数据,增加用户等待时间
    SSR 服务端渲染 SEO 友好, 首屏渲染快(可在服务端缓存页面,请求到来直接给 html ) 代码改动大、需要做特定 SSR 框架的改动(经过我们实践、原有 SPA 代码改动非常大)

    丢失了部分 SPA 体验

    node 容易成为性能瓶颈
    服务端动态渲染(利用 user-agent ) 兼顾 SPA 优点同时解决 SEO 问题 需要服务端应用(但动态渲染只针对爬虫、不会成为性能瓶颈)

    服务端动态渲染(利用 user-agent )

    为了提高用户体验我们用了 SPA 技术、为了 SEO 我们用了 SSR 、预渲染等技术。不同技术方案有一定差距,不能兼顾优点。但仔细想,需要这些技术优点的用户,其实时不一样的,SPA 针对的是浏览器普通用户、SSR 针对的是网页爬虫,如 googlebot 、baiduspider 等,那为什么我们不能给不同用户不同的页面呢,服务端动态渲染就是这种方案。

    基本原理: 服务端对请求的 user-agent 进行判断,浏览器端直接给 SPA 页面,如果是爬虫,给经过动态渲染的 html 页面(因为蜘蛛不会造成 DDOS,所以这种方案相对于 SSR 能节省不少服务器资源)

    PS: 你可能会问,给了爬虫不同的页面,会不会被认为是网页作弊行为呢? Google 给了回复

    Dynamic rendering is not cloaking Googlebot generally doesn't consider dynamic rendering as cloaking. As long as your dynamic rendering produces similar content, Googlebot won't view dynamic rendering as cloaking. When you're setting up dynamic rendering, your site may produce error pages. Googlebot doesn't consider these error pages as cloaking and treats the error as any other error page. Using dynamic rendering to serve completely different content to users and crawlers can be considered cloaking. For example, a website that serves a page about cats to users and a page about dogs to crawlers can be considered cloaking.

    也就是说,如果我们没有刻意去作弊,而是使用动态渲染方案去解决 SEO 问题,爬虫经过对比网站内容,没有明显差异,不会认为这是作弊行为。

    至于百度,请参考 豆丁网是在做黑帽 SEO 吗?

    通过 user-agent 判断,将 Baiduspider 定向到 http 页面

    基本的解释是:

    的确从单一 feature 来讲,会比较难区分 cloaking 型的 spam 和豆丁类的搜索优化,但是搜索引擎判断 spam 绝对不会只用一个维度的 feature 。docin 这样的网站,依靠它的外链关系、alexa 流量、用户在搜索结果里面的点击行为等等众多信号,都足以将其从 spam 里面拯救出来了。

    何况,一般的 spam 肯定还有关键词堆砌、文本语义前后不搭、link farm 等等众多特征。总之 antispam 一门综合性的算法,会参考很多要素,最后给出判断。

    实在不行了,还可以有白名单作为最后的弥补手段,拯救这批大网站是没什么问题的啦。

    第 1 条附言  ·  2020-12-24 15:31:05 +08:00

    最近又做了一些更新, fixed了一些bug, 重构了http模块

    新建了在线体验站点和免费接入渲染的服务, 可以直接查看到效果,不用在自己部署服务

    体验地址

    http://www.zuoyanit.com/tiyan

    免费接入

    http://www.zuoyanit.com/jieru

    github

    https://github.com/zuoyanart/sparender

    13 条回复    2020-12-16 17:28:09 +08:00
    yrj
        1
    yrj  
       2020-12-15 01:07:15 +08:00 via iPad
    窃以为使用 chromium 渲染性能是瓶颈
    lyhiving
        2
    lyhiving  
       2020-12-15 09:20:44 +08:00
    我觉得不能单纯这样去看效果,主要是看网站的收录情况
    wszgrcy
        3
    wszgrcy  
       2020-12-15 10:06:35 +08:00 via Android
    两年前去参加某大会,一个大佬跟我说过这个方案……没想到现在真做出来了
    huabinglan
        4
    huabinglan  
    OP
       2020-12-15 10:39:03 +08:00 via Android
    @yrj 是的,方案的渲染离不开它,它又是资源大头
    huabinglan
        5
    huabinglan  
    OP
       2020-12-15 10:41:14 +08:00 via Android
    @wszgrcy 还很不完善,欢迎提建议
    huabinglan
        6
    huabinglan  
    OP
       2020-12-15 10:44:58 +08:00 via Android
    @lyhiving 收录会有很多因素影响,现在也加了移动端适配,可以增加点权重,且行且观察
    cyjme
        7
    cyjme  
       2020-12-15 11:07:31 +08:00
    哈哈,以前我也做了个类似的,还做了分布式、服务注册,多台服务器领任务跑渲染。

    为了更加通用,还做了管理后台,允许用户自定义渲染结束条件,因为有些数据是异步加载的。

    后来忙别的就停了。。。。 :(
    huabinglan
        8
    huabinglan  
    OP
       2020-12-15 11:12:27 +08:00 via Android
    别啊,自己用也挺香的
    @cyjme
    tangdw
        9
    tangdw  
       2020-12-15 11:59:19 +08:00
    这个算作弊了吧
    yangxiongguo
        10
    yangxiongguo  
       2020-12-15 12:00:32 +08:00
    好玩
    a4854857
        11
    a4854857  
       2020-12-15 17:20:27 +08:00
    有意思呀
    skip11
        12
    skip11  
       2020-12-16 16:54:32 +08:00
    @cyjme 大佬开源出来,大家一起添砖加瓦
    huabinglan
        13
    huabinglan  
    OP
       2020-12-16 17:28:09 +08:00 via Android
    @skip11 我的也在路上
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1143 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 18:32 · PVG 02:32 · LAX 10:32 · JFK 13:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.