PageLayout: preserve scroll offsets inside modules; optimize by only calling _analyzeModule once