@@ -54,17 +54,39 @@ class DOM {
5454 if ( h . classes && h . classes . length ) {
5555 empty = false
5656 let classes = $ ( '<ul>' , { class : 'classes' } ) . appendTo ( elem )
57- classes . append ( await Promise . all ( h . classes . map ( async ( c ) => {
58- return await this . makeClass ( c )
59- } ) ) )
57+ // バッチ処理で段階的に要素を追加
58+ const classBatchSize = 10
59+ for ( let i = 0 ; i < h . classes . length ; i += classBatchSize ) {
60+ const batch = h . classes . slice ( i , i + classBatchSize )
61+ const batchElements = await Promise . all ( batch . map ( async ( c ) => {
62+ return await this . makeClass ( c )
63+ } ) )
64+ classes . append ( batchElements )
65+
66+ // iOS Safariに処理時間を与える
67+ if ( i + classBatchSize < h . classes . length ) {
68+ await new Promise ( resolve => setTimeout ( resolve , 0 ) )
69+ }
70+ }
6071 }
6172
6273 if ( h . others && h . others . length ) {
6374 empty = false
6475 let others = $ ( '<ul>' , { class : 'others' } ) . appendTo ( elem )
65- others . append ( await Promise . all ( h . others . map ( async ( o ) => {
66- return await this . makeOther ( o )
67- } ) ) )
76+ // バッチ処理で段階的に要素を追加
77+ const otherBatchSize = 10
78+ for ( let i = 0 ; i < h . others . length ; i += otherBatchSize ) {
79+ const batch = h . others . slice ( i , i + otherBatchSize )
80+ const batchElements = await Promise . all ( batch . map ( async ( o ) => {
81+ return await this . makeOther ( o )
82+ } ) )
83+ others . append ( batchElements )
84+
85+ // iOS Safariに処理時間を与える
86+ if ( i + otherBatchSize < h . others . length ) {
87+ await new Promise ( resolve => setTimeout ( resolve , 0 ) )
88+ }
89+ }
6890 }
6991
7092 if ( empty ) {
@@ -359,48 +381,63 @@ class Treeview {
359381
360382 const cats = this . kc . categories ( )
361383
362- root . append ( await Promise . all (
363- this . tree . filter ( ( top ) => top . category . index !== cats . get ( 'index' ) . index ) . map ( async ( top ) => {
364- const topID = top . namespace . namespace [ 0 ]
365- let stack = $ ( '<li>' , {
366- class : 'top stack' ,
367- 'data-top-id' : topID ,
368- } )
369-
370- this . dom . topElems . set ( topID , stack )
371-
372- stack . append (
373- $ ( '<div>' , { class : 'heading' } )
374- . append (
375- $ ( '<div>' , { class : 'expander' } ) . on (
376- 'click' , async ( ) => { this . dom . doStackExpand ( topID ) }
384+ // バッチ処理で段階的にDOM要素を生成
385+ const filteredTops = this . tree . filter ( ( top ) => top . category . index !== cats . get ( 'index' ) . index )
386+ const batchSize = 5 // 一度に処理する要素数
387+
388+ for ( let i = 0 ; i < filteredTops . length ; i += batchSize ) {
389+ const batch = filteredTops . slice ( i , i + batchSize )
390+ const batchElements = await Promise . all (
391+ batch . map ( async ( top ) => {
392+ const topID = top . namespace . namespace [ 0 ]
393+ let stack = $ ( '<li>' , {
394+ class : 'top stack' ,
395+ 'data-top-id' : topID ,
396+ } )
397+
398+ this . dom . topElems . set ( topID , stack )
399+
400+ stack . append (
401+ $ ( '<div>' , { class : 'heading' } )
402+ . append (
403+ $ ( '<div>' , { class : 'expander' } ) . on (
404+ 'click' , async ( ) => { this . dom . doStackExpand ( topID ) }
405+ )
377406 )
378- )
379- . append ( await this . dom . makeTitle ( top ) )
380- )
407+ . append ( await this . dom . makeTitle ( top ) )
408+ )
381409
382- let content_wrapper =
383- $ ( '<div>' , { class : 'content-wrapper' } )
384- . appendTo ( stack )
410+ let content_wrapper =
411+ $ ( '<div>' , { class : 'content-wrapper' } )
412+ . appendTo ( stack )
385413
386- let content =
387- $ ( '<div>' , { class : 'content' } )
388- . appendTo ( content_wrapper )
414+ let content =
415+ $ ( '<div>' , { class : 'content' } )
416+ . appendTo ( content_wrapper )
389417
390- let is_not_empty = false
391- if ( top . category . index === cats . get ( 'lang' ) . index ) {
392- is_not_empty = await this . processLangTop ( top , content )
393- } else {
394- is_not_empty = await this . processTop ( top , content )
395- }
418+ let is_not_empty = false
419+ if ( top . category . index === cats . get ( 'lang' ) . index ) {
420+ is_not_empty = await this . processLangTop ( top , content )
421+ } else {
422+ is_not_empty = await this . processTop ( top , content )
423+ }
396424
397- if ( ! is_not_empty ) {
398- stack . addClass ( 'empty' )
399- }
425+ if ( ! is_not_empty ) {
426+ stack . addClass ( 'empty' )
427+ }
400428
401- return stack
402- } )
403- ) )
429+ return stack
430+ } )
431+ )
432+
433+ // バッチごとにDOMに追加
434+ root . append ( batchElements )
435+
436+ // iOS Safariに処理時間を与える
437+ if ( i + batchSize < filteredTops . length ) {
438+ await new Promise ( resolve => setTimeout ( resolve , 0 ) )
439+ }
440+ }
404441 }
405442
406443 async processTop ( top , e ) {
@@ -409,9 +446,21 @@ class Treeview {
409446 if ( top . articles && top . articles . length ) {
410447 is_empty = false
411448
412- let self = $ ( '<ul>' , { class : 'articles' } ) . append ( await Promise . all ( top . articles . map ( async ( ar ) => {
413- return await this . dom . makeArticle ( ar )
414- } ) ) )
449+ let self = $ ( '<ul>' , { class : 'articles' } )
450+ // バッチ処理で段階的に要素を追加
451+ const articleBatchSize = 10
452+ for ( let i = 0 ; i < top . articles . length ; i += articleBatchSize ) {
453+ const batch = top . articles . slice ( i , i + articleBatchSize )
454+ const batchElements = await Promise . all ( batch . map ( async ( ar ) => {
455+ return await this . dom . makeArticle ( ar )
456+ } ) )
457+ self . append ( batchElements )
458+
459+ // iOS Safariに処理時間を与える
460+ if ( i + articleBatchSize < top . articles . length ) {
461+ await new Promise ( resolve => setTimeout ( resolve , 0 ) )
462+ }
463+ }
415464
416465 e . append ( await this . dom . kunaiBranch ( self , 'articles' ) )
417466 }
0 commit comments