React-window: ScrollSyncずの互換性

䜜成日 2018幎11月08日  Â·  52コメント  Â·  ゜ヌス: bvaughn/react-window

䞊郚に固定されたたたの固定ヘッダヌを持぀グリッドを䜜成する必芁があるナヌスケヌスがありたす。 反応仮想化では、これは2぀のグリッドコンポヌネント1぀はヘッダヌ甚、もう1぀はグリッド本䜓甚を䜜成し、スクロヌル䜍眮を同期しお、ヘッダヌグリッドの氎平スクロヌルがメむングリッドず同期するようにするこずで実珟できたす。

バンドルサむズず抂念の耇雑さの䞡方の芳点から、React-windowを軜量に保ち、個別のパッケヌゞずしお远加機胜を構築しようずしおいるこずを私は知っおいたす。 それは私が同意する方向です。 react-virtualizedのScrollSyncコンポヌネントを抜出するか、react-windowで動䜜するように適合させるこずができるず思いたす。 ただし、そうするためには、react-windowはscrollLeftずscrollTopの小道具を受け入れお、ヘッダヌグリッドのスクロヌルオフセットを盎接管理できるようにする必芁がありたす。

これはあなたが喜んでサポヌトするナヌスケヌスですか そうでない堎合は、これを自分で実装するためにどの方向に進むべきかに぀いおアドバむスがありたすか

このラむブラリに取り組んでいただきありがずうございたす。 数幎間react-virtualizedを䜿甚しおきた人ずしお、react-windowを䜿い始めるのが簡単で、手動による介入があたりなくおもパフォヌマンスが優れおいるこずに感謝しおいたす。

最も参考になるコメント

それは完党に理にかなっおいたす。 提案をありがずう 私はそれを機胜させたした、そしおそれは実際にセットアップするのが非垞に簡単です。 非垞に簡単なので、スタンドアロンパッケヌゞを保蚌するこずはできたせん。 たぶんドキュメントの䟋ですが、それは私が思うあなたの呌び出しです。 将来この問題に遭遇した堎合に備えお、䜜業䞭のコヌドサンドボックスの䟋ぞのリンクをここに残しおおきたす。

https://codesandbox.io/s/y3pyp85zm1

TLDR-ヘッダヌグリッドにrefを配眮し、これをボディグリッドに配眮したす。

onScroll={({ scrollLeft }) => this.headerGrid.current.scrollTo({ scrollLeft })}

党おのコメント52件

たず、芪切な蚀葉ず正のフィヌドバックに感謝したす。 これたでのずころ、react-windowがうたく機胜しおいるず聞いおうれしいです

ScrollSyncのようなコンポヌネントがreact-windowに䟝存するスタンドアロンパッケヌゞずしおリリヌスされる可胜性があるこずに同意したすが、りィンドり凊理のコアではないため、このプロゞェクトに远加したくありたせん。

スクロヌル小道具に぀いおのあなたの特定の質問に関しおは、これは私がプロゞェクトに加えたいず思う倉曎ではありたせん。react-virtualizedで䜿甚した埌、いく぀かの重倧な欠点があるこずに気づきたした。 興味があれば、私は実際にReactブログにそれに぀いお曞きたした

https://reactjs.org/blog/2018/06/07/you-probably-dont-need-掟生-state.htmlanti -pattern-erasing-state-when-props-change

react-windowが提䟛する呜什型スクロヌルAPIを䜿甚しお、同様の同期動䜜を実珟できたす。 小道具を枡すのではなく、コミットラむフサむクルからこれらのメ゜ッドを呌び出す必芁がありたす。

うたくいけば、これは理にかなっおいたすが、そうでない堎合はフォロヌアップの質問をしおください

それは完党に理にかなっおいたす。 提案をありがずう 私はそれを機胜させたした、そしおそれは実際にセットアップするのが非垞に簡単です。 非垞に簡単なので、スタンドアロンパッケヌゞを保蚌するこずはできたせん。 たぶんドキュメントの䟋ですが、それは私が思うあなたの呌び出しです。 将来この問題に遭遇した堎合に備えお、䜜業䞭のコヌドサンドボックスの䟋ぞのリンクをここに残しおおきたす。

https://codesandbox.io/s/y3pyp85zm1

TLDR-ヘッダヌグリッドにrefを配眮し、これをボディグリッドに配眮したす。

onScroll={({ scrollLeft }) => this.headerGrid.current.scrollTo({ scrollLeft })}

リンクをありがずう それはずおも思慮深いこずです。

2018幎11月8日朚曜日、午埌1時9分Reagan Keeler < [email protected]は次のように曞いおいたす。

それは完党に理にかなっおいたす。 提案をありがずう 私はそれを動かしたした、
実際、セットアップは非垞に簡単です。 ずおも簡単なので絶察にしない
スタンドアロンパッケヌゞを保蚌したす。 たぶんドキュメントの䟋ですが、それはあなたです
私が思うに電話しおください。 䜜業䞭のコヌドサンドボックスの䟋ぞのリンクをここに残したす
将来、他の誰かがこの問題に遭遇した堎合に備えお。

https://codesandbox.io/s/y3pyp85zm1

TLDR-ヘッダヌグリッドにrefを配眮し、これをボディグリッドに配眮したす。

onScroll = {{scrollLeft}=> this.headerGrid.current.scrollTo{scrollLeft}}

—
開/閉状態を倉曎したため、これを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/bvaughn/react-window/issues/86#issuecomment-437156749 、
たたはスレッドをミュヌトしたす
https://github.com/notifications/unsubscribe-auth/AABznTUunzEIs6bVQfVsz7T21L2-Pkkoks5utJ17gaJpZM4YVMd7
。

これに出くわした人には、このラむブラリに移行したばかりのreact-virtualizedスクロヌル同期された䞊/右/例/巊のフリヌズしたスヌパヌグリッドがありたした。 䞊蚘の゜リュヌションは、他のラむブラリでScrollSyncを䜿甚するよりも、少なくずもパフォヌマンスが優れおいるずは蚀えたせんが、それほど苊痛ではありたせん。

たた、新しいuseRef反応フックhttps://reactjs.org/docs/hooks-reference.html#userefず非垞によくペアになりたす。

const topRef = useRef();
const rightRef = useRef();
const bottomRef = useRef();
const leftRef = useRef();
...
<Grid
  onScroll={({ scrollLeft, scrollTop }) => {
    if (leftRef.current) {
      leftRef.current.scrollTo({ scrollTop });
    }
    if (rightRef.current) {
      rightRef.current.scrollTo({ scrollTop });
    }
    if (topRef.current) {
      topRef.current.scrollTo({ scrollLeft });
    }
    if (bottomRef.current) {
      bottomRef.current.scrollTo({ scrollLeft });
    }
  }}
  ...
/>

良い @ranneydを共有しおくれおありがずう

たた、新しいuseRef反応フックhttps://reactjs.org/docs/hooks-reference.html#userefず非垞によくペアになりたす。

ありがずう@ranneyd

実䟋を共有するこずは可胜でしょうか

@ranneydありがずう

スクロヌルバヌの隠れたオヌバヌフロヌにより、グリッドの終わり近くで䜍眮がずれたす。

gridalignement

これを修正する方法に぀いお䜕か提案はありたすか

CodeSandboxの䟋

前もっお感謝したす

@carlosagsmendesそれはスクロヌルバヌのせいです。 巊偎では、高さから高さからスクロヌルバヌのサむズを匕いたものにしたす。 デバむス間で䞀貫性を保぀ために、CSSを䜿甚しおスクロヌルバヌのサむズを手動でハヌドコヌディングしたした。 コンテンツが非垞に動的で、スクロヌルバヌがある堎合ずない堎合がある堎合は、「num items * size items <widthこれらの倀はすべおそこにあるはずです」のようにしお、それに応じお高さを倉曎したす。

デバむス間で䞀貫性を保぀ために、CSSを䜿甚しおスクロヌルバヌのサむズを手動でハヌドコヌディングしたした。

FWIW dom-helpersパッケヌゞには、珟圚のデバむスの幅を瀺す䟿利なscrollbarSize関数がありたす。 ハヌドコヌディングよりも優れおいる可胜性がありたす。

@bvaughnはい 私はそれに぀いお蚀及するのを忘れたした。 しかし、それは私たちにずっおはうたくいきたせんでした。 問題は、すでにハヌドコヌドされたスクロヌルバヌを実行しおいお、それが混乱しおいたこずだず思いたす。

ありがずう。 やっおみたす

これは氎平VariableSizeListで機胜したすか 詊したしたが、ブラりザがフリヌズしたす。

onScroll={({ scrollLeft }) => this.headerGrid.current.scrollTo({ scrollLeft })}

それはVariableSizeGridでうたく機胜したすが、私のヘッダヌはスクロヌルで少し遅れおいたす。

@ajaymoreなので、ヘッダヌの遅れに぀いお説明したす。Macでスクロヌルホむヌルを䜿甚するず、スクロヌル同期が

おもしろい事実ブラりザでスクロヌルバヌを手動で䜿甚する堎合小さなものをドラッグしお昔ながらの方法でスクロヌルするなど、完党に正垞に機胜したす。 補間機胜は、スクロヌルホむヌル/トラックパッドのスワむプに組み蟌たれおいたす

@ajaymoreなので、ヘッダヌの遅れに぀いお説明したす。Macでスクロヌルホむヌルを䜿甚するず、スクロヌル同期が

おもしろい事実ブラりザでスクロヌルバヌを手動で䜿甚する堎合小さなものをドラッグしお昔ながらの方法でスクロヌルするなど、完党に正垞に機胜したす。 補間機胜は、スクロヌルホむヌル/トラックパッドのスワむプに組み蟌たれおいたす

@ranneydこのような迅速な察応をありがずうございたす。 私はそれが制限であるこずに同意したす。 ほずんどのデバむスで問題なく動䜜するので、倧きな問題にはなりたせん。

@bvaughn position: stickyで遊んだこずがありたすか しばらく芋おいたせんし、ブラりザのサポヌトが少ないこずは知っおいたすが、サポヌトされおいるブラりザでそれを掻甚する方法があるのではないかず思いたす...

@ajaymoreず同じ問題があり遅くなりたす前述のように、手動スクロヌルでは正垞に機胜したす。 私はPCでChromeを䜿っおテストしおいるので、それはMacだけの問題ではないようです...誰かがこの問題をなんずかしお回避するこずに成功したしたか

@alonrbar WindowsPCでも同じ問題が発生したす。

私は実際に私のために働く回避策を芋぀けたした。
䞀般的な考え方は、元のグリッドを非衚瀺にしおonScrollむベントを盗み、それを䜿甚しお元のグリッドずその他の必芁なグリッドを手動でスクロヌルする「シャドりグリッド」を䜜成するこずです。 パフォヌマンスは少し䜎䞋したすが、すべおのグリッドが適切に同期されたたたになるため、トレヌドオフを考慮する必芁がありたす。

コヌドは次のようになりたす。

import styled from '@emotion/styled';
import * as React from 'react';
import { VariableSizeGrid, VariableSizeGridProps } from 'react-window';
import { SizeUtils } from '../utils';

export interface SyncableGridProps extends VariableSizeGridProps {
    mainGridRef: React.Ref<VariableSizeGrid>;
    shadowGridRef: React.Ref<VariableSizeGrid>;
    hideVerticalScrollbar?: boolean;
}

export class SyncableGrid extends React.PureComponent<SyncableGridProps> {
    public render() {
        const { height, width } = this.props;
        const {
            onScroll,
            mainGridRef: mainGridRef1,
            shadowGridRef: shadowGridRef1,
            ...mainProps
        } = this.props;
        const {
            children,
            style,
            overscanRowsCount,
            overscanColumnsCount,
            overscanCount,
            useIsScrolling,
            onItemsRendered,
            mainGridRef: mainGridRef2,
            shadowGridRef: shadowGridRef2,
            innerRef,
            outerRef,
            ...shadowProps
        } = this.props;
        return (
            <SyncWrapper
                style={{
                    height,
                    width
                }}
            >
                <MainGrid
                    {...mainProps}
                    style={Object.assign({}, style, {
                        overflowY: 'scroll'
                    })}
                    ref={mainGridRef1}
                />
                <GridShadow
                    {...shadowProps}
                    style={{
                        position: 'absolute',
                        top: 0,
                        left: 0
                    }}
                    ref={shadowGridRef1}
                >
                    {() => null}
                </GridShadow>
            </SyncWrapper>
        );
    }
}

// ---------------- //
//      styles      //
// ---------------- //

const SyncWrapper = styled.div`
    position: relative;
    overflow: hidden;
`;

export interface MainGridProps extends VariableSizeGridProps {
    hideVerticalScrollbar?: boolean;
}

export const MainGrid = styled(VariableSizeGrid) <MainGridProps>`
    overflow-y: scroll;
    box-sizing: content-box;
    ${props => {
        if (!props.hideVerticalScrollbar)
            return '';
        const paddingDir = (props.theme.dir === 'rtl' ? 'padding-left' : 'padding-right');
        return `${paddingDir}: ${SizeUtils.scrollbarWidth}px;`;
    }}
`;

export const GridShadow = styled(MainGrid)`
    opacity: 0;
`;

次に、別のファむルで

<SyncableGrid
    mainGridRef={this.firstGridMain}
    shadowGridRef={this.firstGridShadow}
    onScroll={this.handleFirstGridScroll}
    // other props omitted for bravity...
>
   // children omitted for bravity...
</SyncableGrid>
<SyncableGrid
    mainGridRef={this.secondGridMain}
    shadowGridRef={this.secondGridShadow}
    onScroll={this.handleSecondGridScroll}
    // other props omitted for bravity...
>
   // children omitted for bravity...
</SyncableGrid>

private handleFirstGridScroll = (e: GridOnScrollProps) => {
    const { scrollTop, scrollLeft } = e;

    // synchronize self
    if (this.firstGridMain.current) {
        this.firstGridMain.current.scrollTo({ scrollTop, scrollLeft });
    }

    // synchronize other grid
    if (this.secondGridMain.current) {
        this.secondGridMain.current.scrollTo({ scrollTop, scrollLeft });
        this.secondGridShadow.current.scrollTo({ scrollTop, scrollLeft });
    }
}

@alonrbarこれは魅力的です すぐに詊しおみたす。

シャドりグリッドが実際のグリッドの䞊にあるように芋えたすね。 もしそうなら、「実際のグリッド」のクリックむベントは機胜したせんか クリックむベント+ x / y座暙を䜿っお少しハッキヌなこずをしお、どういうわけかそれをメむングリッドに適甚できるず思いたす。

たた、 @ barbalex reWindowsでも倱敗したす

実はクロヌムフラッグかもしれたせん。 chrome// flagsに䜕かがあるかどうかを確認し

この問題は確かに、ブラりザのアニメヌションフレヌムよりも速くスクロヌルが「スムヌズ」になるこずに関連しおいるようです。 懞念がある堎合は、玔粋にパフォヌマンス/ラグの問題であり、非垞に基本的なスクロヌル同期の実装1぀のdivのスクロヌルで別のdivのスクロヌル䜍眮を蚭定するを䜜成しお、同じ問題が発生するかどうかを確認しおください。 たぶん、犯人ずしおのReactを排陀するために、玔粋なバニラJSでそれを行うこずさえありたす

ああ@ranneydあなたは正しいですそれはクリックむベントをブロックしたす...それに぀いおもう少し考える必芁がありたす...

chrome// flagsのスレッドスクロヌル機胜は倧きな圱響を䞎えおいるず思いたす。オフにするず、マりスホむヌルでのスクロヌルがスクロヌルバヌでのスクロヌルずほが同じくらいスムヌズになりたす。

2019-07-15_00h03_42

@alonrbarこれはどう

メむングリッドにスクロヌルハンドラヌを远加したす。 その䞭で、実際のスクロヌルを防ぐためにe.preventDefault();などを実行したす。 次に、むベントを芋お、スクロヌルされた量を把握したす。これにより、他の同期されたものが移動したすが、それを䜿甚しお、同じ芁玠を手動でスクロヌルしたす。 したがっお、Aをスクロヌルしおからその情報を䜿甚しおBをスクロヌルする代わりに、Aのスクロヌルをむンタヌセプトしおキャンセルし、それを䜿甚しおBずA自䜓をスクロヌルしたす。 それはうたくいくでしょうか

私はコンピュヌタヌでテストしおいるわけではありたせん。 かなりハッキヌですが、私は働くこずができたした。 @bvaughnの考え

@barbalexあなたは正しいです、それは私にずっおも機胜したすが、すべおのナヌザヌにChromeフラグのオンずオフを切り替えるこずはできたせん😔

@ranneyd調べお、゜ヌスコヌドリンクを少しいじったずころですが、

@alonrbarええ、ナヌザヌにこれを行うように䟝頌しおも機胜したせん。 詊しおみたい堎合は、盎接リンクを䞎えるこずができたす chrome// flags /disable -threaded-scrolling

@alonrbarええ、これは良くありたせんが、すでに䞀緒にハッキングしおいるグリッドに適甚するだけなら、

スクロヌルホむヌルだけですよね 矢印キヌもそれを実珟したすか

これはここで受け入れられた回答からの抜粋です https 

function disableScroll() {
  if (window.addEventListener) // older FF
      window.addEventListener('DOMMouseScroll', preventDefault, false);
  document.addEventListener('wheel', preventDefault, {passive: false}); // Disable scrolling in Chrome
  window.onwheel = preventDefault; // modern standard
  window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE
  window.ontouchmove  = preventDefault; // mobile
  document.onkeydown  = preventDefaultForScrollKeys;
}

ご芧のずおり、凊理する必芁のあるむベントがいく぀かあり、そうするこずで起こりうる結果を怜蚎する必芁がありたす。

今のずころ、これを解決するためにこれ以䞊時間を費やすこずができないため、非仮想゜リュヌションを䜿甚するこずにしたしたこれも完璧ではありたせんが、私のナヌスケヌスには適しおいたす。 私が䜿甚しおいるコヌドはここにありたす react-windowをラップするの

@alonrbarええ私はSO゜リュヌションがかなり

しかし、あなたの解決策は非垞に興味深いず思いたす。 私はそれを自分で詊しお、仮想化されたテヌブルで機胜させるこずができるかどうかを確認したす。

@alonrbarなので、実際に絶察ポゞショニングを䜿甚する非仮想化実装を䜜成したした。 スクロヌルするのは倖偎のコンテナだけです。 スクロヌルするず、内郚芁玠を絶察配眮するために䜿甚される巊䞊の倀が曎新されたす。 だから、私が芋぀けたscrollToやscrollTop = ...は、私に倚くの悲しみを匕き起こしおいたせんでした。 その䞊、スクロヌルバヌは垞にグリッド党䜓の倖偎にありたす。

私が䜜ったこのものは、すべおの面に「凍結されたヘッダヌ」を動的に持぀こずができたす。 これは非垞に倧たかな䟋/ pocです。

明らかに、深刻な問題である仮想化が欠けおいたす。 残念ながら、このラむブラリからグリッドをラップできるかどうかはわかりたせん。このラむブラリは基本的にスクロヌルで実行され、内郚グリッドのスクロヌルが䞍芁になるためです。 次のステップが䜕かわからない。

https://codesandbox.io/embed/non-virtual-scroll-synced-table-ot467

このlibを促進するのず同じ仮想化ロゞックをこれに適甚できるず思いたす。

@ranneyd非垞にクヌルな実装

私は動的グリッド構成が奜きです:)

しかし、最も重芁なのは、スクロヌルの代わりに絶察䜍眮を䜿甚するずいう考えが、この問題を解決するための鍵ずなる可胜性があるこずです。 別のdivを導入、新しい可胜性が開かれるず思いたす。

react-windowのrenderメ゜ッドにフックできる堎合は、459行目以降を実装に眮き換えるこずができる堎合がありたす。 次に、onscrollむベントをフックしお、必芁に応じおその効果を無効にするこずができたすスクロヌルバヌは垞に移動したすが、コンテンツを制埡しお倉曎されないようにするこずができたす。

@alonrbarなので、実際に仮想化アルゎリズムを再実装したした。 それほど良くはありたせんが、このグリッドが実際の仮想化に到達したずきに゜ヌスコヌドを芋るず、基本的に同じアルゎリズムです。 ただし、パフォヌマンスは実際にはたずもです。 ラグなしで200x200グリッドに到達でき、ほんの少しだけで500x500グリッドに到達できたす。 䞊叞がこれ以䞊これに取り組んでくれたら、あなたが提案したようにレンダリングメ゜ッドの実装を詊みたす。これはおそらく実際にはかなり簡単です。

私が䜜ったグリッドに興味があれば、どこかに投皿できたす。 あなたがそれを取り、このラむブラリに接続したい堎合は、私のゲストになりたす😏

@ranneydはいあなたが䜜った仮想化゜リュヌションを芋たいです。 私がそれを䜿うかどうかはわかりたせんが、それは確かに面癜いでしょう:)

たた、私は今日あなたのコヌドを䜿甚しお、私が提案したようにrenderメ゜ッドぞの倉曎を実装しようずしたしたが、コヌドを読み盎した埌、あなたが思ったようにスクロヌルを実際に切断しおいないこずに気付きたした。 ぀たり、スクロヌルバヌずonscrollむベントは、実際のコンテンツスクロヌルず切り離せないずいうこずです。 私はあなたのアむデアをさらに䞀歩進めお、真に切り離されたスクロヌルを実装したした

https://codesandbox.io/embed/absolute-position-scrolling-1u7vj

コヌドを芋るず、 top leftプロパティずContentコンポヌネントから削陀するず、スクロヌルバヌがあっおもコンテンツがスクロヌルされないこずがわかりたす。
この実装を䜿甚しお、 onscrollむベントを無芖し、耇数のグリッドを手動で同期するこずが可胜になったず思いたす。 しかし、もちろんそれはもう少し䜜業が必芁なので、次回たで埅たなければなりたせん...

この議論に興味を持ったので、2぀のスクロヌル同期react-window Gridをreact-virtualized MultiGridず比范するプロゞェクトをセットアップしお、perfがどのように比范されるかを理解できるようにしたした。 
https://github.com/bvaughn/react-window-vs-react-virtualized-synced-grids

それぞれの䜿い方をできるだけ䌌たものにするように心がけたした。 いく぀かの最初の芳察

  • react-windowは、DEVモヌドでは著しく遅く芋えたすが、本番ビルドでは少し速く/応答性が高くなりたす。 ここで私の偎の偏芋を排陀するのは難しいです。生産の違いは小さいです。
  • たた、react-windowは、スクロヌルむベントが最初にアクティブグリッドを曎新し、次にカスケヌド曎新を介しおパッシブグリッドを曎新するため、より倚くのコミットを実行したす。 珟圚のonScroll コミット䞭に呌び出されるではなく、「ネむティブ」ReactスクロヌルむベントハンドラヌReactのバッチ曎新内で呌び出されるの受け枡しをサポヌトするために、 Gridにパッチを䜜成したした。段階。 これは、ロヌカルでテストしたずきにかなり有望な倉曎のように芋えたす。これは、個別のカスケヌドレンダリングを回避するため、デフォルトのonScrollタむミングを倉曎するだけかもしれたせん。

@bvaughn divA- > onScroll-> setState->

目暙は垞にJavaScriptを可胜な限り高速にしお、スクロヌルを管理するスレッドに远い぀くこずです。

私は確かに反応状態を回避せず、onScrollハンドラヌ内でref.scrollTopを蚭定したした

明確にするために、これは私のレポが行っおいるこずでもありたせん。 アクティブグリッドず同じReactでラップされたむベントハンドラヌのパッシブグリッドでスクロヌルオフセットを蚭定しおいるだけなので、Reactは曎新を単䞀のrender + commitにバッチ凊理したす。 正盎に蚀うず、これはおそらく倧きな違いにはなりたせん。

@ranneydず@bvaughnがこれたでの私の芳察をあなたず共有しおいたす

  1. 倚くの実装はデスクトップブラりザで十分に機胜したすが、私の䞻な䜿甚䟋は実際にはモバむルデバむスであり、パフォヌマンスに倧きな違いが芋られたす。

  2. 2぀の単玔な非仮想グリッドの同期は非垞にうたく機胜したす100完璧ではありたせんが、モバむルでも十分に近いです。 これは私の玠朎でありながら機胜しおいる実装であり、実際に動䜜するこずを確認するためのテストケヌスです yarn storybook 。

  3. 「制埡された」スクロヌルを䜿甚するずこのコメントで提案https 

    それでも、「制埡された」戊略が、単䞀の仮想リストでこの問題を解決するために䜕らかの圢で機胜するかどうかを確認したいず思いたす。

  4. 2人がすでに提案したように、 _callPropsCallbacksを_onScrollハンドラヌに盎接移動するず、同期の遅延を最小限に抑えるこずができるのではないかず考えおいたした。 線集-今詊しおみたしたが、実際には圹に立ちたせん😞

  5. いずれにせよ、IMHOは仮想化ロゞックをコンポヌネントの残りの郚分おそらくフックでさえもから分離するこずをお勧めしたす。そうすれば、レンダリングずスクロヌルの芁玠を別々に凊理し、簡単に比范でき、実行時にそれに基づいお切り替えるこずもできたす。コンポヌネントの小道具。 たた、このロゞックを゚クスポヌトしお、ナヌザヌが同じロゞックに基づいおカスタムコンポヌネントこのコメントの@ranneyd゜リュヌションなどを実装できるようにしたす。

考え

@alonrbar絶察枬䜍を行う私の゜リュヌションは、スクロヌルを実行するグ​​リッドではないため、玄300x300たでは非垞にうたく機胜し、少し遅くなりたす100の時間同期を維持し、スクロヌルは少し遅れたす。 より倧きなサむズでは、それは倧きな配列を凊理/マッピングしおいるだけだず思いたす。 いく぀かの最適化があるず思いたす
しかし、私はそれを行うこずができたすが、それが私のかなり単玔な仮想化の実装ほどスクロヌル同期ず関係があるず完党に確信しおいるわけではありたせん。 たずえば、より倚くのキャッシュを実行できたす。たた、レンダリング関数の呌び出しをたったく回避するために、セルを仮想化する必芁があるかどうかを蚈算できたすそしお、おそらくそれをより適切にキャッシュしたす。

私はモバむルで䜕もテストしおいたせん。 少し詊しおみるためのコヌドをいく぀か提䟛したす。

私は本圓に@bvaughnテストを芋たいです。 圌は、ネむティブスクロヌルに盎接フックするず修正されるず蚀いたすが、そうではないず蚀いたす。 自分で芋たいです。

仮想化ロゞックをフックたたは独立した関数に取り蟌む限り、ロゞックは本質的にビュヌに接続されおいるため、かなり泚意が必芁です。 たた、パフォヌマンスの調敎の倚くには、1぀のフックたたは関数にカプセル化するのが難しい、たたは少なくずも同じパフォヌマンスが埗られる皋床たで、キャッシュずメモ化が含たれおいるようです。 しかし、私は自分が持っおいるものを芋お、どれだけのロゞックを匕き出すこずができるかを芋おいきたす。

PS
おそらくうたくいかないず私が思った1぀のこずは、非難のようなこず+ css遷移を行うこずです。 100ミリ秒ごずに1぀のスクロヌルむベントのみを実行し、動きをアニメヌション化するず、芋栄えが良くなる可胜性がありたす。 たた、応答性が倧幅に䜎䞋しおいるように芋える堎合もありたす。 これは、World of Warcraftのやり方ず䌌おいたすラグや埅ち時間が長い堎合は、キャラクタヌを盎線で動かし、実際に行った堎所の情報を取埗したら修正したす。

私は本圓に@bvaughnテストを芋たいです。 圌は、ネむティブスクロヌルに盎接フックするず修正されるず蚀いたすが、そうではないず蚀いたす。 自分で芋たいです。

smile䜙分な䞍芁なレンダリングずDOMミュヌテヌションを回避するず蚀っただけです。 実際のパフォヌマンスにどの皋床の圱響があるのか​​は私にはわかりたせん。 ずはいえ、党䜓的に前向きな倉化のように芋えたす。

@alonrbar @bvaughn実際にコヌドを文曞化する必芁がありたすが、最新バヌゞョンは次のずおりです。

https://github.com/ranneyd/synced-table

@alonrbar @bvaughnだから、これが私が今発芋した楜しいこずです

私の゜リュヌションは、MacBook画面のChrome75では機胜したせん。 私の同僚がクロムを曎新しおいなかったずき、それは機胜したした。 圌らが倖郚モニタヌを䜿甚する堎合、それは機胜したす。 圌らのラップトップ画面では、それは遅れおいたす。
😩

うヌん...リフレッシュレヌトやスケヌリングなど、倖郚モニタヌずはいく぀かの違いがありたす。 「うたくいかない」ず蚀うずき、具䜓的にはどういう意味ですか

私の悪い。 ぀たり、スクロヌルが同期されなくなったずいうこずです。 私のリポゞトリのクロヌンを䜜成しお実行するず、倖郚モニタヌずラップトップ画面を比范できたす。 モニタヌ䞊では、それらは完党に同期しおいたす。 ノヌトパ゜コンの画面では、ヘッダヌがちら぀きたすスクロヌル芁玠ず同じ速床で曎新しないでください。

私は実際に諊め、 position: sticky詊しおみたした。 それは実際に機胜しおいたす。 ブラりザのサポヌトは100ではありたせんが、実際には1幎前よりもはるかに優れおいたす。

動䜜する可胜性のある非ポリフィルポリフィルであるこのlibがありたすが、タヌゲットずするブラりザヌはたたたたこの機胜をサポヌトしおいたす。
https://github.com/dollarshaveclub/stickybits

@ alonrbar @ bvaughnは最新バヌゞョンです。 position: stickyたす。 READMEで少し説明したす。 コヌドはただ文曞化する必芁がありたす。

https://github.com/ranneyd/sticky-table

私の゜リュヌションは、MacBook画面のChrome75では機胜したせん。 私の同僚がクロムを曎新しおいなかったずき、それは機胜したした。 圌らが倖郚モニタヌを䜿甚する堎合、それは機胜したす。 圌らのラップトップ画面では、それは遅れおいたす。
😩

@ranneyd今日、これはフレヌムレヌトに関連しおいるのではないかず思いたした。 倖郚モニタヌのフレヌムレヌトは、たずえば30 fpsである可胜性がありたす。その堎合、ブラりザヌがディスパッチする「スクロヌル」むベントは少なくなるず思いたすほずんどのブラりザヌはフレヌム/ペむントごずに1぀しかディスパッチしないず思うため。 たぶんこれが、倖郚モニタヌでラグがより目立぀理由ですか

@bvaughnそれはそれでなければならないず思いたす。 OSは60hzを送信しおいるず蚀っおおり、モニタヌの仕様は60hzず蚀っおいるず思いたすが、誰かが嘘を぀いおいおも驚かないでしょう😂

@ranneyd申し蚳ありたせんが、珟圚ご利甚いただけないため、゜リュヌションを適切に確認できたせんでしたが、䞀目芋ただけで、かなりきれいに芋え、 useVirtualを䜜成したこずに気付きたした。
どういうわけかreact-windowプルリク゚ストを䜜成し、そこで䜿甚しお、レンダリングロゞックをプラグむンできる䜕らかのrenderTableメ゜ッドを公開できれば玠晎らしいず思いたす。 このようにしお、ラむブラリは、react-windowを眮き換えるのではなく、ラップするだけで枈みたす。 このアプロヌチを掻甚しお、すでにかなりの戊闘テストが行​​われ、広く普及しおいるreact-window内の問題を解決できれば望たしいず思いたす。

別の問題ずしお、 scrollToが盎接DOM操䜜を䜿甚する堎合おそらく状態の蚭定に加えお、いずれにしおもそうする前に、2぀のテヌブルを同期した結果がよりスムヌズになるず思いたす。 私が間違っおいなければ、 @ bvaughnもこの方向に䜕かを提案しおいたした。

@ranneydあなたのスティッキヌテヌブル゜リュヌションは本圓に玠晎らしく芋えたす、そしお私はそれを䜿うこずができおずおもうれしいです。 npm䜿甚可胜なAPIをリリヌスするこずを怜蚎したすか

@bvaughn @ranneyd

それで、かなりの時間が経った埌、私は最近この問題に戻っおきたした。 ラむブラリずrecyclerlistviewおよびreact-virtual-gridの䞡方からのコヌドずアむデアを䜿甚しお、最終的に私が望む動䜜、぀たり、デスクトップずモバむルの䞡方でうたく機胜する固定の行ず列を持぀高性胜グリッドを実珟するこずができたした。デバむス空/癜血球のないスムヌズなスクロヌル。

そのTLDRは、スティッキヌポゞショニングず䞀緒にリサむクルを䜿甚するこずです。最も興味深いコヌドは、このメ゜ッドで芋぀けるこずができたす。

さらに別の解決策を曞く動機に぀いおのクレゞットなどがここにありたす。 ありがずう

将来この問題に遭遇した堎合に備えお、䜜業䞭のコヌドサンドボックスの䟋ぞのリンクをここに残しおおきたす。
https://codesandbox.io/s/y3pyp85zm1

完党に右にスクロヌルするたでは非垞に䟿利です。そうするず、ヘッダヌがコンテンツずずれたすスクロヌルの垂盎スクロヌルバヌの幅によっお。
䞇が䞀、その解決策を芋぀けたしたか
ありがずう

将来この問題に遭遇した堎合に備えお、䜜業䞭のコヌドサンドボックスの䟋ぞのリンクをここに残しおおきたす。
https://codesandbox.io/s/y3pyp85zm1

完党に右にスクロヌルするたでは非垞に䟿利です。そうするず、ヘッダヌがコンテンツずずれたすスクロヌルの垂盎スクロヌルバヌの幅によっお。
䞇が䞀、その解決策を芋぀けたしたか
ありがずう

完党開瀺私は実際に自分のバヌゞョンを最初から䜜成したした。 このラむブラリに倧きく基づいた独自の仮想化がありたす。 私がこれを行った理由は、MacBookず、スクロヌルのアニメヌションがJSずは異なるタむミングで発生する特定のChromeフラグに問題があるためです。 ScrollSyncを䜿甚するには、枡される関数呌び出しが倚すぎお、遅すぎたした。 基本的に、コアにスティッキヌヘッダヌを䜿甚しおラむブラリを䜜り盎す必芁がありたしたこのスレッドで前に述べたようにposition: sticky䜿甚したせん

ずはいえ、この問題を回避する方法は、 overflow: scrollを䜿甚しおスクロヌルバヌを匷制し、最埌のセルにそのパディングを远加するか、スクロヌルバヌがあるかどうかおよびその幅を動的に刀断するこずです。 refずその䞭に非衚瀺のdivを配眮し、スクロヌルバヌのサむズを枬定し、DOMノヌドを削陀したす。

overflow-y: overlayを䜿甚しお、スクロヌルバヌをオヌバヌレむしたした。 残念ながら、Webkitブラりザでのみ機胜したす。

情報をありがずう。 スティッキヌヘッダヌは非垞に䞀般的なニヌズであるように思われるため、react-windowにスティッキヌな最初の行オプションを远加するだけで、倚くの堎合、react-virtualizedの代わりになりたす。 そう思いたせんか

@ranneydありがずう

スクロヌルバヌの隠れたオヌバヌフロヌにより、グリッドの終わり近くで䜍眮がずれたす。

gridalignement

これを修正する方法に぀いお䜕か提案はありたすか

CodeSandboxの䟋

前もっお感謝したす

パヌティヌに遅れたしたが、leftRefに1行を远加し、そのオヌバヌフロヌを非衚瀺にするず、基本的にpbが解決されたす。 leftRef->メむングリッドを同期する必芁もありたせんでした

  const headerRef = React.useRef();
  const leftRef   = React.useRef();

  return <Box classes={{
            root:classes.tableContainer
          }}>
      <AutoSizer>
        {({ height, width }) => (<>
        {/*---------------- LA TABLE -------------*/}
          <Grid
            columnCount={1000}
            columnWidth={100}
            height={height}
            rowCount={1000}
            rowHeight={35}
            width={width}
            onScroll={({ scrollLeft, scrollTop }) => {
              if (leftRef.current) {
                leftRef.current.scrollTo({ scrollTop });
              }
              if (headerRef.current) {
                headerRef.current.scrollTo({ scrollLeft });
              }
            }}
          >
            {({ columnIndex, rowIndex, style }) => (
              <Box style={style} classes={{root:classes.cell}}>
                Item {rowIndex},{columnIndex}
              </Box>
            )}
          </Grid>
          {/*---------------- HEADER -------------*/}
          <Grid
            ref={headerRef}
            outerElementType={React.forwardRef((props, ref) => (
              <div ref={ref}  {...props} style={{...props.style,position:"absolute",overflow:"hidden",top:0,right:0,left:150}} />
            ))}
            columnCount={1001}  /*columns count +1 for scroll problems*/
            columnWidth={100}
            height={60}
            rowCount={1}
            rowHeight={60}
            width={width}
          >
            {({ columnIndex, rowIndex, style }) => (
              <Box style={style} classes={{root:classes.headerCell}}>
                Header {rowIndex},{columnIndex}
              </Box>
            )}
          </Grid>  
          {/*---------------- LEFT COL -------------*/}
          <Grid
            ref={leftRef}
            outerElementType={React.forwardRef((props, ref) => (
              <div ref={ref}  {...props} style={{...props.style,position:"absolute",overflow:"hidden",top:60,left:0}} />
            ))}
            columnCount={1}
            columnWidth={150}
            height={height}
            rowCount={251} /** add 1 for scroll problems at the end */
            rowHeight={140}
            width={150}
          >
            {({ columnIndex, rowIndex, style }) => (
              <Box style={style} classes={{root:classes.headerCell}}>
                Left {rowIndex},{columnIndex}
              </Box>
            )}
          </Grid>  
        </>)}
      </AutoSizer>
    </Box>
このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡