There must be a way to do this more efficiently. What I'm doing is conceptually very simple:
1) Call a web service and receive b64-encoded-string of a PDF blob.
2) Decode it, create blob, render PDF in new window. Account for pop-up blocker.
My code works. Nothing fancy. Its all client-side. Everything works but IE runs SUPER slow compared to the other browsers (IE 11 vs. current Chrome/Firefox/Safari).
In light of this I am certain I could do this more efficiently. Any tips on how to speed this up for IE 11?
Note: I'm using Jeremy's b64toBlob function (thanks Jeremy).
Part I: modal stuff
var box = new SimpleDialog(Dialogs.getNextId(), false);
box.title = "Fetching PDF";
box.isMovable = false;
box.extraClass = "";
box.width = 400;
box.isModal = true;
box.createDialog();
window.parent.box = box;
box.setContentInnerHTML('<p>Please wait....</p>');
box.show();
Part II: call external service, receive b64 encoded string
setTimeout(function(){
var response = ... ; //do callout... get data
var statusCode = ...; //parse from response
var b64Data = ... ; //parse from response
if(statusCode == 200) {
//Account for IE
if (navigator.appVersion.toString().indexOf('.NET') > 0) {
var blob = b64toBlob(b64Data, "application/pdf");
var fileURL = URL.createObjectURL(blob);
window.navigator.msSaveOrOpenBlob(blob, "theFile.pdf");
window.parent.box.cancel();
} else {
var blob = b64toBlob(b64Data, "application/pdf");
var fileURL = URL.createObjectURL(blob);
var pdfWin = window.open(fileURL,"_blank","width=1000,height=800");
if(!pdfWin) {
box.setTitle("Success: PDF has been retrieved");
box.setContentInnerHTML("<p align='left'></p><p align='left'>A popup blocker was detected. The PDF will not open automatically.<br /><br /></p><p align='left'><a onclick='window.parent.box.cancel();' target='_blank' href='"+fileURL +"' >Click here to view .pdf</a><br /><br /></p><p align='center'><button class='btn' onclick='window.parent.box.cancel(); return false;'>Cancel</button></p>");
} else {
window.parent.box.cancel();
}
}
} else {
box.setTitle("Error fetching PDF");
box.setContentInnerHTML("<p align='left'><img src='/img/msg_icons/warning32.png' style='margin:0 5px;'/></p><p align='left'>Unable to retrieve PDF.</p><p align='center'><button class='btn' onclick='window.parent.box.cancel(); return false;'>OK</button></p>");
}
},200);
I don't really see any slowness, and this plunkr run in IE, (using an update on the original "Jeremy" solution) works just fine:
Sample pdf
There was an update in the original post that improves the answer further:
function base64toBlob(base64Data, contentType, sliceSize) {
var byteCharacters,
byteArray,
byteNumbers,
blobData,
blob;
contentType = contentType || '';
byteCharacters = atob(base64Data);
// Get blob data sliced or not
blobData = sliceSize ? getBlobDataSliced() : getBlobDataAtOnce();
blob = new Blob(blobData, { type: contentType });
return blob;
/*
* Get blob data in one slice.
* => Fast in IE on new Blob(...)
*/
function getBlobDataAtOnce() {
byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
byteArray = new Uint8Array(byteNumbers);
return [byteArray];
}
/*
* Get blob data in multiple slices.
* => Slow in IE on new Blob(...)
*/
function getBlobDataSliced() {
var slice,
byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
slice = byteCharacters.slice(offset, offset + sliceSize);
byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
byteArray = new Uint8Array(byteNumbers);
// Add slice
byteArrays.push(byteArray);
}
return byteArrays;
}
}
From the answer here:
martinoss answer
Is the plunkr slow for you? Can you put in some logging to understand which call is actually slow? Put in a timer and log each line. on the IE route. Which one is reporting "slowness"?
Update On the plunkr, I've put a very simple timer, it shows that there is just 46ms approx taken to get the PDF to you in IE11. Obviously it's not multithreaded, but it is an indication.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With