DEV Community

Cover image for Vanilla JavaScript and HTML - No frameworks. No libraries. No problem.

Vanilla JavaScript and HTML - No frameworks. No libraries. No problem.

John Papa on October 13, 2019

Are you using Vue, React, Angular, or Svelte to create web apps? I am, and if you are too, I bet it's been a while since you've written an app that...
Collapse
 
tobbwiz profile image
Bernard Sibanda

Vanilla js is 10x faster than jquery, more faster than any other javascript framework because it has less overheads.

Frameworks expire very quickly. For example Angular is now at version 8.

Using frameworks eliminates control over your abilities to solve the problem in a different most probably in a better way.

Companies behind frameworks market them heavily and in turn you are nolonger an original developer but just a tools integrator.

For the past 40 or so decades of technology change, we have been groping in the dark, and you what? C/C++ remains the most efficient and critical mission language today. It surprised me php7 + swoole processes request per second far more than nodejs. Swoole is developed from C.

All said, now the advantages of frameworks:
They automate routine process, speed up develpment at the expense of efficiency.
They abstract common procedures and eliminate re-inventing the wheel.

Thank you John, this article takes us back to the great basics of web engineering.

Collapse
 
zanehannanau profile image
ZaneHannanAU

Just wanted to say that nowadays Rust is the most efficient language, but not the most mission-critical language.

For web processes, swoole and actix tend to rank pretty high in the speed of processing. Swoole is mostly faster than JS because it isn't converting strings and creating as many objects to pass to the user from what I've explored... also, frameworks like express are really slow in surprising places.

Collapse
 
john_papa profile image
John Papa

I appreciate the comment and I love learning new languages. Rust is indeed very cool.

x is "... faster than JS ..." is not the point of the article. It can be powerful to explore performance, but in most cases in my many years of techhnology, asserting perf often is "it depends" and more often than not perf differences are negligible.

I don't think you are pushing for one over the other, as your comment reads very friendly. I just don't want to start a x is better than Y discussion as I'd rather focus on the point here ... which is there is value in learning plain vanilla js and html even when you mat use additional tools.

thanks for commenting

Thread Thread
 
zanehannanau profile image
ZaneHannanAU

No worries. But in this case it was more "x is faster than node by a long shot" really; and I must agree. Swoole and Rust are both languages much faster than PHP and JS, and both have similar focus groups and people who use them.

In benchmarking (lol) both of them get really high marks (top 5--10 for actix, top 10--20 for swoole) but as you likely know those numbers aren't everything.

Collapse
 
tobbwiz profile image
Bernard Sibanda

Thank you. I have added Rust to my portfolio.

Thread Thread
 
zanehannanau profile image
ZaneHannanAU

Cool.

Collapse
 
john_papa profile image
John Papa

Sure! It's really helpful to remember where we came form, and to re-look at what can be done with lower level APIs.

There is huge value in frameworks ... but personally, I find it very helpful to know what is possible.

Collapse
 
bryistheguy profile image
Bryan Ryan

After seeing this message, I decided to give swoole another shot. Unfortunately, it still has a long ways to go in both documentation and community support for it for me, a huge PHP lover, to consider using it as a framework. I finally got a little demo going using MySQL co-routines within an HTTP server, but it took quite a bit of trial and error as there wasn't any full example and there was little to no documentation on the errors I was encountering. One very glaring issue is that the MySQL module is no longer part of swoole despite it being a major part of the documentation. Also, I could never really get a lot of requests going at once. With a better example on best practices I might have been unable to, but without such, it's a non-starter for me, and I'll continue using Node. I suppose this is for the best since everyone else at my workplace seems to have a weird hatred of PHP.

Collapse
 
john_papa profile image
John Papa

Stencil is cool. Template is powerful and I wish html imports would materialize.

But really the pint of this article is just to appreciate what we have. Ya know?

Collapse
 
squidbe profile image
squidbe

HTML Imports is not supported in most browsers and not trending that way from what I can tell

A few years ago, I used them extensively and had hoped that they'd become a standard, but they are, in fact, dead. The only major browser that still supports them is Chrome (Opera does, but, well... it's Opera), and they said that support is ending Feb. 2020. And polyfills won't work unless you purposely stay on version 1.x of webcomponents.js, which you shouldn't (github.com/webcomponents/polyfills...).

Collapse
 
efrapp profile image
Efrain Pinto Ponce

When you say “I wish ...” is it because there isn’t a way to do that right now?

Thread Thread
 
john_papa profile image
John Papa

HTML Imports is not supported in most browsers and not trending that way from what I can tell. caniuse.com/#feat=imports

Thread Thread
 
efrapp profile image
Efrain Pinto Ponce

Ok John, thanks for replay.

Collapse
 
nomaed profile image
Nomæd

In the last example, you placed const template = document.getElementById('hero-template') inside the loop.
Is the template content itself being modified after importing it, or can the template be queried only once before the loop?

Collapse
 
john_papa profile image
John Papa

Nice catch. Yes, you can get the template outside (before) looping. I'll move that, that's a good move.Thanks

Collapse
 
shadowwarior5 profile image
Konstantin Meiklyar

Love the templates pattern, it's new for me
Thanks for sharing

Collapse
 
john_papa profile image
John Papa

No problem.

Collapse
 
qadsoch profile image
HaQadoschJS

Excellent article, we should not lose sight of the basics.
Any reason for not using documentFragment? developer.mozilla.org/en-US/docs/W...

Collapse
 
john_papa profile image
John Papa

Thanks. Yeah, documentFragment could be very helpful when you assemble a DOM tree outside of the page (to avoid reflow). Then attach it when ready.

Collapse
 
themightyt_v3 profile image
theMightiestT

or a template string?

Thread Thread
 
john_papa profile image
John Papa

sure. template strings with innerHTML work, and it's the first thing I showed here. or do yuo mean something else?

Thread Thread
 
themightyt_v3 profile image
theMightiestT

nope i DID miss it... I was looking for it further down in your example code but you had it covered :)

Thread Thread
 
john_papa profile image
John Papa

No worries.

Collapse
 
mauro_codes profile image
Mauro Garcia

This article is super important right now. I've seen a lot of new devs jumping directly to work with frameworks like react without knowing how "the magic" happens under the hood.
Thanks for your contribution John! I would like to hear your thoughts about Svelte.

Collapse
 
john_papa profile image
John Papa • Edited

Thanks.

I like tools that move the web forward.

Collapse
 
nshathish profile image
Shathish

do you have the code to share, so I can see the full working app ?

Collapse
 
john_papa profile image
John Papa

I haven’t released it yet. But I will

Collapse
 
abourass profile image
Antonio B.

Did you ever end up releasing this?

Collapse
 
zanehannanau profile image
ZaneHannanAU

Little annoying so with gitlab.com/zeen3/z3util-dom:

import { $cc, $cec, filter_map, noemp } from 'z3util-dom';

function createListWithTemplate(heroes: Hero[]) {
  return $cec(
    "ul",
    filter_map(
      heroes,
      hero => hero && $cec("li", [
        $cc("name", [hero.name]),
        $cc("description", [hero.description]),
      ]
    )
  );
}

though what's doing the work may end up a bit excessive:

/** Map an iterable list, filtering as necessary */
export function* filter_map<T, U>(list: T[] | IterableIterator<T>, f: ((t: T) => U | null | undefined)): IterableIterator<U> {
    let v, k
    for (k of list) if ((v = f(k)) != null) yield v;
}
export type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
type Appendable = HTMLElement | DocumentFragment | string;
type Queryable = Document | DocumentFragment | Element;
export type MaybeOr<T> = T | false | 0 | null | '' | undefined;
export type IterableOrNot<T> = MaybeOr<Iterable<MaybeOr<T>>>;
interface createelement<E> {
    <T extends keyof E>(el: T, o: Partial<Omit<E[T], "children" | "childNodes" | "classList" | "style">>): E[T];
}
/** Create element (with attributes) */
export const $ce: createelement<HTMLElementTagNameMap> = (el, o) => Object["assign"](document["createElement"](el), o);
/** Create element (with children, attributes) */
export const $cec = <T extends keyof HTMLElementTagNameMap>(
    name: T,
    children?: IterableOrNot<Appendable>,
    attrs?: Omit<Partial<HTMLElementTagNameMap[T]>, "children" | "childNodes" | "innerHTML" | "innerText" | "outerHTML">,
) => {
    let container = $ce(name, (attrs || {}) as unknown as any), el: MaybeOr<Appendable>;
    if (children) for (el of children) el && container["append"](el);
    return container
};
/** Create container (with classlist) */
export const $cc = (n: string, c?: IterableOrNot<Appendable>) => $cec("div", c, {"className": n});

But then again it's there to be specifically generic.

Collapse
 
themightyt_v3 profile image
theMightiestT

seems excessive.

Collapse
 
zanehannanau profile image
ZaneHannanAU

There's actually very little that's generated.

It's mostly typing information but even then...

Most of it is just expansion. If you expand all of it, it ends up being really short and roughly the same space as the template option.

Collapse
 
bhubr profile image
Benoît Hubert • Edited

The ES6 template string almost eliminates the need for a 3rd-party template library. With Atom (and I guess it's possible with VSCode and Sublime too), you can annotate the template strings so that their content is syntax-highlighted according to the language.

This way you get both the readability and the ability to quickly spot errors.

That said, I'd still rather use a lighweight framework such as Mithril or Svelte.

Collapse
 
devpbrilius profile image
Povilas Brilius

It costs measuring tech, nonetheless, you have to learn a new framework before using it, whereas raw - vanilla javascript doesn't require you to do that. You gain practice in development, but it's your practical material enterprise intangible asset, so to say. If costs aren't important to you or if you consider the government is funding you - subsidizing - while you are learning to cover your learning costs, then you are correct. The vanilla framework is more cost-effective, because you don't have to learn a framework, but you don't save nor improve - i. e. accelerate - dev rendering agility & delivery w/ a framework. Otherwise, you aren't entangled into major vendors like Google backup by angular.js.

Collapse
 
john_papa profile image
John Papa

Thanks for the comments.

Something else to consider is what you don’t get when you use vanilla js. One example is escaping/scrubbing html. Another is optimized updates of the dom for low reflow. And you do still have to learn the dom api.

All that said I do firmly believe that it only benefits us all if we experience the dom api and vanilla js

Collapse
 
clockwerkz profile image
Carlos

Terrific article! I enjoy using frameworks but I find working in Vanilla JS to be really satisfying. :)

Also, am I the only one that didn't know about the progress bar element in html?? Holy moly that's awesome!

Collapse
 
john_papa profile image
John Papa

Thanks. Hey we all learn stuff every day. :)

Collapse
 
theodesp profile image
Theofanis Despoudis

You can also create a cached element that will compare the previous rendered string with a new one, so if the new one is different that the old one then you can replace with innerHTML. Simple and easy.

Collapse
 
aboudard profile image
Alain Boudard

Ah, thanks for the reminder !
Brings back memories et opens perspectives, just like when we worked with jQuery knowing this would be sooner or later replaced by native APIs.
What would be "faster" though ?

  • DOM nodes creation or
  • InnerHTML method

I used both in my "early days" but never knew or had the need to know what was most optimized.
Thanks John.

Collapse
 
eaich profile image
Eddie • Edited

Thanks John. The ES5 -> ES6 leap was huge. We can build amazing things with pure unadulterated JS! Excellent demo.

Collapse
 
john_papa profile image
John Papa

Yes. We’ve come a long way.

Collapse
 
assainov profile image
Ilyas Assainov

With the 3rd approach I had a bug in IE11.

Usually the content inside tag is defended by shadow DOM, so that if you want to querySelect those elements in subsequent interactions, template stays immutable in the DOM. For example, you use template content with Load more button. Template should always be original. But IE11 doesn't really defend elements inside template tag, so if you decide to querySelector(..).parentElement.removeChild(), IE will get those templates and it will delete them, causing unpredictable behaviour!

What helped is replacing tag with .... That way IE11 won't even touch the so called template.

Collapse
 
moyarich profile image
Moya Richards

A lot of times people try to learn frameworks first because it is a marketable skill. I run the largest Facebook group about JavaScript, we currently have over 104k members, and I use that platform to encourage developers to delve deeper into the language and learn how it does certain things. This knowledge makes it easier to use and modify these frameworks.

facebook.com/groups/alljavascript

Collapse
 
gunt profile image
gunt

Hi John,
Thank you! Great article. Where do I learn more of this approach? VanillaJs? I mean any specific resource? Course? Tutorial? I need to learn well the fundamentals before I move on more with frameworks.

Collapse
 
cipak profile image
Ciprian Șerbu
<div class="name">${hero.name}</div>

i'm sure you know you have to escape the hero name:)

Collapse
 
john_papa profile image
John Papa

Yep. That would be a good idea and something a framework does for you.

Collapse
 
itninjas_dev profile image
Izzy Ninja ⚔️

Unless there is some specific and unavoidable reason to use a library or framework, I always go vanilla js. I don't like limiting a client's ability to hire developers after I am done because of a personal preference. That always felt wrong to me. Anyone who understands js should be able to easily understand my comments and modify my scripts.

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

Can I suggest a little enhancement, checkout lit-html

Collapse
 
john_papa profile image
John Papa

Lit html is cool too. But the point here is pure vanilla

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

Ahhh totally get it. I feel that lit is like vanilla essence, it's like vanilla pods only cheeper.

Collapse
 
eljayadobe profile image
Eljay-Adobe

This discussion would not be complete without a link to VanillaJS:

vanilla-js.com/

Collapse
 
simonholdorf profile image
Simon Holdorf

Thanks, John! It's a great addition to framework-oriented articles :)

Collapse
 
john_papa profile image
John Papa

Thanks :)

Collapse
 
smithwebtek profile image
Brad Smith

Sitting in a coding meetup, the guy says something about why jQuery is so yesterday.
I immediately heard the Jim Gaffigan whispering to himself voice: "...hey, I LIKE jquery! fella..."

Collapse
 
john_papa profile image
John Papa

I spent a lot of time in that world too

Collapse
 
delacombo profile image
Jasond_Official

Were the actual array of Heroes implied and outside the article, or am I terrible at reskimming posts...?

Collapse
 
john_papa profile image
John Papa

It’s not shown. You didn’t miss it.

Collapse
 
jckodel profile image
J.C.Ködel

"Vue, React, Angular, or Svelte"

Where is Stencil? Stencil rox! \O/ stenciljs.com/
Where is Mithril? Mithril rox! \O/ mithril.js.org/

Collapse
 
john_papa profile image
John Papa

Where the value listing them all? Lol

Collapse
 
efrapp profile image
Efrain Pinto Ponce

This is exactly what I was looking for!! I was using the second approach but I wanted something like the third one and I found it here. Thank you so much!

Collapse
 
john_papa profile image
John Papa

Glad it helped !

Collapse
 
realityexpander profile image
Chris Athanas

Are the sources available for this little app?

Collapse
 
john_papa profile image
John Papa

Not yet. But in a few weeks

Collapse
 
roramigator profile image
Morado

This is pretty cool, thanks.

Collapse
 
kenovienadu profile image
Ovienadu Ken

Thanks for reminding us of the raw power of html css and Javascript devoid of frameworks.

***I love your Angular courses on Pluralsight. It helped me a lot. 💪🏾

Collapse
 
john_papa profile image
John Papa

Thanks. I appreciate that :)

Collapse
 
tobto profile image
Yuri Polchenko

And then the question: what technique is the most SEO friendly, that Google Bot read page html in one shot from the first visit?

Collapse
 
jqwidgets profile image
jQWidgets

You may look at htmlelements.com/ for a good community set of web components.

Collapse
 
openspeedtest profile image
OpenSpeedtest.com

"F££* jQ" and every other libraries.. I said this in 2015.. I developed openspeedtest app without any library's..

Less Js File size.
Faster performance! Etc..

Collapse
 
hemant profile image
Hemant Joshi

True, I found this helpful but😶 I am not good in JS but here comes the twist this post command me to learn JavaScript at a Professional Level;
Thanks!