perf(frontend): Reduce getting clientWidth in MkMediaImage (#11386)

* perf(frontend): Reduce getting clientWidth

* fix

* ✌️
This commit is contained in:
tamaina 2023-07-26 16:50:54 +09:00 committed by GitHub
parent dc452bf89a
commit bc927b8f75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 29 additions and 2 deletions

View File

@ -22,6 +22,33 @@
</div>
</template>
<script lang="ts">
/**
* アスペクト比算出のためにHTMLElement.clientWidthを使うが
* 大変重たいのでコンテナ要素とメディアリスト幅のペアをキャッシュする
* タイムラインごとにスクロールコンテナが存在する前提だが
*/
const widthCache = new Map<Element, number>();
/**
* コンテナ要素がリサイズされたらキャッシュを削除する
*/
const ro = new ResizeObserver(entries => {
for (const entry of entries) {
widthCache.delete(entry.target);
}
});
function getClientWidthWithCache(targetEl: HTMLElement, containerEl: HTMLElement) {
if (widthCache.has(containerEl)) return widthCache.get(containerEl)!;
const width = targetEl.clientWidth;
widthCache.set(containerEl, width);
ro.observe(containerEl);
return width;
}
</script>
<script lang="ts" setup>
import { onMounted, shallowRef } from 'vue';
import * as misskey from 'misskey-js';
@ -62,7 +89,8 @@ function calcAspectRatio() {
return;
}
const width = gallery.value.clientWidth;
if (!container.value) container.value = getScrollContainer(root.value);
const width = container.value ? getClientWidthWithCache(root.value, container.value) : root.value.clientWidth;
const heightMin = (ratio: number) => {
const imgResizeRatio = width / img.properties.width;
@ -84,7 +112,6 @@ function calcAspectRatio() {
gallery.value.style.height = heightMin(3 / 2);
break;
default: {
if (!container.value) container.value = getScrollContainer(root.value);
const maxHeight = Math.max(64, (container.value ? container.value.clientHeight : getBodyScrollHeight()) * 0.5 || 360);
if (width === 0 || !maxHeight) return;
const imgResizeRatio = width / img.properties.width;