puppeteer: Inconsistent text rendering in headless mode
EDIT: The fix is to add --font-render-hinting=none
to the launch args. E.g.
var browser = await puppeteer.launch({
headless: true,
args: ['--font-render-hinting=none']
});
Original Comment: Font spacing seems to be inconsistent between headless and non headless mode. This is likely a Chromium bug for Puppeteer versions 1.2.0 and above.
Steps to reproduce
Tell us about your environment:
- Puppeteer version: 1.2
- Platform / OS version: Linux
- URLs (if applicable):
- Node.js version: 8.6.0
What steps will reproduce the problem?
- screenshot.js
'use strict';
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch({ headless: true }); // toggle to false
const page = await browser.newPage();
await page.goto('file:///tmp/test.html');
await page.waitFor(5000);
await page.screenshot({path: '/tmp/screenshot.png'});
await browser.close();
})();
- test.html
<html>
<head>
<link rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Lato">
<style>
body {
font-family: 'Lato', serif;
font-size: 15px;
}
div.a {
line-height: 0.5;
}
</style>
</head>
<body>
<div class="a">
<div>aaaaa..............................................................................|111</div><br>
<div>qwertyasdfzxcvyuiohjklbnm................................|222</div><br>
<div>longlonglonglonglonglonglonglongshorty......|333</div>
</div>
</body>
</html>
node /tmp/screenshot.js
, then repeat withheadless: false
What is the expected result?
Text is correctly aligned and looks the same as opening the HTML in browser. headless: false
What happens instead?
Text is misaligned with headless: true
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 55
- Comments: 30 (5 by maintainers)
Commits related to this issue
- Fix font kerning Fix font kerning for headless Chromium in Linux. Tested with Chromium in docker container on macOS. See screenshots attached to PR. See also https://github.com/GoogleChrome/puppetee... — committed to nzzdev/Q-server by romankaravia 5 years ago
- Fix font spacing Font spacing was wrong without using --font-render-hinting=none. An alternative to hard-coding this would be to expose the font-render-hinting flag in chromehtml2pdf. See https://... — committed to norpan/chromehtml2pdf by norpan 4 years ago
- Improve font rendering Tested on Chromium, Firefox and Evince. In general it makes the text look more compact and consistent, as if the previous version used justified text. On Evince, it also fixes ... — committed to victor-gp/best-resume-ever by victor-gp 3 years ago
- Disable font hinting https://github.com/puppeteer/puppeteer/issues/2410 — committed to dtinth/timelapse by dtinth 2 years ago
- Adds allowed args for addressing Puppeteer font rendering issues More on the underlying issue: https://github.com/puppeteer/puppeteer/issues/2410 — committed to conarro/autocode-puppeteer by conarro a year ago
- Disable font hinting https://github.com/puppeteer/puppeteer/issues/2410 — committed to TryEverything920609/timelapse by deleted user 2 years ago
--font-render-hinting=none
seems to be the trick for meAfter digging a little bit more, I found that the inconsistency is caused by https://github.com/GoogleChrome/puppeteer/pull/2072
which in turn, is from https://github.com/chromium/chromium/commit/e1b855d4545dc4fff19cee500d7ce105126f3bd2
If I understand correctly the changes to Chromium, Puppeteer’s
Launcher.js
should set DEFAULT_ARGS for--font-render-hinting
tomedium
instead of leaving it at default. Doing so does indeed resolve this issue.I can make a PR if this is an acceptable solution. Any thoughts, @aslushnikov?
It’s
'--font-render-hinting=medium'
. Mind the=
This approach works for me with Google fonts. Had the issue with “Source Sans Pro”, the font looked really weird.
Now it’s fixed! Thanks!
I found quick hot-fix on CSS-level. I fixed my broken SVG with:
You can see the text overlapping here
Also the extra spacing
Hi All! I have been encountered with the same problem of unnecessary space and also the text overlapping:
Versions: “puppeteer”: “14.1.1”
Code: args: [ ‘–no-sandbox’, ‘–headless’, ‘–enable-logging’, ‘–window-size=820,480’, ‘–hide-scrollbars’, ‘–printBackground=true’, ‘–disable-dev-shm-usage’, ‘–font-render-hinting=medium’ ]
I had the same problem, my text position was one pixel off on m1 macs vs intel macs. In the end, a combination of the following flags helped:
`--window-size=${resolution.w},${resolution.h}`, "--font-render-hinting=none", "--force-color-profile=generic-rgb", "--disable-gpu", "--disable-translate", "--disable-extensions", "--disable-accelerated-2d-canvas", "--deterministic-mode", "--disable-skia-runtime-opts", "--force-device-scale-factor=1", "--js-flags=--random-seed=1157259157", "--disable-partial-raster", "--use-gl=swiftshader"
posted here, so it saves some time for the next person. I spent more than one day on this.I noticed this issue was not fully fixed using the suggested flag. I found that on wikipedia pages, some times another word would fit into a line on my local browser while on the devtools browser (through the debugging port), I saw that the word is actually located after a newline character. I noticed it on the following wikipedia page (that happened to be the featured article of the day when I first encountered the issue): https://en.wikipedia.org/wiki/Tecumseh
EDIT: I noticed that the flag
--disable-font-subpixel-positioning
improved the results more than the--font-render-hinting=none
I was using before, but still I’ve noticed some line breaks that only occurred on the browser while running on a container.EDIT 2: After checking a bit deeper, I found out that apparently wikipedia is 15 pixels wider on OSx than it is on a linux VM, This is what caused the issue after disabling the subpixel positioning (which is still crucial for it to work).
FWIW I had to combine
--font-render-hinting=none
and CSS* { -webkit-font-smoothing: antialiased; }
in order to get consistent results between Ubuntu and MacOS.I was having issues with text on a PDF rendered by Puppeteer running within a Docker container. The issue was only visible on low-res displays, at low zoom levels (i.e. whole page view) and only when opened in Adobe Reader. Other viewers, including OSX preview, Slack, web browsers etc were all fine.
I tried all of the suggestions listed here to no avail. In the end, using this Docker image instead of the default Node image is the only change that produced any noticeable difference for me. Hopefully this can be of use to someone else!
I have the same issue using the puppeteer latest version on CentOS and I have the same problem. I have tried the --font-render-hinting=none argument on puppeteer.launch() but with no luck. I noticed that for some reason the rendering adds 1px letter-spacing. The same implementation on macOS is working just fine.