Just sending full pages, server side rendered, like Hacker News and Wikipedia do is fine:
Going from the HN homepage to this topic we are on:
36 KB in 5 requests.
Going from the Wikipedia Homepage to an article: 824 KB in 25 requests
Going from the AirBnB homepage to an apartment listing: 11.4 MB in 265 requests.
Going from the Reddit homepage to a Reddit thread: 3.74 MB in 40 requests
In comparison to AirBnB and Reddit, HN and Wikipedia feel blazingly fast. And I am sure the developer experience is an order of magnitude nicer as well.What's funny is that the old Reddit makes use of dynamic loading of content here and there the right way. The "load more comments" of the old Reddit is nice and fast. While the "continue this thread" of the new Reddit is annoying and slow.
Look at how HN handles it when you upvote/unvote a comment.
Look at how old.reddit.com handles it when you click "load more comments" in a long thread.
Like you said, AJAX isnt limited to XML, and is really just referring to any use of XMLHttpRequest to hotload data whether its XML, JSON etc.
I wasnt asking what ajax was. I was asking if it falls into the definition of "fancy."
I think my parent proved the opposite point they meant to. old reddit and hn and wp ARE the fancy html over wire sites, and airbnb and reddit are NOT the fancy over wire sites.
How?
You can see votes appear on your network tab under the image tab instead of Fetch/XHR, even though their response return type is text/html -- interesting little hack, although I'm not quite sure why it's done this way instead of fetching since it already requires JS.
(Although modern sites that try to sweep latency under the rug by immediately updating the state on the client side and later reverting the change when the server responds are perhaps more annoying.)
That's thanks to a fantastic browser feature that was introduced a few years ago that hardly anyone knows about: Paint Holding - https://developer.chrome.com/blog/paint-holding/
"... where the browser waits briefly before starting to paint, especially if the page is fast enough. This ensures that the page renders as a whole delivering a truly instant experience."
This is why you don't see flashes of a blank white page while a new page is loading on most sites these days.
What is/was painful was, as an example, the first versions of ASP .Net Web Forms, where every client action was a full server round-trip... Server-rendered Blazor over the wire (not local or in-office server) is roughly as painful by today's standards.
I do think that it's a mix... start with basic html and enhance, or start with a component toolkit with client rendering, and inject server donut or other pre-rendering. With Cloudflare and Deno, I think the latter definitely has some traction.
This would definitely be a bad user experience.
But it doesn't mean refreshes are bad, just that the architect of that application hasn't factored them into the user experience appropriately, or they've made their interface unnecessarily complex.
All modern browsers have enough tools baked in that we can work around this without reinventing the execution and rendering pipeline (e.g. localStorage).
[0] https://github.com/phoenixframework/phoenix_live_view
[2] https://laravel-livewire.com/
[3] https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blaz...
Whatever I click on AirBnB, I get a white screen, then some placeholders, then the placeholders one after the other get replaced by the actual content.
Whatever I click on Wikipedia - its just there instantly.
Remember when AJAX was supposed to make pages faster? LOL. Of course, back then we were just sending HTML to be injected, not JSON that has to be processed by 50+ Javascript functions before finally becoming HTML (or, some DOM entities, anyway).
And offers far less features. Attaching a file to an email takes ages without drag and drop, this alone is worth waiting few more milliseconds to most people (Gmail loads in less than 2 seconds on my crappy hotel wifi)
Most of the time you read e-mails, not write them.
When you write e-mails, most of the time you don't need multiple attachments. The first attachment is reasonably fast to add.
It is possible to create a faster AirBnB by changing some of the underlying constrained imposed on the system (eg by accepting to serve cached, stale, listings; or by lowering the amount of telemetry) but apparently Airbnb management does not think the tradeoff is worth it.
Of course you are entitled to think that these decision from Airbnb are wrong and that they are hurting their sales. But you know the saying: « The least you know about a problem, the more convinced you are that you have the right answer »
AirBnB - client side spa.
the kind of page you like is the fancy html over wire kind
Comparing Reddit and Wikipedia is like comparing a motorcycle to a bicycle. They are different, with specific strengths and weaknesses. Both design/engineering paradigms have a place, imo.
As mentioned everywhere around this thread, the way to do server side rendered apps has also evolved. Hotwire, htmx, Unpoly, Livewire, etc, etc, etc.
Old Reddit still works fine, and I’d argue better than new front end heavy Reddit. You are right it may be for the benefit developers, but Reddit isn’t complicated enough that a heavy front end provides much benefit to the users.
By young people, probably. Me and my friends that I know still use it prefer old.
I can load 3 years of notes on a single page 100kb.
For instance, on GCP, I:
0. Open 2 tabs for a 2 google cloud instance
1. For each tab, I click on the action I want. E.g Logs, deployment, and networking.
2. Then, for each tab again, I click on the nested action I want
3. Repeat step 2
It might sound like a lot, but each click easily takes 5-10 seconds, which is an excruciatingly long time if you spend a lot of day on that site -- and yes, it takes just as long doing it sequentially. Furthermore, I usually use fairly capable machines, so performance should not be an issue IMHO.It does not happen on all sites, and I know GCP is a very complex site, but it happens often enough that it has become a habbit to me.
I love sites like Wikipedia or HN where everything is snappy.
Both AirBnB and Reddit are incentived to collect a massive amount of data on their users and to maximize the experience in any way possible. They need the data to understand user behavior and feed it back into the recommendation algorithms. For both hospitality and social media, users look for images/video content since it is much more powerful than text for most people. All of their competitors have equally bad performance for similar reasons, so they don't lose a competitive edge.
Hacker news specifically goes for a retro look with an interface that has not changed significantly in decades. Wikipedia simply doesn't have the money or engineering capacity to support a more robust platform like airbnb or reddit.
I spend a lot of time in trains, hotels and airports, and I carry a 2017 12" MacBook. It strongly influences how I build websites. It's infuriating to wait for pure content to load because it's tied to a bunch of crap that isn't what you want to read.
In that context, developer docs are often the best kind of websites.
Should you use X? Maybe it depends. I have been burned by using SSR when the complexity of the app increased and suddenly doing SSR was getting in the way and now I was uncomfortably mixing JS with server rendered pages and struggling to maintain state. I've also been on the other side, using React and creating more complexity than was needed.
The point is: don't be dogmatic. Get requirements, extrapolate what could happen in the future, use first principles, weigh decisions against team capabilities, ask yourself if your decisions are for your own personal reasons or have significant positive user/business impact.
Engineers who rush to use one technology over the other without doing their homework are just doing bad engineering. It has nothing to do with "fighting the good fight".
Product designers are notoriously bad at working within the constraints of a stack - so when you choose SSR with hotwire or whatever, you definitely need to push back when a product designer hands you a mock up of something that can't be done easily with SSR. Don't create some mess of SSR and JS. Tell the designer to go back and redesign the experience so it meets the constraints of the stack.
So when I hear "the complexity of the app increased" I'm hearing "the designer invented something that doesn't work with our stack" and rather than saying no, the devs just tried to forge ahead with the wrong tools. (Obviously I'm projecting experiences I've had :))
Some random tips:
- Write a "Django context processor" to inspect requests for "Hx-Request" header, and set a "base_template" variable accordingly. This means that any template that {% extends base_template %} will react to being a full page or just a fragment and you don't even have to think about that in your view logic. Great for progressive enhancement.
- You can get reactive JS elements (for example, a d3.js viz that updates when new data comes in) in a few lines of inline JS by using MutationObserver, and "abusing" HTMX by using views that return JSON targeting a <script> element (`json_script` templatetag can also be used here). In summary, you tell your fancy JS element to render or update whenever a particular <script> element is mutated, and all of it is orchestrated by HTMX.
So in my context_processors.py file, I write something like:
def base_template(request):
template = "templates/base.html" # full page
if "HX-Request" in request.headers:
template = "templates/base_ajax.html" # minimal template
return {"base_template": template}
And then my template just needs to start with `{% extends base_template %}`. Nothing needs to be done in the view (although you could technically override "base_template" there, if you need to).Compare it to Blade (Laravel) or even ERB (Rails) and it’s night and day.
The script injected jQuery, then we replaced the page with HTML fragments. We had an Adobe Air installer, a Flash game and even had an RSS feed.
Funnily enough today we're mostly working towards using ESI - which reminds me of mod_include back in the day.
I guess one could potentially have tiered caches with an optimization layer in the middle and ESI on the backend-facing cache, but that feels extreme and more brittle.
Gmail is one of the first to have adopted this paradigm.
Are developer tools more important than the product they create?
Nothing is isolated so it's probably slower. The tradeoff is that the tests are really simple for how much they cover, and they're entirely separate from the implementation details so refactoring/changing technologies becomes really easy. It's an old project and we've incrementally migrated from jQuery to Backbone to React to Stimulus with the same tests. Conceivably we could change the app to a SPA and keep the tests.
I have no way to really know if it's better than anything else (though I am interested in that question!), but I think it has worked out pretty well for us. One metric might be that our main app has been around for 10+ years, we're still delivering features daily, and nobody is complaining about a rewrite.
You're right we have to know something about the system to know where to inject the stub, and in fact it makes the test brittle in case that implementation detail changes (which has actually happened and failed these tests before), but it doesn't really matter where we inject the stub to cause the error response, so it's not as bad as it sounds. I think it might be pretty analogous to knowing where to mock the JSON API w/ a non-200 response code.
We very rarely stub anything and consider it a code smell, this is one case where we made an exception though because there is otherwise no way to generate an error message via the user interface.
[0] https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html [1] https://htmx.org/
The first webapp framework I saw it in was Rails (turbolinks). I came to Rails late and didn't stay long so I was never clear how old or how broadly used that feature was. Mostly what I got from Rails was being more comfortable writing NodeJS code, which stole shamelessly from Rails.
Over the past 10-ish years alone, I’ve watched web development go through so many phases, it’s not even funny. Anyone remember gulp.js? Well, I remember a time when every conference talk mentioned it and you were weird if you didn’t use it. Backbone.js anyone?
In my experience, I’ve found that most folks can’t even tell you WHY they use React or insert JavaScript framework here.
Not too long ago, I was stepping through some “hello world” code for a trendy framework and the amount of code that was touched just to write “hello world” in the browser felt absolutely ridiculous to me.
Let me stop myself before I go on a prolonged rant . . .
Anyway, all that said, this is why I’m a fan of SvelteKit (Svelte) and Remix (React). I think they provide a decent balance of modern features while building on native web features/protocols properly.
Here is the talk: https://htmx.org/essays/a-real-world-react-to-htmx-port/
Except, guess where the mind of the user is? On the other side of the browser. Embrace the browser, server people, it's closer to the user!
For example, respecting the wishes of users who disable scripts to avoid most of the web's privacy, security, and attention disruption problems.
I don't know if this counts as "HTML over the wire" because server-side Blazor contains some magic to make the page kinda-sorta act like AJAX. It's a little laggy, but for our purposes, it's "good enough."
(The customer-facing pages are going to be SPAs, for very good reasons.)
There might be something that's good enough through css, not sure.
Could be worth releasing on its own as a GitHub project!
https://github.com/curlconverter/curlconverter.github.io/pul...
I couldn't imagine any web developer need such kind of tool [knowing curl by heart], but obviously I'm in my own bubble and I'm wrong on my assumptions.
Someone wanted to buy the site so we added client-side analytics in August to December 2022
https://plausible.io/curlconverter.com?period=custom&from=20...
We also moved the site from GitHub Pages to Cloudflare Pages just for August 2022, to run server-side analytics to count the people that block ads and that said 116k "visits", compared to 67k "unique visitors" and 112k "total pageviews" from client-side analytics for the same time period (August 31st is missing because Cloudflare only lets you see 30 days). 116k and 112k are really close, which makes me suspect that I misunderstood and Cloudflare is actually also doing client-side analytics, but if that's not the case then it's 120,000-150,000 monthly visits.
Back in September 2021 the site used to have Google Analytics and that said 25k users with 60k sessions from Sept 17 to Oct 17 2021.
They offered us 15K for the site so we didn't sell it and they cloned it, since it's all open source. We removed the analytics again in January 2023 for the same reason we removed them before, curl commands copied from the browser might contain cookies or auth tokens and it's easier to not worry about the possibility of them accidentally getting logged by the analytics and also because it's kind of expensive and I got laid off in November. Knowing people are using your code is nice though.
> I couldn't imagine any web developer need such kind of tool [knowing curl by heart]
There might be some edge cases in Bash syntax or curl's option parsing you might miss that the tool won't (or vice versa), but you're right, rewriting a curl command in another language by hand is straightforward. But if you're doing it a lot it gets tedious and some people are writing web scrapers and bots full-time. You usually start with a curl command from the browser or some API's documentation, and if you want to do something with the returned data, you rarely want to do it in Bash. You could call the curl command and read the output in Python but you'll have better error handling and less code if you use an HTTP library. A better solution would be adding "Copy as Python", "Copy as R" etc. to Chrome directly and I opened a PR for Python but I haven't polished it enough for them to just merge it
https://chromium-review.googlesource.com/c/devtools/devtools...
curl is kind of complex and expects you to understand HTTP. It's better if developers that don't want/need to learn it can bypass it.
That's my understanding what is meant to be web developer.
I'm correcting my understanding of reality with comments like yours, thanks!
The reason why so many apps use React/Vue/whatever for everything is because this hybrid setup is far from simple. It leaves you with two different ways of rendering views, which creates unnecessary context switching for developers, and the interface between the two is often ugly and complicated and prone to memory leaks if you're not careful. It also prevents you from taking advantage of the most powerful patterns in these frameworks, which rely on the assumption that it's running as a single page app.
The fact is, if your app has functions that require a JavaScript framework to work, the most straightforward answer is to build the whole app in that framework, rather than trying to cobble together multiple front end systems.
- One language model (i.e. no JS, just our favorite backend language)
- Extremely minimal front-end tooling
- All data is manipulated with the same tools
- No client-side routing, validation, or... really much at all
P.S. We even wrote our own import-maps solution to avoid needing a JS bundler for the small stuff you can't do without JS.
Thankfully people are waking up and seeing that JS is most appropriate as a "last resort" technology.
Almost zero JS (no Vue.js, no React, or else).
I am more in favour of BE telling FE what to render. I honestly believe many apps could be simplified with better abstractions than hard coding html into messy components. Not saying it's a great approach for super complex layouts, of course.
If you're building an where you are going to open up an API, there is a little less benefit, but I've worked on projects in recent years where the API exists solely to be consumed by one client.
It felt like a darkened cafe of inquisitive, sometimes humorous--at turns indignant or snarky--conversation: even intimate, close-quarters, sipping at coffee or wine.
That's what I miss about HN's past feature: we can't browse to a segment of a day. The front page changes across twenty-four hours, an ebb and flow of ephemeral delights.
I guess that's what I'll set lynx with next: sessions, printing, and a way to quickly save snippets of text. The comments are so valuable for follow-up.
I couldn't tell which are replies versus standalone, since everything is left-indented. However, some comments are definitely replies if there's ">" for example, or abbreviated and curt. But I found this "contextual friction" let me be more forgiving in a way.
The comments all seem to float in the ether, utterances in the night. The extra effort to traverse to each comment--arrow, arrow, arrow, arrow--somehow made the whole thing like an exercise in deliberate consciousness: I was seeking after content, rather than having it just be laid out and scrollable.
I was also using the framebuffer. It didn't take much to fill the screen. Moving to the next page happens more often and is so manual; you almost want to wring meaning out of every screen.
I used them this week for the first time and was impressed by the responsiveness on my phone. I looked into the network tab and what I saw was an over-the-wire solution.
However, I'm sure that you can also achieve responsiveness this without HTML over the wire. I scimmed a few blog posts, and it seemed to me like they use Java EE, although I'm not entirely sure.
Ablecommerce (asp.net)
What led you to think it was Java EE ?
[1] https://www.xing.com/profile/Guido_Steinacker
[2] https://www.otto.de/jobs/de/jobsuche/-java/index.php
[3] https://github.com/orgs/otto-de/repositories
[4] https://www.stepstone.de/cmp/de/Otto-GmbH-Co-KG-28607/jobs.h...
For me, if it's an application ui/ux, then the rendering should be almost exclusively on the front-end. It's just delivered via a web server instead of installed. Yeah, it's larger than server-sent. It's also emphatically not tying up server resources for template processing, instead using the super computer on your desk or in your pocket.
I frankly feel ill when I see more than a couple hundred kb of compressed JS go over the wire... why a couple hundred, that's just where I draw the line... React + MUI with some optimizations and all the application logic should easily fit in under 300k compressed payload. If you're going over that, you're probably doing something very, very wrong. Not that you can't go much smaller and hand crafted. It's a trade-off.
I also think edge development tools like Cloudflare Workers and Deno are exceedingly nice and can seriously bridge the gap closer to server rendered, but still not the same as a lot of classic legacy apps.
On the flip side, I look at how much memory and resources applications use on a server as it is... They're often massively under-utilized as well. So who knows. I just know that there's nothing wrong in using the client's system to render the client.
It's not a crazy amount of overhead... and even then, it's a matter of how interactive the site/application is or needs to be. You can have a horrible or great UX in either direction in different use cases.
It’s a joy! But we’re not hiring…
Now using it in a node project and it also works wonderfully
It's practical, pragmatic, and allows me to ship faster.
Send me some counter examples? Im a big SPA fan and there’s lots of good examples
I'd be happy to learn of other Go tools using this.