Start a personal dev blog on your domain for free with Hashnode and grow your readership.
Get Started

Making subsequent page loads faster ๐Ÿš€ at Hashnode

Hey folks! Just wanted to let everyone know about this cool new library from GoogleChromeLabs called quicklink.

It attempts to make navigations to subsequent pages load faster. It:

  • Detects links within the viewport (using Intersection Observer )
  • Waits until the browser is idle (using requestIdleCallback )
  • Checks if the user isn't on a slow connection (using navigator.connection.effectiveType) or has data-saver enabled (using navigator.connection.saveData)
  • Prefetches URLs to the links (using <link rel=prefetch> or XHR). Provides some control over the request priority (can switch to fetch() if supported).

I just added this to Hashnode feed so that top 5 posts are always preloaded in the browser idle time. I must admit it has significantly improved the subsequent ajax calls (for loading posts). Just trying this with top 5 posts. If it works out well, we'll preload other ajax calls as well.

Here is a small video depicting this:

Thoughts? Let me know in comments below. ๐Ÿ˜€

Start a personal dev blog on your domain for free and grow your readership.

3.4K+ developers have started their personal blogs on Hashnode in the last one month.

Write in Markdown ยท Publish articles on custom domain ยท Gain readership on day zero ยท Automatic GitHub backup and more

Jason Knight's photo

Honestly, hoodoo throwing more code at it isn't the answer, but I guess when you're pretty much strictly CSR telling users with accessibility needs -- and therefor search engines -- to get stuffed, that's to be expected.

You want to make pageloads faster?

Move the SVG logo's and icons out of the markup so it can be cached and your server-side code doesn't have to waste time pasting them into the markup every time there's a page load. If you're worried about handshake counts since most of them are monochromatic, put them into a font.

Lose the Aria role nonsense that you wouldn't need if you had semantic markup; if that's too much to ask, maybe kill off all the empty ones bloating out the code or ones that have zero business in the markup - like the ones on the HTML tag?

Kill off 90%+ of the data- attributes for react that have no legitimate reason or purpose to exist in the markup other than to make the page slower. If react needs to hook your META tags, there's something horrifyingly wrong with how you're building the site. Though that's just react and why I rail against its use.

Lose the redundant opengraph values that serve zero legitimate purpose when they'll fall-back on your non-og equivalent. (99% of the time there's no real reason to use anything more than og:image)

Stop wasting bandwidth on presentational classes. Say what things are not what you want them to look like. If you're using classes like "left-items flex-grow-1 d-flex flex-row align-items-center" you're doing it all wrong. As I often say if you want HTML to work that way, you must really miss HTML 3.2.

If you have HTML elements that only serve a purpose for client side scripting, they have no business in your HTML in the first place. Generate all of them from the scripting -- where they can be cached instead of on each and every pageload.

There's a reason where you have this 7k of minified code:

<div class="progressbar" id="hn-progressbar"></div><div id="__next"><div class="main-wrapper d-flex flex-row" data-reactroot=""><header class="global-sidebar" id="global-sidebar"><div class="d-flex flex-column justify-content-between global-sidebar-content"><div class="sidebar-top"><div class="logo-section"><a href="/"><svg viewBox="0 0 1261 213"><defs><linearGradient id="ma" x1="0%" y1="0%" y2="100%"><stop offset="0%" stop-color="#2196F3"></stop><stop offset="100%" stop-color="#2962FF"></stop></linearGradient></defs><g fill="none" fill-rule="evenodd"><path fill="url(#ma)" d="M44.080002 0h124.839996C193.264711 0 213 19.735289 213 44.080002v124.839996C213 193.264711 193.264711 213 168.919998 213H44.080002C19.735289 213 0 193.264711 0 168.919998V44.080002C0 19.735289 19.735289 0 44.080002 0zm112.614012 186.48571l-.032768-.006554c11.317072-.187479 20.52155-9.173403 20.980882-20.482704.459331-11.309301-7.986098-21.012082-19.25069-22.116725l-40.764377-71.973375c-5.963921-10.70884-17.478874-10.243524-21.627403 4.954642-3.565245 14.392053-2.647718 27.951779-3.683212 44.336175-.006749.107669-.082052.19875-.186533.225617-.104481.026866-.21438-.016592-.27223-.107649l-36.39302-72.550105c2.970206-2.332552 4.70883-5.896732 4.718705-9.673348C60.183368 32.413631 54.769737 27 48.091684 27 41.413631 27 36 32.413631 36 39.091684c0 6.678053 5.413631 12.091684 12.091684 12.091684.570177 0 1.035494-.117967 1.494257-.117967C64.902074 90.446935 81.9484 136.395335 88.04995 146.992762c4.14853 10.132111 18.311201 6.907661 18.65855-4.030561l1.494257-57.463354c0-.347349.458763-.347349.576731-.117967l29.229762 69.548484c-1.738487 3.135306-2.641246 6.665096-2.621503 10.250078.014444 11.761139 9.545129 21.291824 21.306268 21.306268z"></path><path fill="#46494C" d="M283 40.4h26.8v59.8h69.8V40.4h26.8v140h-26.8v-56.8h-69.8v56.8H283v-140zm217.385186 140v-13c-3.733352 4.66669-8.533304 8.199988-14.4 10.6-5.866696 2.400012-12.599962 3.6-20.2 3.6-7.466704 0-14.033305-1.433319-19.7-4.3-5.666695-2.866681-10.033318-6.833308-13.1-11.9-3.066682-5.066692-4.6-10.733302-4.6-17 0-10.00005 3.533298-17.833305 10.6-23.5 7.066702-5.666695 17.066602-8.566666 30-8.7h31.2v-2.8c0-6.266698-2.066646-11.133316-6.2-14.6-4.133354-3.466684-10.133294-5.2-18-5.2-10.133384 0-20.733278 3.3333-31.8 10l-9.4-18c8.400042-4.66669 16.033299-8.033323 22.9-10.1 6.866701-2.066677 14.899954-3.1 24.1-3.1 13.866736 0 24.633295 3.3333 32.3 10 7.666705 6.6667 11.566666 15.99994 11.7 28l.2 70h-25.6zm-28.4-18.8c7.466704 0 13.86664-1.766649 19.2-5.3 5.33336-3.533351 8.33333-7.899974 9-13.1v-9.6h-27c-6.933368 0-12.033317 1.033323-15.3 3.1-3.266683 2.066677-4.9 5.43331-4.9 10.1 0 4.533356 1.699983 8.13332 5.1 10.8 3.400017 2.66668 8.033304 4 13.9 4zm143.785185-59.2c-5.200026-3.066682-10.566639-5.466658-16.1-7.2-5.533361-1.733342-10.63331-2.6-15.3-2.6-4.400022 0-7.899987.766659-10.5 2.3-2.600013 1.533341-3.9 3.899984-3.9 7.1 0 3.33335 1.633317 5.899991 4.9 7.7 3.266683 1.800009 8.433298 3.69999 15.5 5.7 7.466704 2.266678 13.599976 4.499989 18.4 6.7 4.800024 2.200011 8.966649 5.466645 12.5 9.8 3.533351 4.333355 5.3 10.033298 5.3 17.1 0 10.400052-3.99996 18.399972-12 24-8.00004 5.600028-18.066606 8.4-30.2 8.4-8.266708 0-16.333294-1.299987-24.2-3.9-7.866706-2.600013-14.533306-6.299976-20-11.1l9-18.2c4.800024 4.133354 10.5333 7.366655 17.2 9.7 6.6667 2.333345 12.99997 3.5 19 3.5 4.800024 0 8.633319-.833325 11.5-2.5 2.866681-1.666675 4.3-4.16665 4.3-7.5 0-3.733352-1.66665-6.533324-5-8.4-3.33335-1.866676-8.733296-3.933322-16.2-6.2-7.200036-2.133344-13.066644-4.233323-17.6-6.3-4.533356-2.066677-8.46665-5.199979-11.8-9.4-3.33335-4.200021-5-9.699966-5-16.5 0-10.533386 3.833295-18.566639 11.5-24.1 7.666705-5.533361 17.299942-8.3 28.9-8.3 7.066702 0 14.033299.99999 20.9 3 6.866701 2.00001 12.96664 4.799982 18.3 8.4l-9.4 18.8zm95.785186-30c12.266728 0 21.933298 3.699963 29 11.1 7.066702 7.400037 10.6 17.43327 10.6 30.1v66.8h-26.2v-59.2c0-7.466704-2.133312-13.366645-6.4-17.7-4.266688-4.333355-10.06663-6.5-17.4-6.5-8.66671.133334-15.533308 3.066638-20.6 8.8-5.066692 5.733362-7.6 13.066622-7.6 22v52.6h-26V32h26v61.8c7.33337-14.00007 20.199908-21.133332 38.6-21.4zm130.385186 0c12.266728 0 21.933298 3.699963 29 11.1 7.066702 7.400037 10.6 17.43327 10.6 30.1v66.8h-26.2v-59.2c0-7.466704-2.133312-13.366645-6.4-17.7-4.266688-4.333355-10.06663-6.5-17.4-6.5-8.66671.133334-15.499975 3.066638-20.5 8.8-5.000025 5.733362-7.5 13.066622-7.5 22v52.6h-26v-107h26v20c7.33337-13.733402 20.133242-20.733332 38.4-21zm112.785185.2c11.066722 0 20.833291 2.266644 29.3 6.8 8.466709 4.533356 15.066643 10.899959 19.800002 19.1 4.73336 8.200041 7.1 17.63328 7.1 28.3 0 10.800054-2.36664 20.333292-7.1 28.6-4.733359 8.266708-11.333293 14.666644-19.800002 19.2-8.466709 4.533356-18.233278 6.8-29.3 6.8-11.200056 0-21.066624-2.266644-29.6-6.8-8.533376-4.533356-15.166643-10.933292-19.9-19.2-4.733357-8.266708-7.1-17.799946-7.1-28.6 0-10.66672 2.366643-20.099959 7.1-28.3 4.733357-8.200041 11.366624-14.566644 19.9-19.1 8.533376-4.533356 18.399944-6.8 29.6-6.8zm0 22.2c-9.066712 0-16.399972 2.99997-22 9-5.600028 6.00003-8.4 13.799952-8.4 23.4s2.799972 17.39997 8.4 23.4c5.600028 6.00003 12.933288 9 22 9 8.800044 0 15.999972-2.99997 21.6-9 5.600028-6.00003 8.4-13.799952 8.4-23.4s-2.799972-17.39997-8.4-23.4c-5.600028-6.00003-12.799956-9-21.6-9zM1133.91111 32v148.4h-26v-17.2c-3.86668 6.00003-8.8333 10.566651-14.9 13.7-6.06669 3.133349-13.09996 4.7-21.1 4.7-10.13338 0-19.03329-2.299977-26.7-6.9-7.6667-4.600023-13.63331-11.066625-17.9-19.4-4.26668-8.333375-6.4-17.899946-6.4-28.7 0-10.66672 2.09998-20.099959 6.3-28.3 4.20003-8.200041 10.1333-14.566644 17.8-19.1 7.66671-4.533356 16.43329-6.8 26.3-6.8 8.13338 0 15.26664 1.599984 21.4 4.8 6.13337 3.200016 11.19998 7.79997 15.2 13.8V32h26zm-56.4 127.8c8.93338 0 16.23331-3.033303 21.9-9.1 5.6667-6.066697 8.5-13.899952 8.5-23.5s-2.8333-17.433303-8.5-23.5c-5.66669-6.066697-12.96662-9.1-21.9-9.1-8.93337 0-16.19997 3.033303-21.8 9.1-5.60002 6.066697-8.46666 13.899952-8.6 23.5.13334 9.600048 2.99998 17.433303 8.6 23.5 5.60003 6.066697 12.86663 9.1 21.8 9.1zm131.58519-87.2c17.06675 0 29.89996 4.866618 38.5 14.6 8.60004 9.733382 12.9 23.399912 12.9 41 0 3.466684-.06667 6.066658-.2 7.8h-79c1.73334 7.600038 5.29997 13.566645 10.7 17.9 5.40003 4.333355 12.03329 6.5 19.9 6.5 5.46669 0 10.69997-1.033323 15.7-3.1 5.00002-2.066677 9.36665-5.033314 13.1-8.9l14 14.6c-5.33336 5.866696-11.8333 10.399984-19.5 13.6-7.66671 3.200016-16.16662 4.8-25.5 4.8-10.93339 0-20.56663-2.266644-28.9-6.8-8.33338-4.533356-14.76664-10.899959-19.3-19.1s-6.8-17.63328-6.8-28.3c0-10.66672 2.29998-20.133292 6.9-28.4 4.60002-8.266708 11.03329-14.699977 19.3-19.3 8.26671-4.600023 17.66661-6.9 28.2-6.9zm27.6 46c-.26667-7.866706-2.86664-14.13331-7.8-18.8-4.93336-4.66669-11.46663-7-19.6-7-7.60004 0-13.96664 2.299977-19.1 6.9-5.13336 4.600023-8.29999 10.89996-9.5 18.9h56z"></path></g></svg></a></div><nav class="primary"><ul class="list-unstyled"><li><a href="/" class=""><span>Home</span></a></li><li class="dropright"><a href="#" class="d-flex flex-row justify-content-between align-items-center" data-toggle="dropdown"><span>Posts</span><i class="mdi mdi-chevron-right"></i></a><div class="dropdown-menu"><a href="/discussions" class=""><span>Discussions</span></a><a href="/stories" class=""><span>Stories</span></a><a href="/news" class=""><span>News</span></a></div></li><li><a href="/tags" class=""><span>Tags</span></a></li><li><a href="/amas" class=""><span>AMAs</span></a></li><li><a href="/jobs" class=""><span>Jobs</span></a></li></ul></nav></div></div></header>

Anyone who actually knows how to use HTML would use this:

<div id="top">
    <h1><a href="/">Hashnode</a></h1>
    <ul id="mainMenu">
        <li><a href="/">Home</a></li>
        <li>
            <input type="checkbox" id="mainMenu_postsToggle">
            <label for="mainMenu_postsToggle">Posts</label>
            <ul>
                <li><a href="/discussions">Discussions</a></li>
                <li><a href="/stories">Stories</a></li>
                <li><a href="/news">News</a></li>
            </ul>
        </li>
        <li><a href="/tags">Tags</a></li>
        <li><a href="/amas">AMAs</a></li>
        <li><a href="/jobs">Jobs</a></li>
    </ul>
<!-- #top --></div>

Assuming one is ok with abusing a checkbox with :checked for the submenu show/hide. Be even less markup if you wanted to rely on a JS only solution.

That's 1/15th the code that would have to be sent on subsequent pageloads. There's a reason when I say people using things like react, bootstrap, and other such crutches are making themselves work harder, not smarter -- because you're making massive convoluted non-semantic inaccessible messes of it with anywhere from two to twenty times the code needed to do the job! That's why it's slow.

As evidenced by the home page of this site right this moment for a non-logged in guest, takes 3 megabytes in 33 separate files just for the HTML, CSS, JavaScript, and XHR present, all to deliver 2.03k of plaintext, maybe two dozen links, and not even a half dozen content media elements -- not even 10k of HTML's job. Much less given the relative simplicity of this site's design it being highly unlikely for the entire site to need more than 48k of CSS in one or two files. Add on the endless horde of JavaScript with no scripting off graceful degradation...

Literally, 90k of HTML doing 10k's job. Nearly a megabyte of CSS in six files doing 48k or less in one or two files' job. Almost two megabytes of JavaScript in two dozen files doing stuff that the lions share of which shouldn't even be having scripting thrown at it!

In handshakes alone the realtime overhead for the majority of the world who doesn't have "magic perfect ultra-fiber broadband" comes to anywhere from 5 to 25 seconds just for the code. That's first-load, but the checks and/or sheer volume of it blowing out many browsers cache limits (the reason all that playing with cache-control headers placebo BS doesn't actually work for people who visit more than two websites a day no matter what Google says) still means "hey has this been updated" requests are gonna hurt.

So not only would such optimization of the code by kicking bootstrap to the curb and reigning in (if not just killing off) react result in faster subsequent visits, it would also speed up initial pageloads.

Of course, you're knee deep in it, so simply getting a stick to -- as I often joke -- "scrape off the bootcrap" is gonna hurt, since we're basically talking a complete rewrite to deal with bad choices in frameworks. But then you know me, IMHO there is no such thing as a good front-end framework for web development. They make you write two to five times the code needed, deploy five to twenty times the code needed, spread stuff out over dozens of separate files when there's no reason to have more than 3 to 5 of them (not counting social plugins, but even those can be bamboozled into behaving).

Throwing some fancy "service" and more code at it isn't the answer. Thanks to the choices of technologies you've got a 5+ megabyte homepage spanning 80+ files before lazy-loading even kicks in -- where more than half of that could be pitched in the can -- and you're worried about screwing around with wasting bandwidth on precaching after the fact, playing games figuring out what the user's connection speed is, and figuring out what links are in the viewport?

Sorry, but like a lot of things Google is doing lately, waste of time, waste of bandwidth, waste of code to correct for poor architectural choices.

Again, exactly the type of failings I go into banks, healthcare, public utilities, and government agencies to send to the nether realms like the reaper leading the horsemen of the apocalypse.

Show +10 replies
Jason Knight's photo

Emil Moe I think you missed my meaning.

And how would you dynamically render stuff on the website without some sort of content creation through JavaScript?

I would do it exactly there, in the script - using createElement, createTextNode, textContent, and so forth. A simple 'make' helper to speed up generation being all that's needed.

In that example code for vue I lifted straight from their tutorial, I would not have the DIV, the OL, or the LI in the markup. I would figure out what element is before/after where I want the DIV (assuming it even needs a DIV, which usually it doesn't, OL's a perfectly good block-level container), generate it from the scripting and insertBefore/appendChild it as appropriate.

Then it doesn't even need ID's or bizzaro curly bracket BS to hook it, as you just made the element.

IF it's going to be scripting only functionality, it doesn't go in the markup... Any of it. Not one line. Because if it's used across multiple pages in the same fashion, you just missed a caching opportunity. Because if someone is visiting with scripting blocked, it's a bit obtuse to have a bunch of non-functional garbage in the markup.

Though again, 99% of what I deal with is built with accessibility first, fancy "dynamic" stuff second... which means a lot of what we're talking about has zero business being implemented client-side, and if there is a client side to it that's an enhancement replicating and improving an already working page, not the only means of providing functionality.

Hence why the majority of scripted "apps" are an annoyance that when duped into using them screws over the clients I'm called in to "consult" with. By their very nature such "dynamic" scripting if no scripting off fallback is provided violates accessibility norms.

It's OK to do it, if you know the risks, plan for the risks, and have a fallback plan, and do it in a rational gracefully degrading manner. Otherwise you're just gambling on how long before it whips around and bites you in the backside.

Aka where pretty much everything I've ever seen built with these "front end frameworks" fail spectacularly.

Emil Moe's photo

I'm missing your point on how to make it reactive then?

As I have read your opinions right now. It's not an impossible task to create a 'mini JavaScript ''framework''' allowing to add, remove stuff and create it reactive and support for AJAX. Not sure what else the frameworks provides.

Just trying to get your ideas. I still believe some sort of framework is good for faster development, but maybe it can be simplified without too much payoff.

Ben Gubler's photo

That's super nifty! It would be cool to have an option for users to disable it though, even if they're not on a slow network.

Gijo Varghese's photo

I'm still not happy with the speed of Hashnode. I'll write down my findings and suggestions soon

Sandeep Panda's photo

Hey Gijo! We are still working on making Hashnode faster. We will get there soon.