Hello! We have been dealing with quite a weird issue when attempting to render a headline using the Prismic RichText React component.
Our product manager (@dan.duett) noticed that, when an iOS device loaded our website, there was a weird "jump" a few pixels down the page. You can see a video of this here.
- This only occurs on real iOS devices, you cannot replicate this in Safari on desktop.
- This only seems to occur on "first page load" (or with cache disabled).
Our immediate fix was to simply .scrollTo(0, 0)
, but I wanted to understand what was actually causing this.
I went through a number of debugging steps to find the culprit, but ultimately I resorted to just deleting entire chunks of the website until the loading bug stopped. Through this brute force method, I was able to find the single header on the site responsible for this bug.
This header (which uses a style and font in numerous other places higher up the page) is rendered by the Prismic RichText component. Now, my first instinct was to investigate the CSS, animations, and other surrounding markup. However, no matter what I tried getting rid of, the bug persisted.
So then I tried something silly. I wrote pure HTML to match what the RichText was outputting. And the bug went away.
<h2>Features developers love.<br/>Experiences <br/>customers trust.</h2>
<RichText render={data.primary.section_title}></RichText>
And here is the HTML comparison, they're identical.
For reference, here is the data supplied to the RichText prop,
[
{
"type": "heading2",
"text": "Features developers love.\nExperiences \ncustomers trust.",
"spans": []
}
]
This seemed really strange to me. Why is the same HTML markup working if I just don't render it with Prismic's RichText component? Surely Prismic isn't calling scroll
anywhere, and we use this same code pattern in numerous places on this page, why would only this title be having this issue?
So I tried a number of things, like removing the line breaks that got passed into the RichText component, and it made no difference. The only change I could make to "fix" the RichText component was to either make it 1 word, or reduce the font size to something very small. Obviously neither of these are "fixes" and I don't quite understand why they worked, but I think it might help provide useful context as folks try to wrap their head around this.
So, we were on an old version of Prismic's React library, 1.3.4, and I thought it was worth investigating if there may in fact be this unexplainable bug in Prismic's library. So I pulled the library down, npm link
'd it to our application, and started debugging.
I wrapped my debug code with the following conditional, so it only ran for the specific title we're investigating here,
if (render && JSON.stringify(render).includes('Features')) {
Within that conditional, I returned the following output,
const output = React.createElement('h2', null, [
'Features developers love.',
React.createElement('br'),
'Experiences',
React.createElement('br'),
'customers trust.',
]);
Yet again, same expected markup as before, and the bug went away. Wat
So now I started comparing the output of what Prismic was generating with the React API, to what I would expect it to generate with something like what I wrote above.
What I found is that, Prismic was nesting elements in an array within another array,
"props": {
"children": [
[
"Features developers love.",
This seemed wrong, and while I didn't understand entirely how it contributed to the literal scroll issue I started investigating (maybe this created some weird rendering "blip" with React?), I figured this might be a sign we should bite the bullet and upgrade Prismic.
Well, one huge Prismic upgrade later, the issue is still there. And yet again, if I npm link
the latest version of @prismicio/react
to our website, and inject the following code into the useMemo
hook of PrismicRichText
,
if (props.debug) {
return (
<h2>
Features developers love.
<br />
Experiences <br />
customers trust.
</h2>
The iOS scroll problem entirely goes away. The problem only occurs if I return the serialized
variable, which again, literally matches the same HTML I wrote above.
I have hit a wall trying to figure this one out. I realize this is extremely hard to debug, and I would be happy to provide any additional information that could be helpful.
I also want to note, if you attempt going to our website to see for yourself,
- The
scrollTo
fix is still in place - We have not shipped the Prismic upgrade yet
- The markup of the title I screen-shotted looks like
<div>
elements. This is due to how a contractor implemented animations, but I assure you this entire time I have been debugging with that code entirely removed.