Forum Moderators: phranque

Message Too Old, No Replies

Is using Ajax to load fragment of a page SE / user friendly?

         

csdude55

1:16 am on Jun 3, 2017 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



My site has a fairly standard HTML5 layout:

<header>
________
| <nav> |
|_______|
<main>
| | |
| <section> | <aside> |
| | |
|__________|_______|
<footer>

As I'm rebuilding, I was thinking about how we used to do frames, leaving the header and navigation in place while only changing the main content section. Those WERE faster, but frames weren't search engine friendly so they died away.

But now that Ajax is pretty much standard on all browsers, does it make sense to do something similar? I'm thinking:

// Change all internal links to
<a href="$link" onClick="loadPage('$link'); return false">Internal Link</a>

and then in the Javascript:

// not tested, just written for this post
function loadPage(url) {
$('main').html('Loading...');

$('main').load(url + ' main', function(response, status, xhr) {
if (status != 'error') {
var thisTitle = $(response).filter('title').text();

history.pushState({url: url}, thisTitle, url);
document.title = thisTitle;
}
});
}

In theory, this would grab the <main> section of the new page, replace the existing <main section, and update the browser's URL so that the user thinks it's just a regular page view. But since I'm not reloading the header (eg, javascript, jquery, Google, css, etc), navigation, or footer, I should be saving up to 4 seconds of load time per page (after the initial).

Thoughts?

graeme_p

12:09 pm on Jun 3, 2017 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You should not be reloading the JS, CSS on every load anyway, it should all be cached.

You may be better off with alternative solutions such as compressing (combining and minimising) JS and CSS. There are tools that make this easy.

You can make Ajax search engine friendly, and is user friendly if you update browser history and URLs, but I am not sure about accessability implications.

csdude55

8:20 pm on Jun 3, 2017 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



It does cache, but when I check the load time of header.php page (which is included on every page) using [webpagetest.org...] the load time is roughly 5 seconds on the first load, and just over 4 seconds on the second and third load. So caching Javascript and CSS saves about 1 second, but there's still 4 seconds left over.

My thought is that if I just change <section> instead of the whole page, I would (in theory) save about 4 seconds per pageview.

lucy24

9:55 pm on Jun 3, 2017 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You should not be reloading the JS, CSS on every load anyway

I took it to mean that the page content itself--the HTML--is produced by scripts. So the parts that are always the same from page to page--not just CSS but things like navigation headers--are only loaded once.

Since it's ajax, does everything behave as intended if the visitor has scripting turned off?

4 seconds seems an awfully long time just to load up a kilobyte or two of content.

csdude55

11:50 pm on Jun 3, 2017 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Since it's ajax, does everything behave as intended if the visitor has scripting turned off?

I haven't actually done it yet, I wanted to discuss it with you guys first. I didn't want to waste too much time on a bad idea :-)

It SHOULD work, though. Every page is written sorta like this (in PHP):

<?php
include 'header.php';

echo <<<EOF
<main>
...
</main>

EOF;

include 'footer.php';
?>

My intent is to leave every page exactly like that, but loadPage(url) would use Ajax to just load that <main>...</main> section; essentially skipping the two included pages. In theory, non-JS browsers would still load the included pages, and if the user returned via a bookmark or search engine then it would load the included pages, too.


4 seconds seems an awfully long time just to load up a kilobyte or two of content.

The header includes the logo, a few widgets, and the navigation, so it's about 80k. I'm not sure if this link works forever, but you can see the load times:

[webpagetest.org...]

First run is 6.968s, second is 4.593s, and third is 4.891s. The bottleneck is mostly Google, though; Adsense and Analytics. They're ASYNC, so the document is active at around 1.3s.

lucy24

2:38 am on Jun 4, 2017 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I don't believe I've ever run one of those tests--on any site--that didn't tell me to "cache static content"--even when I've already got expiration headers up the wazoo, and/or the stuff they claim is static isn't really.

But I digress ;)

:: wandering off for tests of my own ::

phranque

7:32 am on Jun 4, 2017 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



loadPage(url) would use Ajax to just load that <main>...</main> section; essentially skipping the two included pages. In theory, non-JS browsers would still load the included pages, and if the user returned via a bookmark or search engine then it would load the included pages, too

the way php works, the server will process those includes and send the resulting source in the response.
this means the "included pages" are already there when ajax fires.
this happens in the browser and causes a new server request and i assume the response you are expecting is going to be a document fragment.
non-JS browsers would still have the content from the includes but that happened in the server before the response was sent, not the browser.

if the user makes a new url request via a bookmark or SERP link, the response would be similar to any other request for that url, whether referred by a search engine or otherwise.

csdude55

7:45 am on Jun 4, 2017 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I see... so, even if loading a response fragment, the entire page is going to be loaded from the server. Which would presumably mean that it would still take those 4+ seconds for the <main> section to change, anyway.

I think that could be easily corrected, though... maybe change loadPage(url) to:

$('main').load(url + '?includes=1 main', function(response, status, xhr) {...}

(obviously, I would have to check whether to use ? or &, but this is just a sample)

Then in the PHP:

<?php
if (!$_GET['includes'])
include 'header.php';

...
?>

NickMNS

2:39 pm on Jun 4, 2017 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



@csdude55 what you are describing is creating a single page app (SPA). You may want to consider a js.framework such as Angular to do this.
[w3schools.com...]

In addition to saving time spent, retrieving and reloading requested files, you will also save time by not re-rendering the page. So I think this approach makes sense, but you are entirely dependent on the users hardware, as all the heavy lifting will be done the client side. So one must be vigilant, sending a huge load to a mobile device may cause a bigger problem than it solves.

@graeme
You should not be reloading the JS, CSS on every load anyway, it should all be cached.

Even if the files are cached they will still need to be loaded when the page reloads, the difference is that the files will not be requested from the server instead the request will be routed from the user's local file system, thus saving time from the request not the reload.

One general comment about worrying about users with js disabled.In my case I run info sites monetized by Adsense. If a user has js disabled they will not see the ads, thus I will make no money, so I spend no time (time == money) coding workarounds so that they can get content. Not to mention that most users that have js disabled are bots.

csdude55

10:42 pm on Jun 4, 2017 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Hmm. I kinda wish I'd thought about that 6 months ago, when I started this rebuild project! lol I think that using Angular would require a complete toss and start over.

My sites are monetized by Adsense, too, so I'm not TOO concerned about non-JS browsers... unless they're search engine bots. Which, honestly, don't bring a lot of value my way, either.

Even though my sites are generally pretty fast, I've found that anything I can do to decrease load time results in more pageviews (which means, more money). But mobile is killing me, since mobile users look at far less pages on my site and contribute much less, so with this mobile-friendly rebuild I'm trying to think of anything I can to shave a 1/10th of a second here or there.

csdude55

1:46 am on Jun 6, 2017 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Well, it was a cool idea, but in practice I don't think it's going to work. A fragment load strips ALL Javascript, which means I would have to rebuild every page to duplicate all Javascript in the callback function of loadPage().

So it's not as simple to implement as I'd hoped, and it gets very tricky on pages with infinite scroll. But my test page DID load super fast, so... I don't know, maybe it's worth the effort?

But then, if I'm scrapping and starting over, maybe moving to Angular is a better idea.

It's a tough decision.