I just discovered that Chrome doesn't cache images which are placed inside SVGs if their cache-control
header is set to no-cache
. Firefox & IE10 seem to ignore this setting.
I've created a little test page with a static SVG:
HTML:
<div style="width: 500px; text-align: center;">
<input id="move-left-btn" type="button" value="<<">
<input id="move-right-btn" type="button" value=">>">
</div>
<div class="svgwrapper" style="width: 500px; height: 250px; background-color: lightgrey;">
<svg id="svg" version="1.1" xmlns="" width="500" height="250">
<g id="svggroup" class="transition-on" transform="matrix(0.2,0,0,0.2,80,35)">
<image width="1672" height="887" opacity="1" xlink:href=".png"></image>
</g>
</svg>
</div>
Javascript:
$(document).ready(function() {
var curXPos = 80;
// Local test function which represent some server calls in my "real life" scenario
// Just updates the x-position in the transform matrix in this test case
function updateSvgText(svgText, posXDelta) {
curXPos += posXDelta;
if (curXPos < 0) {
curXPos = 160;
} else if (curXPos > 160) {
curXPos = 0;
}
return svgText.replace(/matrix\(.*\)/, 'matrix(0.2,0,0,0.2,' + curXPos + ',35)');
}
// Fetch the new SVG (in real life from server) and rerender it
function moveSvg(posXDelta) {
var svg = $('#svg'),
svgText = updateSvgText($('.svgwrapper').html(), posXDelta);
svg.empty();
svg.append($(svgText).children());
}
$('#move-left-btn').click($.proxy(moveSvg, this, -20));
$('#move-right-btn').click($.proxy(moveSvg, this, 20));
});
Working example with
cache-control
header of source image set tono-cache
(flickers in chrome after every press on the "move" buttons):
/Same example with different source image with
cache-control
header set tomax-age=315360000,public
(no flickering):
/
In Chrome you can see the reloading of the images on each button click in the first example ("flickering" of the image & visible in the network tab of the dev tools) whereas Firefox rerenders the SVG in both examples smoothly without any reloading.
Some additional information:
This is just an example. In my "real-life-scenario" I receive a new SVG from the server (instead of the
updateSvgText
method call) which means that I can't just perform partial updates of the SVG by changing the value of the transform matrix attribute but have to rerender the whole SVG every time (at least by now...).I can't control where the images e from which means 2 things:
- I can't change the
cache-control
header - I can't create Base64 encoded data-uris, save them locally and just replace the images inside the SVG with those data-uris before rendering (can't create Base64 encoded data-uri because of "Same resource origin" policies...)
- I can't change the
Is there any way to either...
- Overwrite/overrule the
cache-control
header locally even if the image is from an uncontrolled remote location? - Create the Base64 encoded data-uri from an Image that is loaded from a different domain I don't have any control over client sided?
- Somehow tell Chrome to always cache images inside my SVGs?
Needless to say that other solutions are also very wele!
Thanks
I just discovered that Chrome doesn't cache images which are placed inside SVGs if their cache-control
header is set to no-cache
. Firefox & IE10 seem to ignore this setting.
I've created a little test page with a static SVG:
HTML:
<div style="width: 500px; text-align: center;">
<input id="move-left-btn" type="button" value="<<">
<input id="move-right-btn" type="button" value=">>">
</div>
<div class="svgwrapper" style="width: 500px; height: 250px; background-color: lightgrey;">
<svg id="svg" version="1.1" xmlns="http://www.w3/2000/svg" width="500" height="250">
<g id="svggroup" class="transition-on" transform="matrix(0.2,0,0,0.2,80,35)">
<image width="1672" height="887" opacity="1" xlink:href="https://dl.dropboxusercontent./sh/q7htlj5h8qqfhjf/SVDuynM7R3/car.png"></image>
</g>
</svg>
</div>
Javascript:
$(document).ready(function() {
var curXPos = 80;
// Local test function which represent some server calls in my "real life" scenario
// Just updates the x-position in the transform matrix in this test case
function updateSvgText(svgText, posXDelta) {
curXPos += posXDelta;
if (curXPos < 0) {
curXPos = 160;
} else if (curXPos > 160) {
curXPos = 0;
}
return svgText.replace(/matrix\(.*\)/, 'matrix(0.2,0,0,0.2,' + curXPos + ',35)');
}
// Fetch the new SVG (in real life from server) and rerender it
function moveSvg(posXDelta) {
var svg = $('#svg'),
svgText = updateSvgText($('.svgwrapper').html(), posXDelta);
svg.empty();
svg.append($(svgText).children());
}
$('#move-left-btn').click($.proxy(moveSvg, this, -20));
$('#move-right-btn').click($.proxy(moveSvg, this, 20));
});
Working example with
cache-control
header of source image set tono-cache
(flickers in chrome after every press on the "move" buttons):
http://jsfiddle/zF6NF/4/Same example with different source image with
cache-control
header set tomax-age=315360000,public
(no flickering):
http://jsfiddle/zF6NF/5/
In Chrome you can see the reloading of the images on each button click in the first example ("flickering" of the image & visible in the network tab of the dev tools) whereas Firefox rerenders the SVG in both examples smoothly without any reloading.
Some additional information:
This is just an example. In my "real-life-scenario" I receive a new SVG from the server (instead of the
updateSvgText
method call) which means that I can't just perform partial updates of the SVG by changing the value of the transform matrix attribute but have to rerender the whole SVG every time (at least by now...).I can't control where the images e from which means 2 things:
- I can't change the
cache-control
header - I can't create Base64 encoded data-uris, save them locally and just replace the images inside the SVG with those data-uris before rendering (can't create Base64 encoded data-uri because of "Same resource origin" policies...)
- I can't change the
Is there any way to either...
- Overwrite/overrule the
cache-control
header locally even if the image is from an uncontrolled remote location? - Create the Base64 encoded data-uri from an Image that is loaded from a different domain I don't have any control over client sided?
- Somehow tell Chrome to always cache images inside my SVGs?
Needless to say that other solutions are also very wele!
Thanks
Share Improve this question asked Oct 17, 2013 at 8:42 suamikimsuamikim 5,35910 gold badges44 silver badges81 bronze badges 1-
unrelated ment - the regexp may overmatch if there's another parentheses later in the text. So it should be
/matrix\([^)]*\)
or something. – Sanjay Manohar Commented Jan 17, 2017 at 16:33
1 Answer
Reset to default 3Unfortunately, when it es to caching, it's 99% the server's job.
In-dept guide : here
Browsers will always look for more recent versions of the file based on certain conditions:
- The cached entry has no expiration date and the content is being accessed for the first time in a browser session
- The cached entry has an expiration date but it has expired
- Cache-Control/Pragma tells the browser not to cache
- Etag in header is a pain.
In terms of solutions you have:
- Be very insistent to your server guys that you need caching (remove etag, Cache-Control: public,max-age=31536000, Pragma: public)
- Create a proxy on your domain that requires the image from the site, (optionally convert to base64) then send to your client (with the proper headers). Here's an example for PHP : here
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744936764a4602071.html
评论列表(0条)