Closed itsjoekent closed 2 years ago
Hey @itsjoekent, thank you so much for the very detailed triaging and description. This is definitely a strange bug. Thankfully I have an iPhone to test this. 😄
I'll be looking into this today and will post here once I understand the problem better.
@angeloashmore Thank you @angeloashmore , let me know if you need my help trying to create a reproducible example. I have an idea in my head of how I would do this that wouldn't require sending you our entire website, would just need to clear with my team spending some time on that.
@itsjoekent Unfortunately, I am having trouble creating a reproduction of this issue. Is it possible you could create a project with just that section of the website? Ideally you could share the version that has been upgraded to @prismicio/react
.
If you would like to share the code privately, you can send me a message on Prismic's forum with this link: https://community.prismic.io/new-message?username=angeloashmore&title=prismic-react%20Issue%20%23116
A ZIP file of the project is sufficient, or you can share it in any other way you see fit.
Thank you again!
@angeloashmore Working on getting internal permission to share code, will get back to you!
@angeloashmore Sent!
Hey @itsjoekent, just letting you know I didn't forget about this. I have time today to test out your reproduction and hopefully find what's causing the issue. Thanks for your patience!
@itsjoekent This was fun to debug! I think I figured out the issue and how to fix it. If I'm correct, it's not caused by <PrismicRichText>
. 🙂
The issue happens because the tt-bluescreens
font is not available initially. This is why the issue only occurs on an empty cache. Something could be calculating something about the canvas and changing the scroll position before the font is available (are there any scrollTo
s?).
Before the font is loaded, headings use the fallback sans-serif
font. This font is much wider than tt-bluescreens
. Long, non-wrapping words cause the text to overflow outside the Slice’s bounding box. The viewport is configured to shrink the page’s canvas to fit within the viewport’s width. This ultimately messes with the page’s canvas size during scroll position calculation (if that’s what the site is doing).
As you know, the large layout shift was caused by the one_picture_section
Slice. This is a result of its heading content, not because of its use of <PrismicRichText>
. If you were to replace the heading content with short words, like "Hello World," the issue would likely not occur.
If you want to see what I'm talking about re: overflow, remove tt-bluescreens
from the fonts.heading
theme value. On an iOS device, the heading will extend far outside the Slice's container.
The replacement HTML you tested was actually not identical to what was rendered from Prismic.
<h2>Features developers love.<br/>Experiences <br/>customers trust.</h2>
There should be an
between “developers” and “love”. You can confirm this by inspecting the HTML when rendering with <PrismicRichText>
.
With the correct content in place, the issue occurs exactly as with <PrismicRichText>
.
<h2>Features developers love.<br/>Experiences <br/>customers trust.</h2>
This difference is significant because
is a “non-breaking” space. This means the browser needs to render the string “developers love” with no line breaks. Combined with wide width of sans-serif
(before tt-bluescreens
is loaded), this causes the Slice component to overflow significantly.
overflow-x: hidden
around the Slice Zone.tt-bluescreens
is loaded.
in the heading. This only appears to fix the issue, but in reality, any long word and sufficiently small display (even my iPhone XS still sees a slight vertical shift) will still trigger this issue. Still, this is a quick, easy, sort-of fix for this specific issue.I'm pretty sure this is what's happening. If it still seems to be directly related to <PrismicRichText>
, please let me know and I will take another look.
@angeloashmore This all makes sense! I ruled the font loading out as a possibility when (I thought*) I had evidence that it was only occurring when we rendered with the rich text component.
I am curious for future reference, how were you able to locate/identify the
symbol? I don't recall coming across that in the Chrome inspect elements tab or the React output.
And thank you for the incredible write-up & looking into this! Sorry it turned out to be a false report.
@itsjoekent No problem! I'm glad we were able to figure out the problem. 🙂
Re: identifying the
- I inspected the <h2>
in Chrome and noticed the extra character in there. It's definitely not obvious when looking at the rendered version of it.
Hello! I originally posted this on the forum but I was asked to move it here. I'm copying all of the detail from that post to this issue.
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 (@justduett) 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.
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.
And here is the HTML comparison, they're identical.
For reference, here is the data supplied to the RichText prop,
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
.scrollTo
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,
Within that conditional, I returned the following output,
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,
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 theuseMemo
hook ofPrismicRichText
,The iOS scroll problem entirely goes away. The problem only occurs if I return the
serialized
variable (which seems to stem from a mix of this repo & the react package). Theserialized
variable 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,
<div>
elements if you inspect element on our live site. 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.Versions