Streamline image code (faster)

Former-commit-id: 74b5755d7a5aeb9a5b48efe8323beebebd091377 [formerly 27aebef21f5692dad7419fd69c73299b15bd0539]
Former-commit-id: 967048752f39160c840e7fadb367d31badf354b3
This commit is contained in:
Jaifroid 2019-06-14 22:10:13 +01:00
parent 6bd47a98c3
commit 0e0cb97103
2 changed files with 56 additions and 57 deletions

View File

@ -330,7 +330,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'images', 'cookies', 'q', 'trans
}
//Pre-load all images in case user wants to print them
if (params.imageDisplay) {
loadImagesJQuery(10000);
loadImagesJQuery(printIntercept);
document.getElementById("printImageCheck").disabled = false;
} else {
document.getElementById("printImageCheck").checked = false;
@ -2122,12 +2122,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'images', 'cookies', 'q', 'trans
docBody.addEventListener('dragover', handleIframeDragover);
docBody.addEventListener('drop', handleIframeDrop);
}
if (/manual|progressive/.test(params.imageDisplayMode)) {
var imageList = doc.querySelectorAll('img');
if (imageList.length) {
images.prepareImagesServiceWorker(imageList, params.imageDisplayMode);
}
}
if (/manual|progressive/.test(params.imageDisplayMode)) images.prepareImagesServiceWorker();
iframeArticleContent.contentWindow.onunload = function () {
$("#searchingArticles").show();
};
@ -2824,7 +2819,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'images', 'cookies', 'q', 'trans
}
});
loadImagesJQuery();
images.prepareImagesJQuery();
//loadJavascript(); //Disabled for now, since it does nothing - also, would have to load before images, ideally through controlled css loads above
insertMediaBlobsJQuery();
var determinedTheme = params.cssTheme == 'auto' ? cssUIThemeGetOrSet('auto') : params.cssTheme;
@ -2994,37 +2989,13 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'images', 'cookies', 'q', 'trans
if (params.preloadingAllImages !== true) {
$('#searchingArticles').show();
params.preloadingAllImages = true;
if (params.imageDisplay) loadImagesJQuery(10000);
if (params.imageDisplay) images.prepareImagesJQuery(printIntercept);
return;
}
// All images should now be loaded, or else user did not request loading images
uiUtil.extractHTML();
$('#searchingArticles').hide();
};
function loadImagesJQuery(forPrinting) {
var iframeArticleContent = document.getElementById('articleContent');
var imageNodes = iframeArticleContent.contentDocument.querySelectorAll('img[data-kiwixurl]');
if (!imageNodes.length) return;
if (forPrinting) {
images.extractImages(imageNodes, params.preloadingAllImages ? params.preloadAllImages : params.printIntercept ? printIntercept : null);
} else if (params.imageDisplayMode === 'progressive') {
// Firefox squashes empty images, but we don't want to alter the vertical heights constantly as we scroll
// so substitute empty images with a plain svg
for (var i = imageNodes.length; i--;) {
imageNodes[i].src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'/%3E";
imageNodes[i].style.opacity = '0';
imageNodes[i].style.transition = 'opacity 0.5s ease-in';
}
images.lazyLoad(imageNodes);
} else {
// User wishes to extract images manually
images.setupManualImageExtraction(imageNodes);
}
setTimeout(images.loadMathJax, 3000);
}
/**
* This is the main image loading function.

View File

@ -23,6 +23,11 @@
define(['uiUtil'], function (uiUtil) {
/**
* An array to hold all the images in the current document
*/
var documentImages = [];
/**
* A variable to keep track of how many images are being extracted by the extractor
*/
@ -168,45 +173,67 @@ define(['uiUtil'], function (uiUtil) {
/**
* Prepares an array or collection of image nodes that have been disabled in Service Worker for manual extraction
*
* @param {Object} images An array or collection of DOM image nodes
* @param {String} displayType If 'progressive', lazyLoad will be used; if 'manual', setupManualImageExtraction will be used
*/
function prepareImagesServiceWorker (images, displayType) {
var zimImages = [];
for (var i = 0, l = images.length; i < l; i++) {
function prepareImagesServiceWorker () {
var iframe = document.getElementById('articleContent');
var doc = iframe.contentDocument.documentElement;
documentImages = doc.getElementsByTagName('img');
if (!documentImages.length) return;
for (var i = 0, l = documentImages.length; i < l; i++) {
// DEV: make sure list of file types here is the same as the list in Service Worker code
if (/(^|\/)[IJ]\/.*\.(jpe?g|png|svg|gif)($|[?#])/i.test(images[i].src)) {
images[i].dataset.kiwixurl = images[i].getAttribute('src');
images[i].style.transition = 'opacity 0.5s ease-in';
documentImages[i].dataset.kiwixurl = documentImages[i].getAttribute('src');
documentImages[i].style.transition = 'opacity 0.5s ease-in';
if (displayType === 'progressive') {
images[i].style.opacity = '0';
documentImages[i].style.opacity = '0';
}
zimImages.push(images[i]);
}
}
if (displayType === 'manual') {
prepareManualExtraction(zimImages);
if (params.imageDisplayMode === 'manual') {
prepareManualExtraction();
} else {
lazyLoad(zimImages);
lazyLoad();
}
}
function prepareImagesJQuery (forPrinting) {
var iframe = document.getElementById('articleContent');
var doc = iframe.contentDocument.documentElement;
documentImages = doc.querySelectorAll('img[data-kiwixurl]');
if (!documentImages.length) return;
if (forPrinting) {
extractImages(documentImages, params.preloadingAllImages ? params.preloadAllImages : params.printIntercept ? forPrinting : null);
} else if (params.imageDisplayMode === 'progressive') {
// Firefox squashes empty images, but we don't want to alter the vertical heights constantly as we scroll
// so substitute empty images with a plain svg
for (var i = documentImages.length; i--;) {
documentImages[i].src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'/%3E";
documentImages[i].style.opacity = '0';
documentImages[i].style.transition = 'opacity 0.5s ease-in';
}
lazyLoad();
} else {
// User wishes to extract images manually
setupManualImageExtraction();
}
setTimeout(loadMathJax, 3000);
}
/**
* Processes an array or collection of image nodes so that they will be lazy loaded (progressive extraction)
*
* @param {Object} images And array or collection of DOM image nodes which will be processed for
* @param {Object} documentImages And array or collection of DOM image nodes which will be processed for
* progressive image extraction
*/
function lazyLoad(images) {
function lazyLoad() {
// The amount by which to offset the second reading of the viewport
var offset = window.innerHeight;
// Perform an immediate extraction of visible images so as not to disconcert the user
// We request images twice because frequently the position of all of them is not known at this stage in rendering
images = queueImages(images, true, 0, function () {
images = queueImages(images, true, window.innerHeight).remaining;
}).remaining;
if (!images.length) return;
queueImages(documentImages, true, 0, function () {
queueImages(documentImages, true, window.innerHeight);
});
if (!documentImages.length) return;
// There are images remaining, so set up an event listener to load more images once user has stopped scrolling the iframe
var iframe = document.getElementById('articleContent');
var iframeWindow = iframe.contentWindow;
@ -214,18 +241,18 @@ define(['uiUtil'], function (uiUtil) {
var rateLimiter = 0;
// NB we add the event listener this way so we can access it in app.js
iframeWindow.onscroll = function () {
if (!images.length) return;
if (!documentImages.length) return;
var velo = iframeWindow.pageYOffset - scrollPos;
if (velo < 15 && velo > -15) {
// Scroll is now quite slow, so start getting images in viewport
images = queueImages(images, true, 0, function () {
queueImages(documentImages, true, 0, function () {
if (!rateLimiter) {
rateLimiter = 1;
images = queueImages(images, true, velo >= 0 ? offset : -offset, function () {
queueImages(documentImages, true, velo >= 0 ? offset : -offset, function () {
rateLimiter = 0;
}).remaining;
});
}
}).remaining;
});
}
scrollPos = iframeWindow.pageYOffset;
};
@ -259,6 +286,7 @@ define(['uiUtil'], function (uiUtil) {
extractImages: extractImages,
setupManualImageExtraction: prepareManualExtraction,
prepareImagesServiceWorker: prepareImagesServiceWorker,
prepareImagesJQuery: prepareImagesJQuery,
lazyLoad: lazyLoad,
loadMathJax: loadMathJax
};