mirror of
https://github.com/zoldar/jenot.git
synced 2026-01-03 14:32:54 +00:00
Optimize notes rendering reducing DOM updates
This commit is contained in:
parent
8774683919
commit
8e8c37b1c5
1 changed files with 81 additions and 34 deletions
|
|
@ -113,48 +113,95 @@ editNote.addEventListener("deleteNote", async (e) => {
|
||||||
Notes.saveStorage();
|
Notes.saveStorage();
|
||||||
});
|
});
|
||||||
|
|
||||||
// All notes are currently re-rendered on each storage
|
// The notes rendering routine is optimized to replace only
|
||||||
// update. The routine will be optimized to replace only
|
// nodes that actually changed.
|
||||||
// nodes that actually changed - most likely based on unique
|
|
||||||
// note IDs associated with block elements.
|
let currentNotes = {};
|
||||||
|
|
||||||
|
function notesEqual(note1, note2) {
|
||||||
|
return note1.id === note2.id && note1.updated === note2.updated;
|
||||||
|
}
|
||||||
|
|
||||||
async function render() {
|
async function render() {
|
||||||
const notes = await Notes.all();
|
const notes = await Notes.all();
|
||||||
const notesContainer = document.querySelector("#notes");
|
const notesContainer = document.querySelector("#notes");
|
||||||
notesContainer.replaceChildren();
|
|
||||||
|
let previousId = null;
|
||||||
|
let notePrecedence = {};
|
||||||
|
const ids = [];
|
||||||
|
|
||||||
|
notes.forEach((n) => {
|
||||||
|
notePrecedence[n.id] = previousId;
|
||||||
|
ids.push(n.id);
|
||||||
|
previousId = n.id;
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(currentNotes)
|
||||||
|
.filter((id) => !ids.includes(id))
|
||||||
|
.forEach((id) => {
|
||||||
|
delete currentNotes[id];
|
||||||
|
document.getElementById(id).remove();
|
||||||
|
});
|
||||||
|
|
||||||
notes.forEach((note) => {
|
notes.forEach((note) => {
|
||||||
const container = document.createElement("div");
|
const existingNote = currentNotes[note.id];
|
||||||
container.id = note.id;
|
|
||||||
container.classList.add("note");
|
|
||||||
container.classList.add("readonly");
|
|
||||||
|
|
||||||
if (note.type === "note") {
|
if (!existingNote) {
|
||||||
container.replaceChildren(...renderText(note.content));
|
const noteElement = renderNote(note);
|
||||||
} else if (note.type === "tasklist") {
|
const beforeId = notePrecedence[note.id];
|
||||||
const list = document.createElement("ul");
|
|
||||||
|
|
||||||
note.content.forEach((task) => {
|
if (!beforeId) {
|
||||||
const item = document.createElement("li");
|
notesContainer.prepend(noteElement);
|
||||||
const check = document.createElement("p");
|
} else {
|
||||||
check.textContent = task.checked ? "☑" : "☐";
|
const before = document.getElementById(beforeId);
|
||||||
item.appendChild(check);
|
if (before) {
|
||||||
const itemContent = document.createElement("p");
|
before.after(noteElement);
|
||||||
itemContent.replaceChildren(...renderText(task.content));
|
} else {
|
||||||
item.appendChild(itemContent);
|
notesContainer.prepend(noteElement);
|
||||||
list.append(item);
|
}
|
||||||
});
|
}
|
||||||
|
} else if (!notesEqual(existingNote, note)) {
|
||||||
container.appendChild(list);
|
const noteElement = renderNote(note);
|
||||||
|
const existing = document.getElementById(note.id);
|
||||||
|
existing.replaceWith(noteElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
notesContainer.appendChild(container);
|
|
||||||
|
|
||||||
container.addEventListener("click", async (e) => {
|
|
||||||
newNote.classList.add("hidden");
|
|
||||||
editNote.classList.remove("hidden");
|
|
||||||
const note = await Notes.get(container.id);
|
|
||||||
editNote.load(note);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
currentNotes = {};
|
||||||
|
notes.forEach((n) => (currentNotes[n.id] = n));
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderNote(note) {
|
||||||
|
const container = document.createElement("div");
|
||||||
|
container.id = note.id;
|
||||||
|
container.classList.add("note");
|
||||||
|
container.classList.add("readonly");
|
||||||
|
|
||||||
|
if (note.type === "note") {
|
||||||
|
container.replaceChildren(...renderText(note.content));
|
||||||
|
} else if (note.type === "tasklist") {
|
||||||
|
const list = document.createElement("ul");
|
||||||
|
|
||||||
|
note.content.forEach((task) => {
|
||||||
|
const item = document.createElement("li");
|
||||||
|
const check = document.createElement("p");
|
||||||
|
check.textContent = task.checked ? "☑" : "☐";
|
||||||
|
item.appendChild(check);
|
||||||
|
const itemContent = document.createElement("p");
|
||||||
|
itemContent.replaceChildren(...renderText(task.content));
|
||||||
|
item.appendChild(itemContent);
|
||||||
|
list.append(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
container.appendChild(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
container.addEventListener("click", async (e) => {
|
||||||
|
newNote.classList.add("hidden");
|
||||||
|
editNote.classList.remove("hidden");
|
||||||
|
const note = await Notes.get(container.id);
|
||||||
|
editNote.load(note);
|
||||||
|
});
|
||||||
|
|
||||||
|
return container;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue