top | item 36083745

(no title)

sparks1970 | 2 years ago

I also feel that generating HTML from string templates is wrong because its so fine-grained. We use a lot of boostrap and its verbose, repetitive and hard to keep standardized using string templating.

Recently I did an experiment in python using the XIST library for generating HTML vs a Jinja2 template. Things I found:

1. The XIST approach was 10x slower, probably related to XML serialization vs string building with Jinja2

2. Although an HTML template looks a bit like a set of nested functions (like the lisp people say it is) you actually end up wanting to pass context deep down the call tree. For example. You end up adding parameters to all the parent functions or you pass in a "context" dict which makes it hard to see what is actually being consumed from the context and by what.

  def make_header(user) -> html.Div: <-- user passed
     return html.Div(
        make_logo(),
        make_user_section(user) # <-- so this can use it
     )

This might not seem that different from normal programming but html-as-functions can mean you end up with a very deeply nested call stack with each function a thin wrapper around the next (Russian Doll programming) passing parameters down and down and down.

3. As demonstrated by the example above, instead of a set of "what you see is what you get" html strings you end up with a lot of component/function calls which actually make it hard to correlate what is rendered and sent to the browser vs where it came from.

I still like the idea of saying button(icon="plane", text="Book ticket") vs 3 lines of html, and the idea of getting type checking on my html generation functions but this experiment put me off it.

discuss

order

mixmastamyk|2 years ago

Guessing the lib is not optimized. Dominate is relatively slow as well. Probably could be sped up with some profiling and/or Cython. I believe Jinja is accelerated similarly as well.

Not sure what to make of the second point, but I'd probably try to log it in debug mode somehow, hopefully avoiding performance degradation when not used.

emptysea|2 years ago

The passing stuff down when it isn't needed also comes up with JSX / React. The basic options for solving it are either:

- pass it down manual - use Context, essentially thread local variables but React

both have tradeoffs and it really depends on what you're building your codebase.