More from Jim Nielsen’s Blog
John Gruber has a post about how Google’s search results now require JavaScript[1]. Why? Here’s Google: the change is intended to “better protect” Google Search against malicious activity, such as bots and spam Lol, the irony. Let’s turn to JavaScript for protection, as if the entire ad-based tracking/analytics world born out of JavaScript’s capabilities isn’t precisely what led to a less secure, less private, more exploited web. But whatever, “the web” is Google’s product so they can do what they want with it — right? Here’s John: Old original Google was a company of and for the open web. Post 2010-or-so Google is a company that sees the web as a de facto proprietary platform that it owns and controls. Those who experience the web through Google Chrome and Google Search are on that proprietary not-closed-per-se-but-not-really-open web. Search that requires JavaScript won’t cause the web to die. But it’s a sign of what’s to come (emphasis mine): Requiring JavaScript for Google Search is not about the fact that 99.9 percent of humans surfing the web have JavaScript enabled in their browsers. It’s about taking advantage of that fact to tightly control client access to Google Search results. But the nature of the true open web is that the server sticks to the specs for the HTTP protocol and the HTML content format, and clients are free to interpret that as they see fit. Original, novel, clever ways to do things with website output is what made the web so thrilling, fun, useful, and amazing. This JavaScript mandate is Google’s attempt at asserting that it will only serve search results to exactly the client software that it sees fit to serve. Requiring JavaScript is all about control. The web was founded on the idea of open access for all. But since that’s been completely and utterly abused (see LLM training datasets) we’re gonna lose it. The whole “freemium with ads” model that underpins the web was exploited for profit by AI at an industrial scale and that’s causing the “free and open web” to become the “paid and private web”. Universal access is quickly becoming select access — Google search results included. If you want to go down a rabbit hole of reading more about this, there’s the TechCrunch article John cites, a Hacker News thread, and this post from a company founded on providing search APIs. ⏎ Email :: Mastodon :: Bluesky #generalNotes
This is a note to my future self, as I’ve setup HTML minification on a few different projects and each time I ask myself, “How did I do that again?” So here’s your guide, future Jim (and anyone else on the internet who finds this). I use html-minifier to minifiy HTML files created by my static site generator. Personally, I use the CLI tool because it's easy to add a CLI command as an npm postbuild step. Example package.json: { "scripts": { "build": "<BUILD-COMMAND>" "postbuild": "html-minifier --input-dir <BUILD-DIR> --output-dir <BUILD-DIR> --file-ext html <OPTIONS>" } } All the minification options are off by default, so you have to turn them on one-by-one (HTML minfication is a tricky concern). Me personally, I’m using the ones exemplified in the project README: --collapse-whitespace --remove-comments --remove-optional-tags --remove-redundant-attributes --remove-script-type-attributes --remove-tag-whitespace --use-short-doctype --minify-css true --minify-js true So, for a site folder named build, the entire command looks like this: html-minifier --input-dir ./build --output-dir ./build --file-ext html --collapse-whitespace --remove-comments --remove-optional-tags --remove-redundant-attributes --remove-script-type-attributes --remove-tag-whitespace --use-short-doctype --minify-css true --minify-js true That’s it — that’s the template. What Kind of Results Do I Get? I use this on a few of my sites, including my notes site and this blog. When testing it locally for my blog’s build, I: Run a build and put files to ./build Copy ./build to ./build-min Command: cp -R build build-min Run html-minifier on build-min and compare the resulting folders in macOS finder. Here’s my results for my blog (2,501 items in ./build): Directory size: Before: 37MB After: 28.4MB Difference: ▼ -8.6MB (-23.24%) Main index.html file lines of code: Before: 1,484 After: 15 lines Difference: ▼ -1,469 lines (-99%) Main index.html file size over the network: Before: 30.6kB After: 17.6kB Difference: ▼ -13kB (-42.48%) And the results for my notes (one big index.html file): File size: Before: 1.5MB After: 1.1MB Difference: ▼ -0.4MB (-26.67%) Lines of code: Before: 25,974 After: 1 Difference: ▼ -25,973 lines (-99.996%) Email :: Mastodon :: Bluesky #html
A note before we start: I don’t know how much of this I believe. I’m sketching out some feelings in this post and thinking through whether it actually makes any sense. I’d be curious where other folks land on this. I’m not sure I totally understand this impulse we have on the web to override the default style and appearance of fundamental computing controls. Everyone wants their own checkboxes, radios, and select menus that fit their brand. But websites aren’t about you or your brand. They’re about the people you’re serving who have to use them, i.e. the users. And their needs vary from one person to the next, based on their unique context and environment (operating system, device, etc.) For them, a checkbox that’s visually and functionally uniform across every website is a good thing. It provides consistency and sets expectations — “Oh hey, a checkbox, I know how to use this. It looks and functions the same as a checkbox on every other website, app, or system preference on my computer.” But where we’ve arrived on the web is consistency for brands is more important than consistency for end users. Take Radios, For Example Imagine a radio control in macOS. There are some design considerations in how that system-level control looks and functions that are unique to macOS. For example, when a window loses focus in favor of another window, radio controls are de-emphasized visually because the user is now focused on something else in a different window. This is a unique solution for a specific computing experience where multiple windows may be on the screen at the same time and, as the user shifts focus from one window to another, additional visual help is provided to emphasize and de-emphasize the user’s focal point in the user interface. The beauty of leveraging a system-level element is that you’re tapping into these kinds of solutions which are tailored to solve problems unique to their context and environment. Contrast that with a radio somebody re-implemented on the web to match their brand. I highly doubt many have taken into consideration a de-emphasized state for windowed computing experiences. Or Take Select, For Example As another example, consider how the <select> element can break outside of the browser window because it is an OS-level control. For example, have a list with a lot of options? A <select> element can provide users something your custom select never could: an adaptation to its environment, the operating system. If the browser window is small on screen (because, say, the user is trying to do something else within their computing environment like side-by-side windows) the <select> can break out of the browser window and accommodate more space. Similarly, though perhaps not as advantageous, on mobile devices like iOS the <select> can break outside of the browser window. Something a custom element could never do. Additionally, these native controls are incredibly forward looking. If new hardware or OS appears on the scene (see visionOS), how the <select> works is handled for you. When it ships, you’re up to date (vs. a design system where now you have to go consider how, if at all, things change for your entire system and every site it supports). Business case: there’s no more economical way to ship websites than using the platform. You get outside engineering resources to build your UIs at no cost to you! Every component you build is a liability, so what’s the least you can do to deliver value? I get it, there are trade-offs. But when building UIs, how often do we stop to ask: What’s lost when we refuse to consider the context and environment of our users because we instead force upon them the context and environment of our brand? Two Cents on Design Systems We extoll the virtues of a “design system” within our brands and organizations — consistency, familiarity, uniformity, all for our users! But once they leave the walled garden of our brand, it’s ok that they suddenly lose this privilege? If the inconsistencies across design systems for basic computing controls were within our own organizational systems, we would be enraged! But since they’re across brands (e.g. websites), it’s fine? (Below is an example of radios and checkboxes and selects across various popular design systems.) In the end, it’s the user who has to deal with these inconsistencies. But isn’t that what “systems” are meant to solve in the first place? In other words, the default, un-styled, system-level controls for radios, switches, checkboxes, etc., are the original design system before our branded design systems overrode them. Are Organizational Design Systems User-Centric? Your organization’s design system lacks the sensibilities of your users’ platforms. “We made our own radios! They’re great! They’re ‘on-brand’ and consistent across all our stuff.” But they’re not consistent across all your users’ stuff. In other words, you made a radio for your company without considering what makes a radio a radio on the computer it will be used on. You oriented a visual and functional experience around you and your environment, rather than the person you’re serving and their context and environment. And I just tend to think we’re losing out on something with that choice — to say nothing of its cost. Disclaimers Disclaimer 1: I know I’m cheating here. Not all native system controls have been standardized in a way that serves the varied needs of complex applications. But, on the other side of this coin, a simple healthcare form that would be perfectly suited to some basic radio controls and a plain <select> menu instead rolls its UI for no other reason than to make it “on-brand” and it’s worse in almost every way: visually, functionally, accessibly. Disclaimer 2: Yeah I know, this puts us as developers at the mercy of browser vendors and OS platforms and the paltry level of access they give us to system controls. For example, it’s still not easy to mark a checkbox with an indeterminate state in HTML alone. I get that. But perhaps if we spent more time advocating for these kinds of enhancements (instead of re-theming a checkbox for the nth time) maybe we’d get what we ask for? Disclaimer 3: In case it’s not clear, I am not advocating every website everywhere should only use form controls provided by the web platform. The web is a big place, it’s silly to make universal statements for something so big. What I’m trying to do is bring attention to the fact that maybe you don’t need to roll your own. Maybe design systems should consider the computing context and environment of their users over the context and environment of their own brand. Disclaimer 4: I get that system-level consistency is a kind of branded consistency. If you choose an Apple product, you’re choosing an Apple-branded experience for native form controls. I realize these things are not totally brand-agnostic. But consumers make a choice when they buy a computing device, and maybe we should honor that choice rather than try overriding it. Disclaimer 5: Having disclaimers clears me of any and all criticism lol. Email :: Mastodon :: Bluesky
You know what’s really helpful in solving my own problems? Writing them down, sending them to someone, and not hearing back. You ever do that? For me, it’s a bulletproof method to solving problems. It’s akin to those moments when you go to someone with a problem, you talk it through, you find a solution, you thank them for their help, and they say, “Well I didn’t even say anything, but you’re welcome.” If I have a friend, co-worker, or collaborator who I know is on the other end of a chat box, typing out my problem and not hearing back from them can be a tremendous help. Here’s an example of how it often goes: Jim Nielsen, Friday at 12:53 PM I’m having an issue where the deployment isn’t working. Failiures are coming from lines 123-125 of the build script... Jim Nielsen, Friday at 12:59 PM Oh, it looks like something changed in commit abc123e in the lock file... Jim Nielsen, Friday at 1:02 PM This is so weird, I hate troubleshooting this crap. Why is everything in the world garbage? Jim Nielsen, Friday at 1:03 PM Ok, I can’t figure this out. I'm going to need your help when you have a second. Jim Nielsen, Friday at 1:09 PM Oh hey, actually I think I know what the problem is... Jim Nielsen, Friday at 1:11 PM Ok, it’s fixed now. Nevermind, I don’t need your help. Thanks! Co-worker, Friday at 4:03 PM You're welcome, glad I could help! In contrast, AI is too eager to respond back with something when nothing would be much more helpful. Knowing another human is there to connect with — available, listening, but not speaking — has helped me many times as I express my thinking step-by-step. So let me give you some relationship advice, AI. Sometimes you don’t need to say or do anything. You just need to listen. Cool? Thanks. Email :: Mastodon :: Bluesky #ai
More in programming
I occasionally receive emails asking me to look at the writer's new language/library/tool. Sometimes it's in an area I know well, like formal methods. Other times, I'm a complete stranger to the field. Regardless, I'm generally happy to check it out. When starting out, this is the biggest question I'm looking to answer: What does this technology make easy that's normally hard? What justifies me learning and migrating to a new thing as opposed to fighting through my problems with the tools I already know? The new thing has to have some sort of value proposition, which could be something like "better performance" or "more secure". The most universal value and the most direct to show is "takes less time and mental effort to do something". I can't accurately judge two benchmarks, but I can see two demos or code samples and compare which one feels easier to me. Examples Functional programming What drew me originally to functional programming was higher order functions. # Without HOFs out = [] for x in input { if test(x) { out.append(x) } } # With HOFs filter(test, input) We can also compare the easiness of various tasks between examples within the same paradigm. If I know FP via Clojure, what could be appealing about Haskell or F#? For one, null safety is a lot easier when I've got option types. Array Programming Array programming languages like APL or J make certain classes of computation easier. For example, finding all of the indices where two arrays differ. Here it is in Python: x = [1, 4, 2, 3, 4, 1, 0, 0, 0, 4] y = [2, 3, 1, 1, 2, 3, 2, 0, 2, 4] >>> [i for i, (a, b) in enumerate(zip(x, y)) if a == b] [7, 9] And here it is in J: x =: 1 4 2 3 4 1 0 0 0 4 y =: 2 3 1 1 2 3 2 0 2 4 I. x = y 7 9 Not every tool is meant for every programmer, because you might not have any of the problems a tool makes easier. What comes up more often for you: filtering a list or finding all the indices where two lists differ? Statistically speaking, functional programming is more useful to you than array programming. But I have this problem enough to justify learning array programming. LLMs I think a lot of the appeal of LLMs is they make a lot of specialist tasks easy for nonspecialists. One thing I recently did was convert some rst list tables to csv tables. Normally I'd have to do write some tricky parsing and serialization code to automatically convert between the two. With LLMs, it's just Convert the following rst list-table into a csv-table: [table] "Easy" can trump "correct" as a value. The LLM might get some translations wrong, but it's so convenient I'd rather manually review all the translations for errors than write specialized script that is correct 100% of the time. Let's not take this too far A college friend once claimed that he cracked the secret of human behavior: humans do whatever makes them happiest. "What about the martyr who dies for their beliefs?" "Well, in their last second of life they get REALLY happy." We can do the same here, fitting every value proposition into the frame of "easy". CUDA makes it easier to do matrix multiplication. Rust makes it easier to write low-level code without memory bugs. TLA+ makes it easier to find errors in your design. Monads make it easier to sequence computations in a lazy environment. Making everything about "easy" obscures other reason for adopting new things. That whole "simple vs easy" thing Sometimes people think that "simple" is better than "easy", because "simple" is objective and "easy" is subjective. This comes from the famous talk Simple Made Easy. I'm not sure I agree that simple is better or more objective: the speaker claims that polymorphism and typeclasses are "simpler" than conditionals, and I doubt everybody would agree with that. The problem is that "simple" is used to mean both "not complicated" and "not complex". And everybody agrees that "complicated" and "complex" are different, even if they can't agree what the difference is. This idea should probably expanded be expanded into its own newsletter. It's also a lot harder to pitch a technology on being "simpler". Simplicity by itself doesn't make a tool better equipped to solve problems. Simplicity can unlock other benefits, like compositionality or tractability, that provide the actual value. And often that value is in the form of "makes some tasks easier".
Ask an engineering leader about their incident response protocol and they’ll tell you about their severity scale. “The first thing we do is we assign a severity to the incident,” they’ll say, “so the right people will get notified.” And this is sensible. In order to figure out whom to get involved, decision makers need … Continue reading Incident SEV scales are a waste of time
John Gruber has a post about how Google’s search results now require JavaScript[1]. Why? Here’s Google: the change is intended to “better protect” Google Search against malicious activity, such as bots and spam Lol, the irony. Let’s turn to JavaScript for protection, as if the entire ad-based tracking/analytics world born out of JavaScript’s capabilities isn’t precisely what led to a less secure, less private, more exploited web. But whatever, “the web” is Google’s product so they can do what they want with it — right? Here’s John: Old original Google was a company of and for the open web. Post 2010-or-so Google is a company that sees the web as a de facto proprietary platform that it owns and controls. Those who experience the web through Google Chrome and Google Search are on that proprietary not-closed-per-se-but-not-really-open web. Search that requires JavaScript won’t cause the web to die. But it’s a sign of what’s to come (emphasis mine): Requiring JavaScript for Google Search is not about the fact that 99.9 percent of humans surfing the web have JavaScript enabled in their browsers. It’s about taking advantage of that fact to tightly control client access to Google Search results. But the nature of the true open web is that the server sticks to the specs for the HTTP protocol and the HTML content format, and clients are free to interpret that as they see fit. Original, novel, clever ways to do things with website output is what made the web so thrilling, fun, useful, and amazing. This JavaScript mandate is Google’s attempt at asserting that it will only serve search results to exactly the client software that it sees fit to serve. Requiring JavaScript is all about control. The web was founded on the idea of open access for all. But since that’s been completely and utterly abused (see LLM training datasets) we’re gonna lose it. The whole “freemium with ads” model that underpins the web was exploited for profit by AI at an industrial scale and that’s causing the “free and open web” to become the “paid and private web”. Universal access is quickly becoming select access — Google search results included. If you want to go down a rabbit hole of reading more about this, there’s the TechCrunch article John cites, a Hacker News thread, and this post from a company founded on providing search APIs. ⏎ Email :: Mastodon :: Bluesky #generalNotes
The ware for January 2025 is shown below. Thanks to brimdavis for contributing this ware! …back in the day when you would get wares that had “blue wires” in them… One thing I wonder about this ware is…where are the ROMs? Perhaps I’ll find out soon! Happy year of the snake!
Explore how JSDOM's browser simulation works, and learn front-end testing approaches using Vitest Browser Mode for direct browser testing and native APIs