mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-21 06:45:00 +00:00
only preload once - fixes #49
This commit is contained in:
@@ -42,6 +42,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"cy:open": "cypress open",
|
"cy:open": "cypress open",
|
||||||
"test": "mocha --opts mocha.opts",
|
"test": "mocha --opts mocha.opts",
|
||||||
|
"pretest": "npm run build",
|
||||||
"build": "rollup -c",
|
"build": "rollup -c",
|
||||||
"dev": "rollup -cw"
|
"dev": "rollup -cw"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -37,38 +37,43 @@ function select_route(url: URL): { route: Route, data: RouteData } {
|
|||||||
|
|
||||||
let current_token: {};
|
let current_token: {};
|
||||||
|
|
||||||
function render(Component: ComponentConstructor, data: { query: Query, params: Params }, scroll: ScrollPosition, token: {}) {
|
function render(Component: ComponentConstructor, data: any, scroll: ScrollPosition, token: {}) {
|
||||||
Promise.resolve(
|
if (current_token !== token) return;
|
||||||
|
|
||||||
|
if (component) {
|
||||||
|
component.destroy();
|
||||||
|
} else {
|
||||||
|
// first load — remove SSR'd <head> contents
|
||||||
|
const start = document.querySelector('#sapper-head-start');
|
||||||
|
const end = document.querySelector('#sapper-head-end');
|
||||||
|
|
||||||
|
if (start && end) {
|
||||||
|
while (start.nextSibling !== end) detach(start.nextSibling);
|
||||||
|
detach(start);
|
||||||
|
detach(end);
|
||||||
|
}
|
||||||
|
|
||||||
|
// preload additional routes
|
||||||
|
routes.reduce((promise: Promise<any>, route) => promise.then(route.load), Promise.resolve());
|
||||||
|
}
|
||||||
|
|
||||||
|
component = new Component({
|
||||||
|
target,
|
||||||
|
data,
|
||||||
|
hydrate: !!component
|
||||||
|
});
|
||||||
|
|
||||||
|
if (scroll) {
|
||||||
|
window.scrollTo(scroll.x, scroll.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepare_route(Component, data) {
|
||||||
|
return Promise.resolve(
|
||||||
Component.preload ? Component.preload(data) : {}
|
Component.preload ? Component.preload(data) : {}
|
||||||
).then(preloaded => {
|
).then(preloaded => {
|
||||||
if (current_token !== token) return;
|
Object.assign(data, preloaded)
|
||||||
|
return { Component, data };
|
||||||
if (component) {
|
|
||||||
component.destroy();
|
|
||||||
} else {
|
|
||||||
// first load — remove SSR'd <head> contents
|
|
||||||
const start = document.querySelector('#sapper-head-start');
|
|
||||||
const end = document.querySelector('#sapper-head-end');
|
|
||||||
|
|
||||||
if (start && end) {
|
|
||||||
while (start.nextSibling !== end) detach(start.nextSibling);
|
|
||||||
detach(start);
|
|
||||||
detach(end);
|
|
||||||
}
|
|
||||||
|
|
||||||
// preload additional routes
|
|
||||||
routes.reduce((promise: Promise<any>, route) => promise.then(route.load), Promise.resolve());
|
|
||||||
}
|
|
||||||
|
|
||||||
component = new Component({
|
|
||||||
target,
|
|
||||||
data: Object.assign(data, preloaded),
|
|
||||||
hydrate: !!component
|
|
||||||
});
|
|
||||||
|
|
||||||
if (scroll) {
|
|
||||||
window.scrollTo(scroll.x, scroll.y);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,8 +91,16 @@ function navigate(url: URL, id: number) {
|
|||||||
scroll_history[cid] = { x: 0, y: 0 };
|
scroll_history[cid] = { x: 0, y: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
selected.route.load().then(mod => {
|
const loaded = prefetching && prefetching.href === url.href ?
|
||||||
render(mod.default, selected.data, scroll_history[id], current_token = {});
|
prefetching.promise :
|
||||||
|
selected.route.load().then(mod => prepare_route(mod.default, selected.data));
|
||||||
|
|
||||||
|
prefetching = null;
|
||||||
|
|
||||||
|
const token = current_token = {};
|
||||||
|
|
||||||
|
loaded.then(({ Component, data }) => {
|
||||||
|
render(Component, data, scroll_history[id], token);
|
||||||
});
|
});
|
||||||
|
|
||||||
cid = id;
|
cid = id;
|
||||||
@@ -146,6 +159,11 @@ function handle_popstate(event: PopStateEvent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let prefetching: {
|
||||||
|
href: string;
|
||||||
|
promise: Promise<{ Component: ComponentConstructor, data: any }>;
|
||||||
|
} = null;
|
||||||
|
|
||||||
function prefetch(event: MouseEvent | TouchEvent) {
|
function prefetch(event: MouseEvent | TouchEvent) {
|
||||||
const a: HTMLAnchorElement = <HTMLAnchorElement>findAnchor(<Node>event.target);
|
const a: HTMLAnchorElement = <HTMLAnchorElement>findAnchor(<Node>event.target);
|
||||||
if (!a || a.rel !== 'prefetch') return;
|
if (!a || a.rel !== 'prefetch') return;
|
||||||
@@ -153,9 +171,10 @@ function prefetch(event: MouseEvent | TouchEvent) {
|
|||||||
const selected = select_route(new URL(a.href));
|
const selected = select_route(new URL(a.href));
|
||||||
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
selected.route.load().then(mod => {
|
prefetching = {
|
||||||
if (mod.default.preload) mod.default.preload(selected.data);
|
href: a.href,
|
||||||
});
|
promise: selected.route.load().then(mod => prepare_route(mod.default, selected.data))
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user