hnedeotes
Joined 5 years ago
Joined 5 years ago
At some point I was tasked with improving the queries/retrieval times and started converting parts of the code and not only was it possible to write tests that would convey the actual meaning of the code and crystallise it but I started finding bugs in the implementation that no-one realized were even bugs because they no longer knew what it should do when queries grew to certain complexity and the search space was in the hundreds of millions of rows that thinking through them just with napkin calcs wasn't cutting it (specially when the bugs were subtle and the results still allowed the program to work "mostly" correctly).
It's good that we now have a recorded timeline for history...
The html there's not really many places to be creative, a navbar with 3 sections, 5 links, a text card, a hero image, etc, all those are the same across thousands of projects - they're structured, there's not really many ways you can be creative about it. So in part seeing that "middle ground" design is indeed a filter for the lowest of the low effort (or not understanding how to prompt properly, or how the final thing comes together).
If you just want to prompt models and have them come up with more diverse styles that's also quite, or more, lazy - it would help if you understood (not you in particular) how the look of a web page comes together, because then you can direct the model properly - and if needed tweak the lose ends because at some point it's just easier and faster to edit the output yourself but you need to know what needs change and how. If you know how an html page comes together into the thing you see in the browser you can spec the model properly.
Nonetheless, if there's going to be a premium it has to be discernible in any particular way because software for business is always considered a cost. But what really shows this industry is half a joke, is that now there's no issue in giving 3rd party agents full access to inner code and logic, many times credentials too because these systems are being deployed in CIs. And because there's really no enforcement or punishment for leaks, or endangering users in most areas there's no reason for a premium. There's people pushing thousands of lines / min (and I think even the most professional people out there can't honestly keep up with it) although that isn't in itself meaning the overall security is worse than before, it just means that for the most part it's now un-auditable in any meaningful way.
You would also need to switch inside the handle event to deal with the different types plus the different targets that might be bound to those events inside the component so I think that for anything with a modicum of complexity it doesn't cut it, unless I'm misunderstanding how to apply them in those cases (pattern matching with multiple function heads would definitively make it read like a declarative model but is not really serviceable in JS even if you syntactic sugar it, you wouldn't be able to describe `target` html elements probably - like:
`handleEvent({type: "click", target: {TAG: "input", id: "some-id", type: "input"}) { ... }`
and then another
`handleEvent({type: "click", target: {TAG: "button", ...}) { ... }`
, etc).
The importNode I think there was some issues with some properties not being copied outside of clone? I can't recall why I defaulted to `cloneNode`, could also be I just missed the `importNode` altogether or misread it at the time, but it has worked fine since then so I didn't look for ways to do that better.
Regarding batching, I basically have been using the same class extension since I've started working with webcomponents and it works, it uses a timestamp to control if we're inside the batch window for the inner working and then the "apply/build" part of each component has to compare those and decide - this is the part I would rather not have to code and have it handled natively (some events might actually run a single pointed update while others run the "full" apply/build function). It's nonetheless a bit more wiring and someone that never seen it might have the same reaction as some people here, even though they're fine in importing 50 libs, or 20 lines of useMemo with useState and useWhatever but heavens forbid they might need to read a 50loc class module. At some point many components need to ditch the `attribute` change handles as parsing the attributes into json/objects can get expensive, and you need to start doing parent->child direct data transmission and this is the only real bottleneck I've experienced when using attributes and requires an overhaul to how data is passed into the children (either from parent orchestration from top level attribute parsing that is fairly less taxing when done once only, but at a certain point can still stall the main loop just the same, at which point you need to parent-level requests, websockets, SSR that then you can pass directly to the child child_component._set_whatever_data_function(data) or setting the prop directly if it's workable in the particular case).
The thing with being able to load html fragments (or, even if whole html docs would be what we settle into) and having it be available would be that you could separate them into cacheable requests - so if you have `/essential-templates.html` , `/signed-in-templates.html`, `/special-page-templates.html` they could be cached, which means they would only need to be refetched if they changed or TTL expired. But with no way of declaring dependencies it can (will) also introduce bugs - if there were we could probably do some cool (as in useful) things too. I guess this is what many frameworks end up doing when they need code splitting, modules, and to create the initialization tree of a page/component, but then need to be re-implemented from scratch by each and leave vanilla webc out of an inbuilt system for it.
Here I might just be lacking some knowledge, and perhaps with TS it would be possible to, but the same way you write `static get observedAttributes() { return ["data-flux"]; }` would be great to have a `prop` like system, say `observedProps` that specified the `required` props when the node is to be attached to the DOM (not before, since `createElement` doesn't take options right? for the constructor or otherwise) for the cases you're adding elements from inside another component, that don't derive their inner state/data from attributes due to parsing cost and require directly setting those props.
Shadow dom is not something I use very much because I'm not creating widgets for third parties, or having to have locked components, but I do understand their existence and think it makes sense to have that mode too.
I imagine this is a complex topic altogether to push forward in the context of wrangling so many disparate interests (companies with lots of power and the only real players when it comes to browsers) but nonetheless not having them forces everyone and the webplatform to be way more spaghetti and troublesome than it needs to be. And I think that at a certain level, these issues go beyond the implementation and RFCs into the way browsers actually work, their engines and choices made before, that don't seem to be reasonable in hindsight when looking at from where we landed but asking for a new model will have 0 traction (of the type that matters) since there's too much at stake for what I imagine are "other" reasons.
I don't really understand why people are complaining that this is unmaintainable on the replies to this snippet but there's plenty of things with webcomponents in general that could be better done on the browser side.
For one the innerHTML (or some new method) should be able to reference a `template` directly. If you want to use templates you need to do:
``` const template = document.getElementById("templates-materialization-base").content;
this.appendChild(template.cloneNode(true)); ```
And if you want to use templates then you need to render the templates in a part of the dom that is parsed before this JS is run - there's no way of specifying dependencies for this kind of things - which is a short-coming of the platform as a whole.
One the same topic there's no way of providing an url for retrieval of a fragment that contains templates and have it parsed directly and available to subsequent JS if you could do:
`<HTML-FRAGMENT href="/my-endpoint/returns-templates.html" required="true" id="MAIN_FRAGMENTS">` or doing `fetch("/my-endpoint/returns-templates.html", {DOCUMENT_ID="MAIN_FRAGMENTS")` would parse the result and make it available to the browser engine then you could have on subsequent JS:
`<script requires="MAIN_FRAGMENTS" wait="GLOBAL_LOADING_INDICATOR`>....</script>` or in a file/module `requires DOCUMENT_ID: MAIN_FRAGMENTS` and the file/script execution would block until that would be available, just that would go a long way. You could specify fragments (the component DOM templates to be used) that are needed for the webpage to work at all, fragments that would only show loading for their own content, etc (you could style the TAG with a pseudo-state indicator, so if it had a wait not resolved yet, CSS could target it with `MY-TAG:state(waiting)`).
Another issue is `attributeChangedCallback` - this doesn't take into account how most of the times one can/will update the attributes of an element, so it fires once for each change, even if you made X changes in one swoop, making it so that you have to have to make a more complex "update_render" function to work around that, or lots of small functions that are composable (ideally, but not practical or wanted in many cases where the whole thing is to be treated as a single update) or create a `batched_attributeChangedCallback` that you implement yourself as part of a class mixin and then extend the HTMLElement class on declaration and use that, because most of the times you want to re-do/update the whole component and when you have multiple properties (equivalent to react props and similar in other frameworks) and multiple components this can result in expensive updates to the page that the user feels as sluggish on their end. Something like:
`batched_attributeChangedCallback(attributes, old_values, new_values, batch_timer_window: 200, batch_timer_fn: true)` where the default for the batch window is 200ms, but can be provided a `fn` that does the evaluation to. So even if the updates are done independently but under the timer window they're batched instead of run 1 by 1 (or immediately if the `fn` returns true, defaulting to true when it's independent 1 by 1 updates).
I usually have a function `_set_handlers(boolean)` that is used on connected and disconnected callback but this is just plain js organisation:
``` _set_handlers(toggle) { let act = toggle ? "addEventListener" : "removeEventListener";
window[act]("some-window-event", this._maybe_ready);
this[act]("some-component-event", this._some_fun.bind(this));
}
```And the connectedCallback just calls `this._set_handlers(true)` and disconnected `this._set_hanlders(false)`.
I use them, you can use them to great effect, but I think the biggest problem is the lack of connection between the different APIs. This includes things like indexDB as well, it's not very complex, but it does look messy on "first-glance". Like your example, but when you actually read it, it's pretty straightforward (ignoring the bad/non-existing functionality/APIs). The same with SSE. This could be a great solution for many things, but you always need to wire up yourself how it works. Would be great if you could declare "receiving beacons", at the page level, or component level, with automatic teardown on removal/navigation. So a component could have `static SSE_BEACONS() { ["https://something.com/path"] }` and would mark the state of the component automatically with `BEACONS: [WAITING | CONNECTED | ERROR]`
The loading indications, still seems strange that after 40 years of web development the transition between webpages are basically "white page", "freeze current view". Just having some way of specifying loading states would make any webpage feel 90% of a webapp between page transitions. Make it be a restricted subset of CSS that can be included as a header at the document top level and cached for subsequent visits `<LOADING_STYLES version=X><MAIN>background-color: white;</MAIN><LOADING_INDICATOR>shape: square; rotation: 1s; main-color: blue; secondary-color: turquoise</LOADING_INDICATOR></LOADING_STYLE>`. This would also allow to evolve it while maintaining strict backwards compatibility by starting from a very basic set of possible values - but just this would make website loading a much more app like experience. It could be used together with webcomponents too: `<MY-WEBCOMPONENT ...><LOADING_STYLES>...</LOADING_STYLES></MY-WEBCOMPONENT>` that then could be automatically derived from the `states` I mentioned prior.
Anyway... Spent too much time with frameworks and webcomponents by now. It probably would also make writing code for LLMs less error prone.
Just a rant, don't take it too seriously, but sometimes I wonder with all the resources poured into frameworks by the big Gs, that must amount to millions and millions of dollars when you take into account the salaries some of the people working on them take, if it wouldn't have been better spent somewhere else on the "base" implementation.
To be honest haven't played chess for years - I did MtG for a while even as I got older but then it just annoyed me and haven't played in years - it was when I started working on my own take on tcg's