top | item 28382772

Twitter.com's HTML, which is produced by React Native for Web, explained

160 points| ggurgone | 4 years ago |giuseppegurgone.com

155 comments

order
[+] Milolol|4 years ago|reply
The classic mistake of thinking role=button replaces <button>. It doesn't (as mentioned in the linked PR comments). Native HTML buttons are supported by all user agents and assistive technology and provide keyboard and focus requirements by default [1]. The "short answer" they give as to why they did this (a flexbox bug) links to a comment from February saying this was fixed in Firefox 63.

https://developer.mozilla.org/en-US/docs/Web/Accessibility/A...

[+] slowwriter|4 years ago|reply
> > The "paragraph" role isn’t mapped to a <p> tag because it’s an HTML conformance error to include block-level children within the [article] element

I believe you are misquoting here. "The element" refers to the paragraph element, meaning that valid HTML5 doesn't allow block-level elements within <p>. This is supported by what follows the quote:

> in React Native for Web both Text and View support block-level children.

[+] dexwiz|4 years ago|reply
I think years of <div> only development has destroyed most developer's knowledge of semantic HTML elements. There are over a hundred elements with various meanings, but to a visual user, they all look the same. With a renewed interested in A11Y people are still starting to rediscover these, but it's still slow.
[+] extra88|4 years ago|reply
At least they were thorough enough in their re-implementation of <button> to include activation by pressing either Enter/Return or Space bar.
[+] rgbrgb|4 years ago|reply
Lots of classic HN dismissals here, though I am glad we as a community have finally gotten past the anger around requiring JS to use the site.

In my mouth, Twitter is probably the best, most responsive web app I've ever used. It is not trivial to make a responsive infinite scroll that remembers your place on back, live updates gracefully, has useful shareable URLs, keeps memory usage low, loads quickly, etc. To me it's the real proof point for RN web and web workers.

[+] turminal|4 years ago|reply
> we as a community have finally gotten past the anger around requiring JS to use the site.

We have not. It still sucks.

As for the twitter responsiveness experience... You must be living in an alternate universe.

[+] lucideer|4 years ago|reply
> Twitter is probably the best, most responsive web app I've ever used

What machine are you running it on?

I'm a regular Twitter user and it is hands down the slowest most unresponsive webapp I use: worse than Slack or Gmail.

Fwiw probably the best complex responsive webapp I use is YouTube (loathe as I am to compliment anything produced by Google's web frontend teams as the rest of their webapps have been consistently poor for so long)

[+] alteii|4 years ago|reply
Agreed. I’d love to hear some alternative examples to Twitter’s web app or how one could build it faster.

Also I’m curious if the original Twitter lite was well engineered. I generally share all the criticisms above about the web but I thought Twitter’s Scala back end actually made the response fast and resilient. I mostly use the iOS app but never had problems with the mobile (until recent changes).

https://blog.twitter.com/en_us/topics/product/2017/introduci...

[+] tomgp|4 years ago|reply
Maybe not trivial but these are all solved problems - media queries, http get requests and history state manipulation are all mature and well understood. In common with 90% of the web twitter’s performance and memory usage is utterly abysmal. We’ve been trained to accept this kind of thing but it doesn’t have to be this way. Im prepared to accept that there are complications that i don’t know about but Twitter is not that complicated a front end and it shouldn’t be beyond the wit of a tech company the size of Twitter to make something that y’know actually shows a tweet when you click a link to see a tweet.
[+] SkyPuncher|4 years ago|reply
Twitter is unbearable for me on mobile web. Takes multiple reloads many times.
[+] heavyset_go|4 years ago|reply
In my experience, Twitter is only bearable on a Zen 3 or equivalent processor with at least 16GB of memory. Anything less than that is almost guaranteed to slow to a crawl if you're doing something other than reading a single tweet and closing the tab immediately afterwards.
[+] Seirdy|4 years ago|reply
Try out Nitter, a Twitter web frontend that doesn't require JS. Same content but way faster, leaner, and nonsense-free (excluding the tweets themselves).
[+] bmeski|4 years ago|reply
This is actually not that hard to do and has been done many many many times before.

URLs can be unique ids for scrolling to.

Simple Ajax function to attach cards on scroll.

Poll or get pinged by SSE to pull updates, swap by url as Id

Loads fast if you simply render html and lazy load the images. Css is almost instant.

We can do better with so much less. Unfortunately we now have front end engineers everywhere doing web development.

[+] chadlavi|4 years ago|reply
> To the eyes of somebody who’s not familiar with the framework, the HTML produced by React Native for Web might look utterly ugly and full of bad practices.

To the eyes of someone familiar with the framework it is still full of bad practices.

[+] SergeAx|4 years ago|reply
Let me write it all down, it's a bit confusing. There is a React framework, created to produce Javascript backed applications running in the browser. Then there is a React Native, a wrapper to run those applications on mobile platforms by compiling Javascript apps to native code. And then here is a React Native for Web, a way to compile a Javascript React Native apps into... Javascript to run inside browsers?

Boy, that frontend ecosystem is really cursed.

[+] _fat_santa|4 years ago|reply
React Native web is really all about code sharing between web and mobile in my mind. Say Twitter were to build their website in plain ReactJS, if they did that then there would be no easy way to transfer components from web to mobile, yes they are both written in React, but regular React isn't 100% interoperable with React Native.

This is where React Native for Web comes into the picture, RN for Web patches that gap of interoperability between web and mobile, what Twitter likely has behind the scenes is a custom UI library that provides all the elements you see on Twitter, if they had chosen ReactJS for the web, they would have to maintain two libraries, however with React Native for web, they only have to maintain one.

[+] skytreader|4 years ago|reply
Amusing anecdote involving div soups: Back in 2010 in one of my CS classes, the professor maintained a Google Sites to communicate with her students and upload slides. At the end of the semester, she wrote a list of students who must take the finals to get at least a passing grade.

The thing is, you view it Chrome, the list displays normally, a handful of students. But you view it in Firefox and it's an empty list. On Firefox it would look like

> (MM/DD/YY) Here's the list of students who must take the finals:

>

> (MM/DD/YY) [Next reminder...]

Sucks to be a Firefox user and be on that list.

A few years later, maybe 2015/2016, with a few years in the industry under my belt, I remember this curiosity and rechecked. Firefox is still not showing the list. I open developer tools to inspect and I'm greeted by an eldritch, decadent, and blasphemous nesting of divs. I did not try to understand it but it seems the stylesheet in use indents divs a certain amount and they abused this rule to get the list to the indentation they want. Probably it hit some limit in Firefox.

I've never used Google Sites so I can't guess whose fault is this. But it's unlikely my prof hand-wrote that HTML.

With this article, it seems to me that Twitter devs, for all their fancy dev toolchains, could only produce slightly better HTML than my professor. Perhaps the industry in general is really not much better than Google Sites, seeing our reliance on such bloated frameworks. What a sobering thought.

P.S. I did look her up just to check if this bug is still present. Her Google Sites is still up, she still teaches, but she seems to have taken down her earlier course pages.

[+] dexwiz|4 years ago|reply
Wouldn't be surprised if this was an output of a WYSIWYG editor. These are notoriously bad for outputting garbage HTML, especially since multiple edits to the content can leave behind unneeded elements. Browsers are incredibly tolerant of invalid HTML (will do things like add closing tags), but they aren't all the same. When you generate garbage HTML, it's easy to see the differences between browsers and their attempts to correct it.
[+] BiteCode_dev|4 years ago|reply
> With this article, it seems to me that Twitter devs, for all their fancy dev toolchains, could only produce slightly better HTML than my professor.

I assume they also make the html complicated to make it hard to scrap the site.

[+] DoctorOW|4 years ago|reply
So pardon my ignorance but I thought React was already for web and React Native merely a set of tools to help port React web apps to native mobile apps. What is the difference between React for web and React Native for web?
[+] robertoandred|4 years ago|reply
An important distinction that often gets lost is that React itself is an abstract, standalone layer above web and native. It handles deciding what to render and when. When you learn the concepts of React, you're learning this layer.

Then there are layers that decide how to render. Regular React has a renderer that accepts HTML tags spits out HTML for the browser. React Native has a renderer that accepts more abstract tags (<View>, <Text>) and spits out native views for apps. There are other projects that make renderers for making PDFs, animations, etc.

React Native for Web is basically a renderer that accepts the abstract tags React Native uses (<View>, <Text>) and spits out HTML. React Native does not really help you directly port a web app to native, but React Native for Web is designed to directly port a native app to the web.

[+] giaset|4 years ago|reply
React Native for web allows you to use the same primitives (View, Text, Image, Button) across platforms (web/iOS/Android/etc)
[+] notamy|4 years ago|reply
React Native for web is, as the name implies, React Native components used for building websites. The idea is that you can share code between your native apps and your web app.
[+] lxe|4 years ago|reply
It's simply React (for web), but for native, ported for web. Would be cool to see a react-native-web-native port to use react-native-web for native apps!
[+] lemax|4 years ago|reply
React and React Native are separate tools, and they don't play with each other. You actually need to build two separate apps and you don't get much of any re-use. For example, you can't use Material UI for React in React Native, and you can't build a React component library and just pull it into React Native.

So if you want a fully cross platform React experience, you need React Native from the get-go and to compile it for web when you want web.

[+] karimf|4 years ago|reply
I've been searching a stack which could allow for a single codebase to be rendered in Android, iOS, and the web, and React Native + React Native Web might be the top choice for that. Other competitor includes Flutter, which used to only render canvas on the web, but right now it seems they have an option to render as HTML as well.

I bet the need for cross-platform stack might continue to rise in the future. It's just impossible for small team/solo founder to target 3 different platforms, while handling three different codebases.

[+] notpachet|4 years ago|reply
I am increasingly of the opinion that we need to ditch HTML in order to protect and advance the open web. We've lost something valuable in this brave new HTML-as-a-compile-target future. The original intention of HTML was to serve as a a lightweight, semantic language that people could use to produce documents that were more-or-less structurally understandable (by both humans and computers). Now it's so muddy that we may as well be downloading binary files. (Sometimes we are.)

Gone are the days when you could disable custom CSS and still kinda-sorta navigate the web. These days, it is en vogue to tightly couple what we're seeing on an HTML page (a product listing, a social media post) with instructions about how to render it (250px wide, black background, blinking marquee text). This is great for the tech companies that are producing these HTML blobs, because they have a lot of control over what they're showing to their users. It's only good for the users if they're 100% happy with how the data is being presented. I don't know about you, but I'm rarely happy these days. To say nothing for users with more stringent accessibility requirements.

I wonder if there's a future where we all use a different kind of web browser -- one that doesn't accept any styling instructions from the websites it's visiting. It would probably need to be built on top of accepted data types for various things, like product listings or social media posts. That way, it wouldn't matter whether I was looking at a product on Amazon, Ebay or Etsy. I could tell my browser that I want all product listings to be rendered in dark mode, with a thumbnail preview image instead of a full-sized one, regardless of what site I'm currently on.

Google is already in the process of trying to become this kind of "browser". It has the advantage of being the "front door" of the internet in doing so. It aggregates, and homogenizes, similar documents from various companies and presents them in a uniform way on the results page (eg, hotels, flights, word definitions).

I don't want to rely on Google to do this for me. I want the documents of the web to be semantically meaningful to the point where my browser can make opinionated decisions about how to style the information I'm downloading.

[+] Seirdy|4 years ago|reply
> I don't want to rely on Google to do this for me. I want the documents of the web to be semantically meaningful to the point where my browser can make opinionated decisions about how to style the information I'm downloading.

You've described the Gemini protocol and Gemtext markup. Gemtext is explicitly designed to leave presentation up to the user agent.

https://gemini.circumlunar.space

[+] bastawhiz|4 years ago|reply
It feels very unnatural to me to use React Native semantics and bolt on props for headings and the like; it seems like it would be better to write <H1> than <Text accessibilityRole="heading" accessibilityLevel={1}>, even just from a DX perspective.
[+] ggurgone|4 years ago|reply
Since everything is a component in React you could abstract that eg.

const H1 = props => <Text accessibilityRole="heading" accessibilityLevel={1} {...props} />

[+] cruano|4 years ago|reply
I love that the site has a screensaver
[+] ourcat|4 years ago|reply
I came across this too. Really nice idea.
[+] steviedotboston|4 years ago|reply
So this explains how their markup is hot garbage, but not really WHY it is.
[+] tomgp|4 years ago|reply
laziness. they could just not use a tool that generates reams of bullshit markup but that would require thought and effort to understand and work with the material of the web.
[+] gwbas1c|4 years ago|reply
???

This page is just an animation, and has nothing to do with "Twitter.com's HTML, which is produced by React Native for Web, explained"

[+] Scottopherson|4 years ago|reply
Apparently is has a screensaver if you don't interact with the page after a certain amount of time.
[+] marstall|4 years ago|reply
rnweb saved my bacon in an app I did that was architected as a react app hosted within an iOS webview. the killer problem I was facing is that the webview didn't handle touches well within a scrolling context. so if you began your scrolling gesture by touching down on a button's box, it would often interpret that as a button press.

which was hella annoying and a classic "tell" that you are dealing with a web app trying to masquerade as a native app.

refactoring to use rnweb's <ScrollView/> and <Button/> made all that go away. Now I'd (boldly) challenge you to find a "tell" that this app is not native. (shelf.fm if you're curious).

[+] antigirl|4 years ago|reply
Would one have to write custom CSS for the desktop version after the generator has spat out the css? Mobile first, so thats not the issue but targeting the various classes generated would be a pain?
[+] heavyset_go|4 years ago|reply
Twitter is almost unusable on a machine with 8GB of memory. Many M1 Macs ship with 8GB of memory to this day.
[+] jonplackett|4 years ago|reply
So why isn't React Native for web, just, you know, React? What's the difference and why?
[+] chmod775|4 years ago|reply
I consider any site that loads 3 seconds to display about 100 bytes worth of unicode text to be utter garbage.

I actually wanted to check the precise loading times before posting this, but would you look at this: https://i.imgur.com/VWOlNHu.png

I rest my case.

[+] spiderice|4 years ago|reply
This is genuinely what I see 50% of the time I go to Twitter. Every other big website can keep their site loading >99% of the time. The fact that Twitter can’t is beyond me, and speaks to their incompetence.
[+] SilasX|4 years ago|reply
This is old, but I thought another hilarious unforced error was when you could click on a tweet link, and it couldn’t fit the 140 character message in your initial view!

https://imgur.com/972el7u