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 //Pre-load all images in case user wants to print them
if (params.imageDisplay) { if (params.imageDisplay) {
loadImagesJQuery(10000); loadImagesJQuery(printIntercept);
document.getElementById("printImageCheck").disabled = false; document.getElementById("printImageCheck").disabled = false;
} else { } else {
document.getElementById("printImageCheck").checked = false; document.getElementById("printImageCheck").checked = false;
@ -2122,12 +2122,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'images', 'cookies', 'q', 'trans
docBody.addEventListener('dragover', handleIframeDragover); docBody.addEventListener('dragover', handleIframeDragover);
docBody.addEventListener('drop', handleIframeDrop); docBody.addEventListener('drop', handleIframeDrop);
} }
if (/manual|progressive/.test(params.imageDisplayMode)) { if (/manual|progressive/.test(params.imageDisplayMode)) images.prepareImagesServiceWorker();
var imageList = doc.querySelectorAll('img');
if (imageList.length) {
images.prepareImagesServiceWorker(imageList, params.imageDisplayMode);
}
}
iframeArticleContent.contentWindow.onunload = function () { iframeArticleContent.contentWindow.onunload = function () {
$("#searchingArticles").show(); $("#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 //loadJavascript(); //Disabled for now, since it does nothing - also, would have to load before images, ideally through controlled css loads above
insertMediaBlobsJQuery(); insertMediaBlobsJQuery();
var determinedTheme = params.cssTheme == 'auto' ? cssUIThemeGetOrSet('auto') : params.cssTheme; var determinedTheme = params.cssTheme == 'auto' ? cssUIThemeGetOrSet('auto') : params.cssTheme;
@ -2994,7 +2989,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'images', 'cookies', 'q', 'trans
if (params.preloadingAllImages !== true) { if (params.preloadingAllImages !== true) {
$('#searchingArticles').show(); $('#searchingArticles').show();
params.preloadingAllImages = true; params.preloadingAllImages = true;
if (params.imageDisplay) loadImagesJQuery(10000); if (params.imageDisplay) images.prepareImagesJQuery(printIntercept);
return; return;
} }
// All images should now be loaded, or else user did not request loading images // All images should now be loaded, or else user did not request loading images
@ -3002,30 +2997,6 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'images', 'cookies', 'q', 'trans
$('#searchingArticles').hide(); $('#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. * This is the main image loading function.
* Contains four sub functions: prepareImages, triageImages, displaySlices, loadImageSlice * Contains four sub functions: prepareImages, triageImages, displaySlices, loadImageSlice

View File

@ -23,6 +23,11 @@
define(['uiUtil'], function (uiUtil) { 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 * 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 * 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) { function prepareImagesServiceWorker () {
var zimImages = []; var iframe = document.getElementById('articleContent');
for (var i = 0, l = images.length; i < l; i++) { 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 // 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)) { if (/(^|\/)[IJ]\/.*\.(jpe?g|png|svg|gif)($|[?#])/i.test(images[i].src)) {
images[i].dataset.kiwixurl = images[i].getAttribute('src'); documentImages[i].dataset.kiwixurl = documentImages[i].getAttribute('src');
images[i].style.transition = 'opacity 0.5s ease-in'; documentImages[i].style.transition = 'opacity 0.5s ease-in';
if (displayType === 'progressive') { if (displayType === 'progressive') {
images[i].style.opacity = '0'; documentImages[i].style.opacity = '0';
} }
zimImages.push(images[i]);
} }
} }
if (displayType === 'manual') { if (params.imageDisplayMode === 'manual') {
prepareManualExtraction(zimImages); prepareManualExtraction();
} else { } 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) * 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 * progressive image extraction
*/ */
function lazyLoad(images) { function lazyLoad() {
// The amount by which to offset the second reading of the viewport // The amount by which to offset the second reading of the viewport
var offset = window.innerHeight; var offset = window.innerHeight;
// Perform an immediate extraction of visible images so as not to disconcert the user // 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 // 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 () { queueImages(documentImages, true, 0, function () {
images = queueImages(images, true, window.innerHeight).remaining; queueImages(documentImages, true, window.innerHeight);
}).remaining; });
if (!images.length) return; 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 // 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 iframe = document.getElementById('articleContent');
var iframeWindow = iframe.contentWindow; var iframeWindow = iframe.contentWindow;
@ -214,18 +241,18 @@ define(['uiUtil'], function (uiUtil) {
var rateLimiter = 0; var rateLimiter = 0;
// NB we add the event listener this way so we can access it in app.js // NB we add the event listener this way so we can access it in app.js
iframeWindow.onscroll = function () { iframeWindow.onscroll = function () {
if (!images.length) return; if (!documentImages.length) return;
var velo = iframeWindow.pageYOffset - scrollPos; var velo = iframeWindow.pageYOffset - scrollPos;
if (velo < 15 && velo > -15) { if (velo < 15 && velo > -15) {
// Scroll is now quite slow, so start getting images in viewport // Scroll is now quite slow, so start getting images in viewport
images = queueImages(images, true, 0, function () { queueImages(documentImages, true, 0, function () {
if (!rateLimiter) { if (!rateLimiter) {
rateLimiter = 1; rateLimiter = 1;
images = queueImages(images, true, velo >= 0 ? offset : -offset, function () { queueImages(documentImages, true, velo >= 0 ? offset : -offset, function () {
rateLimiter = 0; rateLimiter = 0;
}).remaining; });
} }
}).remaining; });
} }
scrollPos = iframeWindow.pageYOffset; scrollPos = iframeWindow.pageYOffset;
}; };
@ -259,6 +286,7 @@ define(['uiUtil'], function (uiUtil) {
extractImages: extractImages, extractImages: extractImages,
setupManualImageExtraction: prepareManualExtraction, setupManualImageExtraction: prepareManualExtraction,
prepareImagesServiceWorker: prepareImagesServiceWorker, prepareImagesServiceWorker: prepareImagesServiceWorker,
prepareImagesJQuery: prepareImagesJQuery,
lazyLoad: lazyLoad, lazyLoad: lazyLoad,
loadMathJax: loadMathJax loadMathJax: loadMathJax
}; };