构建以 HTML 为先的网站,我们的用户量一夜之间翻了一番。
Building an HTML-first site doubled our users overnight

原始链接: https://mohkohn.co.uk/writing/html-first/

在为一家公用事业公司构建复杂的 React 应用程序两次失败后(导致性能低下、功能损坏以及高跳出率),一位开发者采取了不同的方法:构建一个“HTML 优先”的解决方案。 通过优先考虑可访问性和韧性,该开发者使用 Astro 创建了一个表单驱动的应用程序,即使在没有 JavaScript 的情况下也能完美运行。该架构利用了标准表单提交和后端会话持久化,确保使用低端设备或网络环境较差的用户也能完成申请,而不会丢失数据。为了提升用户体验,开发者构建了一个 1KB 的轻量级 Web 组件,用于增强而非替代浏览器原生的验证功能。 结果是变革性的:用户完成率在一夜之间翻了一番,覆盖到了此前因浏览器无法处理繁重的 JavaScript 实现而无法被分析工具捕捉到的用户群体。 这一案例为软件行业提供了一个至关重要的教训:通过为“最低公分母”(如连接较弱的旧设备)进行设计,你所创建的软件将更具包容性、稳健性,并能为所有人提供服务。走出网页开发的“蛮荒时代”,需要优先考虑长期的可访问性和可靠性,而非不必要的复杂性。

此次讨论围绕文章《构建“HTML 优先”网站使我们的用户量一夜翻倍》展开,凸显了开发者群体对业界普遍过度依赖 React 等重型 JavaScript 框架来完成简单任务的日益不满。 **核心主题:** * **过度工程:** 许多贡献者认为,现代的“React 优先”文化导致了网站臃肿、运行缓慢且缺乏无障碍支持。当开发者习惯性地为简单表单构建复杂的单页应用(SPA)时,往往会无意中排斥使用旧设备、流量受限或依赖辅助技术的用户。 * **“HTML 优先”的复兴:** 支持者认为,原生的 HTML、CSS 以及轻量级工具(如 Astro 或 HTMX)不仅足够,且在许多应用场景中表现更优。这些方法依赖于浏览器原生行为,在无需承担庞大 JavaScript 包“代价”的同时,提升了无障碍性和性能。 * **技能鸿沟与利益驱动:** 辩论还触及了初级开发者基础知识匮乏的问题,他们往往只接受过现代框架的训练。参与者还指出,商业激励机制(如咨询公司的合同)往往倾向于复杂而非简单,因为复杂的代码更难维护,从而需要持续的付费支持。 * **人为成本:** 讨论强调,网页开发不仅关乎代码,更关乎用户同理心,即确保重要的服务对每一个人(无论其使用何种设备)而言都能保持正常功能。
相关文章

原文

This is a story of how building HTML-first doubled a company’s users literally overnight.

My client was a utility company, and they had a big problem. To apply for their services, customers could either use an old ASP form on the website, or follow a manual process. The manual process was more expensive for the company, of course. Adding a lot of pressure, this was a regulated monopoly, and if their customer satisfaction dropped below 96% (if I remember correctly) it could result in millions of pounds in fines.

There were two previous failed (and very expensive) attempts to solve the problem. In the most recent, contractors in another country had built a React app. The React app was online for 3 days before being pulled because of customer complaints. I took one look at it and told my boss “we can’t take ownership of this.” It was a mess of loading spinners and global javascript states. It was not accessible. Image upload was a vital part of the form, and it attempted to store images (along with all other form data) in localstorage which has a 5mb limit!

I took a very bold decision and built a new version of the site using Astro. It was HTML-first. Javascript existed, in web components, but only to progressively-enhance a website that worked perfectly fine without it.

My logic was thus:

  1. This is a public service
  2. It should work on every machine possible
  3. It should work when connections are poor
  4. The forms must never lose data once it is entered

I was very moved by this anecdote from Terence Eden:

A few years ago I was doing policy research in a housing benefits office in London. They are singularly unlovely places. The walls are brightened up with posters offering helpful services for people fleeing domestic violence. The security guards on the door are cautiously indifferent to anyone walking in. The air is filled with tense conversations between partners - drowned out by the noise of screaming kids.

In the middle, a young woman sits on a hard plastic chair. She is surrounded by canvas-bags containing her worldly possessions. She doesn’t look like she is in a great emotional place right now. Clutched in her hands is a games console - a PlayStation Portable. She stares at it intensely; blocking out the world with Candy Crush.

Or, at least, that’s what I thought.

Walking behind her, I glance at her console and recognise the screen she’s on. She’s connected to the complementary WiFi and is browsing the GOV.UK pages on Housing Benefit. She’s not slicing fruit; she’s arming herself with knowledge.

The PSP’s web browser is - charitably - pathetic. It is slow, frequently runs out of memory, and can only open 3 tabs at a time.

But the GOV.UK pages are written in simple HTML. They are designed to be lightweight and will work even on rubbish browsers. They have to. This is for everyone.

Some requirements I derived:

  1. Each session with the form should have a unique ID
  2. At every step in the form wizard, submitted data should be stored on the backend, including uploads
  3. It should be possible to complete the form without javascript
  4. It should be possible to complete the form on outdated and crap web browsers
  5. We had to meet WCAG accessibility (the team settled on AA rather than AAA)
  6. Javascript and modern CSS should be used to enhance the experience

The basic setup ended up being that each step in the form wizard was its own page. When the user clicked next, the form would submit. If the data was judged to be valid by the API, the browser would be redirected to the next step.

A venerable web application pattern that has had a small modern renaissance thanks to Remix, form submissions and redirects took a while to explain to my colleagues, on account of everyone being used to heavily client-side web applications. I have nothing against heavily client-side applications, in their place. But this is just a big form - it’s not showing real-time data. Our user could be standing in the middle of a field on a new-build housing estate, holding a decade-old commodity android phone they bought in Tesco. Shipping them 20MB of javascript before we even render a form would be a ridiculous thing to do.

Next, I tackled one of my biggest bugbears, form validation (and form and form error rendering). I have seen teams waste person-months of effort wrangling React validation libraries. If you are a React person, you might be scoffing at this - skill issue, I guess - but it is the reality for many teams. I would like to humbly suggest that you too may be spending more time than you realise, and a lot more time than is necessary, interacting with and maintaining poor imitations of the validation system that ships with every browser.

So I built an HTML web component. These are simple custom elements that wrap around existing HTML and bring it to life. No shadow DOM, no (or little) rendering HTML in javascript. Mine wrapped around any HTML form, picked up the HTML validation, and made it look modern. It would prevent those HTML validation popup tooltips, and instead place the error in the aria-describedby element associated with the field (today, aria-errormessage is advised instead). It would clear validation while you typed, if you reached a valid state, and assess it again on blur and submit.

Exactly the user experience a form needs, delivered in under 1KB. If it failed, the form would fall back to built-in browser validation. If that failed, the backend API would handle validation. We reported validation issues to the user as early as possible given their browser, and always fell back to an acceptable experience if it failed.

I have since written a new version of this web component from scratch, aimed for general use. It’s called validation-enhancer. I have been in this industry for over 20 years, and it is the best form validation library I have ever used. I am very proud of it.

The code is so simple to work with:

<validation-enhancer>
  <form>

    <label for="my-email">Email</label>
    <input type="email" name="my-email" aria-errormessage="my-email-error" required />
    <div id="my-email-error"></div>
    
    <button type="submit">Submit</button>
  </form>
</validation-enhancer>

The results? When we launched, the number of people completing the form doubled. The analytics people didn’t even know where these users were coming from. Of course, your javascript-based analytics package doesn’t see the users you are bouncing because of javascript failures. It was a flood! We also saw my “keep a backend session, never lose user data” approach pay off. In one case, someone completed a form a month after starting it.

There was a sad coda; as is the way of contract work, I moved on. I explained what I had built to my replacement, that it always worked even without javascript. He was appalled and said, “but that’s a lot more work for us.”

It is not acceptable to bounce users on old browsers, users with bad network connections, users using assistive technologies. Certainly not from a monopoly public service. A lot of hype and noise is pressing us to extend the cowboy, wild-west phase of the software industry’s expansion. We should set that aside, and take ourselves seriously as a mature industry. Build a web application that works on a playstation portable on a 3G connection - if you do, it will work for all your users, and it will still work 30 years from now.

联系我们 contact @ memedata.com