@@ -1756,6 +1756,78 @@ <h3 class="subsection-title" data-i18n="svg_demos_title">SVG Demos: Vector Graph
17561756
17571757 initLanguageToggle ( ) ;
17581758
1759+ function setVideoSourceState ( video , shouldAttach ) {
1760+ const source = video . querySelector ( "source" ) ;
1761+ if ( ! source ) return ;
1762+
1763+ const currentSrc = source . getAttribute ( "src" ) ;
1764+ if ( ! source . dataset . src && currentSrc ) {
1765+ source . dataset . src = currentSrc ;
1766+ }
1767+
1768+ if ( shouldAttach ) {
1769+ if ( ! source . getAttribute ( "src" ) && source . dataset . src ) {
1770+ source . setAttribute ( "src" , source . dataset . src ) ;
1771+ video . load ( ) ;
1772+ }
1773+ return ;
1774+ }
1775+
1776+ if ( source . getAttribute ( "src" ) ) {
1777+ video . pause ( ) ;
1778+ source . removeAttribute ( "src" ) ;
1779+ video . load ( ) ;
1780+ }
1781+ }
1782+
1783+ function updateCliDemoVideoSources ( activeDemoId ) {
1784+ document . querySelectorAll ( ".video-section" ) . forEach ( ( section ) => {
1785+ const shouldAttach = section . id === activeDemoId ;
1786+ section . querySelectorAll ( "video" ) . forEach ( ( video ) => {
1787+ video . preload = "none" ;
1788+ setVideoSourceState ( video , shouldAttach ) ;
1789+ } ) ;
1790+ } ) ;
1791+ }
1792+
1793+ function initCliDemoVideoOptimization ( ) {
1794+ const visibleSection = Array . from ( document . querySelectorAll ( ".video-section" ) )
1795+ . find ( ( section ) => getComputedStyle ( section ) . display !== "none" ) ;
1796+ updateCliDemoVideoSources ( visibleSection ?. id || "demo1" ) ;
1797+ }
1798+
1799+ function initDemoIframeLazyLoad ( ) {
1800+ const iframes = Array . from ( document . querySelectorAll ( ".demo-iframe" ) ) ;
1801+ if ( ! iframes . length ) return ;
1802+
1803+ iframes . forEach ( ( iframe ) => {
1804+ const src = iframe . getAttribute ( "src" ) ;
1805+ if ( src ) {
1806+ iframe . dataset . src = src ;
1807+ iframe . removeAttribute ( "src" ) ;
1808+ }
1809+ iframe . setAttribute ( "loading" , "lazy" ) ;
1810+ } ) ;
1811+
1812+ const iframeObserver = new IntersectionObserver ( ( entries , obs ) => {
1813+ entries . forEach ( ( entry ) => {
1814+ if ( ! entry . isIntersecting ) return ;
1815+ const iframe = entry . target ;
1816+ const src = iframe . dataset . src ;
1817+ if ( src && ! iframe . getAttribute ( "src" ) ) {
1818+ iframe . setAttribute ( "src" , src ) ;
1819+ }
1820+ obs . unobserve ( iframe ) ;
1821+ } ) ;
1822+ } , {
1823+ root : null ,
1824+ threshold : 0.01 ,
1825+ rootMargin : "600px 0px" ,
1826+ } ) ;
1827+
1828+ iframes . forEach ( ( iframe ) => iframeObserver . observe ( iframe ) ) ;
1829+ }
1830+
17591831 // Video demo switching
17601832 function showDemo ( demoId , event ) {
17611833 // Hide all video sections
@@ -1779,10 +1851,11 @@ <h3 class="subsection-title" data-i18n="svg_demos_title">SVG Demos: Vector Graph
17791851 event . target . classList . add ( 'active' ) ;
17801852 }
17811853
1782- // Pause all videos
1854+ // Pause all videos and keep source only for active demo
17831855 document . querySelectorAll ( 'video' ) . forEach ( video => {
17841856 video . pause ( ) ;
17851857 } ) ;
1858+ updateCliDemoVideoSources ( demoId ) ;
17861859 }
17871860
17881861 // Smooth scroll for anchor links
@@ -1809,12 +1882,15 @@ <h3 class="subsection-title" data-i18n="svg_demos_title">SVG Demos: Vector Graph
18091882 entries . forEach ( entry => {
18101883 if ( entry . isIntersecting && ! entry . target . classList . contains ( 'animated' ) ) {
18111884 entry . target . classList . add ( 'animated' ) ;
1885+ observer . unobserve ( entry . target ) ;
18121886 }
18131887 } ) ;
18141888 } , observerOptions ) ;
18151889
18161890 // Observe all fade-in elements after page load
18171891 window . addEventListener ( 'load' , ( ) => {
1892+ initCliDemoVideoOptimization ( ) ;
1893+ initDemoIframeLazyLoad ( ) ;
18181894 document . querySelectorAll ( '.fade-in' ) . forEach ( el => {
18191895 observer . observe ( el ) ;
18201896 } ) ;
0 commit comments