Incorrect DOM-output is likely caused by common mistakes (e.g. conditional rendering based on `typeof window !== 'undefined'`) which screw up rehydration. Dealt with it in the past and seen a lot of developers struggle with it. This article describes it well:
https://joshwcomeau.com/react/the-perils-of-rehydration/
Gigantic page-data.json files are caused by querying more data than necessary to render a given template/component. Let's say you define a component named `EmployeeCard` that renders a name and photo given an `employeeId`. Now you need to query all employees and render the right one using `.find()`. All this data (including base64 thumbnails) ends up in page-data.json, even if you need to render a only single employee.
This is solved by querying only the relevant employee(s) in the template and provide the data (name + photo) directly to the `EmployeeCard` component as props.
I've developed quite a few websites using Gatsby (mostly backed by various GraphQL API's such as WPGraphQL and Strapi) and while there's lots to learn, it's been an enjoyable experience so far.