How can we cache inline SVG in Browsers? - javascript

SVGs have been around for years due to its scalability and it is long-familiar that the benefit of inline SVG is one can manipulate it with CSS and JS, and when we want to repeat the same SVG over a html document, then we can use the <use> tag to reference the original element. Furthermore, inline SVGs could also reduce the number of HTTP requests.
However, many articles suggest (without explaining the details) that while we use inline SVG to save HTTP request, it is no longer cacheable by a browser as a separate subject, which means it is not reusable across the pages.
As I happen to use inline SVGs extensively for a project, I would like to know exactly how inline SVG (the renowned html5 element, which is a w3c recommendation) can be cached in browsers whilst using SVGs with <img> tag or background-image are cacheable.
If DOM is cacheable, then why can't the SVG DOM ?
(which builds upon and is compatible with DOM Level 2. Ref: https://www.w3.org/TR/SVG/svgdom.html)
So far, the solution I came up with cachebility is to use Data URI scheme
(Also Ref: Optimizing svgs in data uris )
But by doing so, it loses the ability to deal with CSS and JS for styling and manipulation.
A few examples around the web suggest the use of JS to load cacheable resource or by replacing placeholder elements such as <object> tag, as well as using localStorage, CacheStorage and Service Worker. But I still need some guide lines to get started to achieve an ideal solution.
Could someone shed me some light please?
-
-
-
Ref: Caching SVG Sprite in localStorage
Ref: Inline SVG and caching
Ref: SVG ON THE WEB
Ref: Do Inline SVGs Weigh Down Websites?

Basic HTTP caching works based on URLs, and it is “all or nothing” - you can instruct the client to either take the whole resource from cache, or to reload it completely.
Now, by “inlining” your SVGs, you are making them part of the HTML document - they are not external resources any more, that could individually be checked for whether they can be taken from cache or need to be reloaded.
So, if you have three HTML documents that all have the same SVG image inlined, the code of the image will be loaded three times - because it is part of the three HTML documents.
Whereas, if the image was embedded as an external resource (as img, background-image, object, …), it would be loaded only once, on the first of those three HTML pages the browser loads. On the other pages, it will recognize, “hey, that external resource with this particular URL is in my cache already - no need to load it again.”

Related

HTML5 / Javascript - Making preloaded Images DOM Accesible?

I'm trying to bridge the gap between loading/preloading images and other items in a manifest and making them accessible to CSS and JS in conventional DIV tags.
I understand the preloading process. I then have an array of images or objects, etc, that are viewable in a window/stage object, but I want them in DIV tags to reference them.
How do people go about loading/preloading images and then reference them in a standard HTML5 markup page?
Like, imagine I have a site with clean markup and scripts/styles links. Now I want to preload it. I can't find any documentation that makes that clear.
Does anybody know what I mean or can point out the perspective of trying to load a page of content and then access it with getElementById?
Thanks in advance for any feedback.
Preloading images is not directly related to being able to access elements in DOM.
Preloading tells the browser to download a web resource in advance already when the browser would otherwise not download it yet.
The ability to access an element in DOM on the other hand depends on the stage of downloading the page itself.

Loading CSS using Manifest

How to load CSS with images and audio file using load manifest?
With or without use of createjs and preload js?
I want to load it first then append it in main? is this possible to do so or not?
Check out the examples in the PreloadJS GitHub - for example the MediaGrid loads all of the supported file types, including CSS, Audio, and images.
http://createjs.com/Demos/PreloadJS/MediaGrid.html
https://github.com/CreateJS/PreloadJS/
Note that due to browser limitations, CSS is always added to the DOM immediately. This is because when you are loading using Tags (instead of XHR), it has to be in the DOM to load, and we wanted tag and XHR loading to be consistent.

javascript lazy loading the progressive enhancement way?

I'm building a website for a gallery owner that has a lot of images per webpage.
Therefore I want to lazy load the images on the webpage, making the initial load
less heavy. However, I would like to implement this in a "progressive enhancement" way.
I've found a lot of lazy loading methods but they all require fiddling with the html code
in such a way that the webpage would be useless with javascript turned off. (eg. the src attribute of the img tags remains unset until the images is lazy loaded).
To implement a lazy loading method progressivly I think one would need the following:
prevent the browser from fetching the images, even though thers are on the page,
but only do this when javascript is on (so on non-javascript browsers, the images still
load as normal). This should be done without altering the html.
save the src attribute in a data-src attribute
sequentually load the images when scrolling down
Of these three steps the first one seems the hardest one. Even this stackoverflow discussion did not provide an answer that doesn't ruin progressive enhancement.
Has anyone got any ideas?
Since none has come up with an answer, I'll post what I found a reasonable solution.
This problem boils down to the following: while we want to prevent the browser from downloading the images when javascript is turned on, we must be sure the images are downloaded
when javascript is turned off or not available.
It is hard to consistently use javascript to stop loading images on a page when they are
in the "normal" format:
<img src="path/to/image.jpg"></img>
To stop the images from downloading we'd have to remove their src attributes, but in order
to do this, the DOM should be loaded already. With the optimisations a lot of browsers have nowadays it is hard to guarantee that the images aren't downloading already.
On top of that, we certainly want to prevent interrupting images that are already downloading,
because this would simply be a waste.
Therefore, I choose to use the following solution:
<img data-src="path/to/image.jpg" class="lazy"></img>
<noscript>
<img src="path/to/image.jpg"></img>
</noscript>
Notice how the images outside of the noscript tag have no src but a data-src attribute instead. This can be used by a lazyloading script to load the images one by one for instance.
Only when javascript is not available, will the images inside the noscript block
be visible, so there's no need to load the .lazy images (and no way to do this, since
javascript is unavailable).
We do need to hide the images though:
<noscript>
<style>
.lazy {
display: none;
}
</style>
</noscript>
Like the img tags inside the noscript block, this style block will only be visible to the browser when javascript is unavailable.
On a related note: I thought I could reduce the html size by not putting a src or data-src attributes on the lazy images at all. This would be nice because it eliminates
the redundant url from the page, saving us some bandwidth.
I thought I could pluck the src attribute out of the noscript block using javascript anyways. However, this is impossible:
javascript has no access to the contents of a noscript block. The above scheme is therefore
the most efficient I could come up with.
Not specifying a src attribute is invalid HTML, which is unfortunately how most lazy image loaders work.
I am working on a lazyloader that uses valid html markup, github link:
https://github.com/tvler/lazy-progressive-enhancement
A lazyloaded image would be declared by wrapping it in a noscript element:
<noscript><img alt="hello!" src="..."></noscript>
and the final outputted html would be
<img alt="hello!" src="...">.
You can view the whole project on github, which deals with batch loading, event hooking & more, but here's the basic functionality at the scope of a single noscript image:
var noscript = document.querySelector('noscript'), img;
(img = document.createElement('div')).innerHTML = noscript.textContent;
noscript.parentElement.replaceChild(img.firstChild, noscript);

Flashing between page loads

On a website, I'm experiencing a "flash" of white that occurs between page loads. It looks bad because I'm using a background image and when the page loads, the background images flash before it comes onto the screen (take a look for yourself). This issues occurs in chrome and IE but not in firefox.
The site has a way of preloading stuff. Every element on the page is in a div wrapper #website which is initially at display:none, and every image is in a div wrapper #website-images which is also hidden. Then the site (using a jquery plugin) checks to see if all the images in #website-images are done loading, once they are a cookie is set to remember that this user has loaded the images already so it won't go through the preloading process once they go to another page or reload the current one, then a call to $("#website").show() is made to display the webpage.
So what could be causing this flickering between the page loads? Is it my way of preloading images? I've added different doctypes, and changed meta information but NOTHING has worked. I'm really lost here, does anyone have any ideas or insights?
This is happening because the DOMLoaded event is fired enough milliseconds before the page actually renders.
In a nutshell, this means you have to optimise your website's speed. This doesn't mean to make it download faster, but it means to download in the correct order, in a non-blocking way.
Step one: Your markup
1)
It seems there is a lot you can do to optimise your markup. Firstly, the order of stylesheets and JavaScripts can be optimised. To ensure CSS files are downloaded asynchronously, you always have to include external CSS before external JavaScript files. style.css is downloaded after some/all of your JavaScript calls.
There is 1 script block found in the head between an external CSS file and another resource. To allow parallel downloading, move the inline script before the external CSS file, or after the next resource.
2)
Your main JavaScript file is inline within your markup. Not only does this block the page download until the script has finished downloading, but having it before your content is probably causing (or adding to) the white flash.
Loading your script asynchronously in the head is my preferred method. You will then have to trigger your script when the DOM has finished loading, or you can achieve the same result by placing the script at the bottom of the body tag.
Step two: Harness the browser's capabilities
1) Looking at the http headers, there are 28 items being served as separate HTTP calls, that are not being cached on the browser (including the html pages, jpg images, stylesheets and JavaScript files).
These items are explicitly non-cacheable, and this can be easily fixed by editing your webserver's configuration.
2) Enable gzip compression. Most web browsers (yes, even IE) supports gzip decompression, and most (if not all) web servers support compressing using gzip. You could even go overkill and look into SPDY, which is an alternative lighter HTTP protocol (supported in Chrome and Firefox).
Step three: Content serving
There are around 30 individual items being served from your domain. Firstly, consider how you could reduce this number of requests. 30 HTTP requests per page view is a lot. You can combat this using the following methods:
1) Paralleled downloads across multiple hostnames. Browsers currently limit the number of concurrent connections to a single domain. Serving your images from a separate domain (for example, img.bigtim.ca) can allow them to be served in parallel to other content.
2) Combine multiple items into one. Many items that are downloaded are purely style content, such as the logo, menu elements, etc. These can be combined into a single image (downloaded only once), and split using CSS. This is called CSS spriting. Stack Overflow does this: look here.
3) If you cannot reduce the amount of items needing downloading, you could reduce the load on your server (and in turn, the client's browser) by serving static content from a cookieless domain. Stack Overflow does this with all their static content such as images, stylesheets and scripts.
Step four: Optimise your own code
There's only so much that HTTP and browser technology can do to help your website's speed. This last step is down to you.
1) Is there any reason you choose to host jquery yourself? Jquery's download page shows multiple CDNs where you can point to for speedy, cached script downloading.
2) There are currently over 20 unused CSS rules within your stylesheets (that's 36% of your entire CSS file). Have a re-think of what is really needed.
3) The main chunk of JavaScript (at the top of your body tag) seems to be a hack to attempt to speed things up, but is probably not helping anything.
A cookie is being set to specify whether or not the page has faded in yet. Not only are you using JavaScript to perform a transition which can happily be performed by CSS, but more than half of the script is used to define the functionality for reading and writing the cookie.
Seeing things like this: $("body").css ("background-image", "url('images/background.png')"); and $("#website").show (); usually gets me ranting about "separation of concerns", but this answer is long enough now so hopefully you can see that it is bad practice to mix style and functionality in the same code.
Addendum: Looking at the code, there is no need for jquery at all to
perform what you are doing. But then again, there is no need to
perform what you are doing, so you could probably do better without any
JavaScript at all.
Move your javascript to the end of the html just before closing the body tags. Sometimes it helps.
I know this is old thread but here is a hack I tried and works.
The idea is not to display anything while CSS is loaded completely.
in html file:
<body style="display:none">
in your CSS, the last line:
body{display:block !important}
CSS is render-blocking.
Divide you CSS into 2 parts -
Critical CSS
Non-Critical CSS
Make Critical CSS load with the page. It should come embedded within the head tag.
Make Non-critical CSS lazy load via ajax.
This will result in serious performance optimization in your webpage leading to less white-screen time.
Also, you can consider loading your Javascript in async/defer way.

Re-base relative URLs in HTML returned from AJAX requests

I have a webpage that does various AJAX requests (over time) to load HTML fragments that are displayed on the page. The HTML that is returned sometimes contains relative URLs (in a[href], img[src], etc.) and I can't easily change that on the server-side. When the HTML is inserted into my document, these URLs are interpreted relative to the location of my webpage, which leads to wrong destinations.
I've thought about using something the HTML <base> element to rebase the relative URLs, but this affects the entire webpage at once, whereas I need to use a different base URL for each HTML fragment.
Currently the easiest solution seems the following: (i) load the HTML fragment in a DOM element (ii) visit all the nodes to absolutize the relative URLs and (iii) insert the resulting element into my document. However:
At step (i), I think the browser will already start loading images at the wrong locations? Can you prevent that?
For step (ii), is there a more or less comprehensive way to find all URL properties? a[href] and img[src] are the most important ones, but you may also have object[src], script[src] and other things that I'm forgetting.
Or is there a better way, perhaps using a Javascript HTML parser? I need to be able to handle pretty general HTML, but the set of supported browsers is limited (latest versions of Chrome, Mobile Safari). I'm using PrototypeJS, so code samples for this framework are most appreciated (but jQuery is fine too).

Categories

Resources