Skip to content

Commit

Permalink
Merge pull request #9 from addyosmani/surm-review
Browse files Browse the repository at this point in the history
Clean up promises
  • Loading branch information
addyosmani committed Dec 6, 2018
2 parents cb2c03d + e4923ee commit 55a793b
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 85 deletions.
72 changes: 34 additions & 38 deletions src/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,23 @@ import requestIdleCallback from './request-idle-callback.mjs';
* @return {Promise} resolving with list of URLs found
*/
function fetchInViewportLinks(el, options) {
return new Promise((resolve, reject) => {
const urls = [];
const links = el.querySelectorAll('a');
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
// Link is in the view
if (entry.intersectionRatio > 0) {
urls.push(entry.target.href);
} else {
// Link is out of the view
}
const links = Array.from(el.querySelectorAll('a'));
const observer = new IntersectionObserver(entries => {
const urls = entries
.filter(entry => entry.isIntersecting)
.map(entry => {
observer.unobserve(entry.target);
return entry.target.href;
});
// prefetch() maintains a list of in-memory URLs
// previously fetched so we don't attempt a refetch
prefetchURLs(urls, options.priority);
resolve(urls);
});
links.forEach(link => {
observer.observe(link);
});
// prefetch() maintains a list of in-memory URLs
// previously fetched so we don't attempt a refetch
prefetchURLs(urls, options.priority);
});
links.forEach(link => {
observer.observe(link);
});
// Return a list of found URLs
return links.map(link => link.href);
};

/**
Expand All @@ -54,7 +50,7 @@ function fetchInViewportLinks(el, options) {
* @param {Array} urls - Array of URLs to prefetch
* @param {string} priority - "priority" of the request
*/
const prefetchURLs = function (urls, priority) {
function prefetchURLs(urls, priority) {
urls.forEach(url => {
prefetch(url, priority);
});
Expand All @@ -75,24 +71,24 @@ const prefetchURLs = function (urls, priority) {
* @return {Object} Promise
*/
export default function (options) {
return new Promise((resolve, reject) => {
options = options || {
options = {
... {
priority: 'low',
timeout: 2000,
};
const timeoutFn = options.timeoutFn || requestIdleCallback;
timeoutFn(() => {
// Prefetch an array of URLs if supplied (as an override)
if (options.urls !== undefined && options.urls.length > 0) {
prefetchURLs(options.urls, options.priority);
resolve(options.urls);
} else {
// Element to extract in-viewport links for
const el = options.el || document;
fetchInViewportLinks(el, options).then(urls => {
resolve(urls);
});
}
}, {timeout: options.timeout});
});
timeoutFn: requestIdleCallback,
el: document
},
...options
};

options.timeoutFn(() => {
// Prefetch an array of URLs if supplied (as an override)
if (options.urls !== undefined && options.urls.length > 0) {
prefetchURLs(options.urls, options.priority);
return options.urls;
} else {
// Element to extract in-viewport links for
return fetchInViewportLinks(options.el, options);
}
}, {timeout: options.timeout});
}
78 changes: 31 additions & 47 deletions src/prefetch.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -94,25 +94,17 @@ function xhrPrefetchStrategy(url) {
* @return {Object} a Promise
*/
function highPriFetchStrategy(url) {
return new Promise((resolve, reject) => {
// TODO: Investigate using preload for high-priority
// fetches. May have to sniff file-extension to provide
// valid 'as' values. In the future, we may be able to
// use Priority Hints here.
if (self.fetch === undefined) {
xhrPrefetchStrategy(url)
.then(() => {
resolve();
});
} else {
// As of 2018, fetch() is high-priority in Chrome
// and medium-priority in Safari.
fetch(url, {credentials: `include`})
.then(() => {
resolve();
});
}
});
// TODO: Investigate using preload for high-priority
// fetches. May have to sniff file-extension to provide
// valid 'as' values. In the future, we may be able to
// use Priority Hints here.
if (self.fetch === undefined) {
return xhrPrefetchStrategy(url);
} else {
// As of 2018, fetch() is high-priority in Chrome
// and medium-priority in Safari.
return fetch(url, {credentials: `include`});
}
};

const supportedPrefetchStrategy = support(`prefetch`)
Expand All @@ -125,40 +117,32 @@ const supportedPrefetchStrategy = support(`prefetch`)
* @param {string} priority - preferred fetch priority (`low` or `high`)
* @return {Object} a Promise
*/
function prefetcher(url, priority) {
return new Promise(resolve => {
if ('connection' in navigator) {
// Don't prefetch if the user is on 2G..
if (navigator.connection.effectiveType && /\slow-2g|2g/.test(navigator.connection.effectiveType)) {
resolve();
return;
}
// Don't prefetch if Save-Data is enabled..
if (navigator.connection.saveData) {
resolve();
return;
}
async function prefetcher(url, priority) {
if (preFetched[url]) {
return;
}

if ('connection' in navigator) {
// Don't prefetch if the user is on 2G..
if ((navigator.connection.effectiveType || "").includes("2g")) {
return;
}
if (preFetched[url]) {
resolve();
// Don't prefetch if Save-Data is enabled..
if (navigator.connection.saveData) {
return;
}
}

try {
if (priority && priority === `high`) {
highPriFetchStrategy(url)
.then(() => {
resolve();
preFetched[url] = true;
})
.catch(() => { });
await highPriFetchStrategy(url);
} else {
supportedPrefetchStrategy(url)
.then(() => {
resolve();
preFetched[url] = true;
})
.catch(() => { });
await supportedPrefetchStrategy(url);
};
});
preFetched[url] = true;
} catch(e) {
// Wanna do something?
}
};

export default prefetcher;

0 comments on commit 55a793b

Please sign in to comment.