Is it possible to “buffer” DOM changes that happen

2019-07-18 04:29发布

To make it clear what I'm asking, here is my example (fiddle).

I have a list of ~500 random names. I have an input at the top that has live-style searching. On every keyup, the value of the input is taken, and every item in the list is matched against it. Items that don't match are hidden.

Subjectively, the performance is okay, but not great. If you type quickly there is a noticeable pause before the list updates. I haven't profiled the code, but the bottleneck is almost certainly the changes to the DOM and the reflows it causes.

I wonder if it's possible to “queue up” these changes and only actually apply them at the end of the loop. So it would be one giant reflow and not lots of little ones.

In another version of the fiddle, I used a RegExp to get more fancy with the matching and presentation. Even though I'm using more DOM manipulation in this one (adding/removing tags to enable match highlighting) the performance feels about the same. I did also try adding visible/hidden classes in CSS and just setting the elements' className to that because that is supposed to be better performing (search for javascript reflows & repaints stubbornella—I can't post more than 2 links) but in my testing (Firefox 54) I found it was worse. So I don't know what's going on there.

What I guess I'm actually asking is: how do I make this code faster?

5条回答
地球回转人心会变
2楼-- · 2019-07-18 04:49

Why not use a debounce function from underscore to limit the number of calls to get new data? I generally use 3-400 ms delay for search input fields. This will reduce the number of times that the dom has changes and will also prevent the flashing of search results if the user is a slow typist.

Find details of debounce here

查看更多
\"骚年 ilove
3楼-- · 2019-07-18 04:56

Sometimes, thinking outside the box can be very rewarding...

CSS allows you to easily hide many elements with "display: none" and browsers are exceptionally well optimized when it comes to CSS.

So is there a way to apply this CSS rule to your searched term and let the browser do the job for you? (yes!)

var search = document.getElementById('s');
var list = document.getElementById('l');
var styling = document.getElementById('t');


var searchAction = function() {
    var term = search.value;

    if (term == '') styling.innerHTML = '';
    else styling.innerHTML = '#l>li:not([data-name *= "' + term + '"]) {display: none}';
}

var searchActivateEvent = function() {
    timeoutThing.restartSaveTimeout(searchAction);
}

search.addEventListener('keyup', searchActivateEvent, false);

var timeoutThing = {
    INPUT_TIMEOUT: 00, // ms
    saveTimeoutID: null,

    restartSaveTimeout: function(thingToDo) {
        this.cancelSaveTimeout();
        var that = this;
        this.saveTimeoutID = window.setTimeout(function() {
            thingToDo();
        }, this.INPUT_TIMEOUT);
    },

    cancelSaveTimeout: function() {
        clearTimeout(this.saveTimeoutID);
    }
}
li {
    transition: heigwht .25s ease-in-out, opacity .75s ease-in-out;
}

span {
    background: wheat;
    border-radius: 2px;
}

li.hidden {
    display: none;
}

li.visibru {
    display: list-item;
}
<input id="s">
<style id="t"></style>
<ul id="l">
    <li data-name='Vicente Yeates'>Vicente Yeates</li>
    <li data-name='Bryant Mcmiller'>Bryant Mcmiller</li>
    <li data-name='Analisa Shetterly'>Analisa Shetterly</li>
    <li data-name='Dorotha Graniero'>Dorotha Graniero</li>
    <li data-name='Monte Laranjo'>Monte Laranjo</li>
    <li data-name='Ross Olynger'>Ross Olynger</li>
    <li data-name='Antione Ruehl'>Antione Ruehl</li>
    <li data-name='Shayla Lamprecht'>Shayla Lamprecht</li>
    <li data-name='Latasha Sarkodie'>Latasha Sarkodie</li>
    <li data-name='Duncan Kellems'>Duncan Kellems</li>
    <li data-name='Ike Yanos'>Ike Yanos</li>
    <li data-name='Whitley Catanese'>Whitley Catanese</li>
    <li data-name='Lisa Janek'>Lisa Janek</li>
    <li data-name='Lucas Ahrends'>Lucas Ahrends</li>
    <li data-name='Kena Firmin'>Kena Firmin</li>
    <li data-name='Doug Rardin'>Doug Rardin</li>
    <li data-name='Pilar Awender'>Pilar Awender</li>
    <li data-name='Melda Barlup'>Melda Barlup</li>
    <li data-name='Teodoro Bartunek'>Teodoro Bartunek</li>
    <li data-name='Amira Fiene'>Amira Fiene</li>
    <li data-name='Kris Ormsby'>Kris Ormsby</li>
    <li data-name='Digna Engelbert'>Digna Engelbert</li>
    <li data-name='Chase Schingeck'>Chase Schingeck</li>
    <li data-name='Marc Capraro'>Marc Capraro</li>
    <li data-name='Angele World'>Angele World</li>
    <li data-name='Rex Alvirez'>Rex Alvirez</li>
    <li data-name='Margarett Weyer'>Margarett Weyer</li>
    <li data-name='Cedric Nevils'>Cedric Nevils</li>
    <li data-name='Charisse Guglielmo'>Charisse Guglielmo</li>
    <li data-name='September Shedd'>September Shedd</li>
    <li data-name='Charlie Buffaloe'>Charlie Buffaloe</li>
    <li data-name='Andreas Totten'>Andreas Totten</li>
    <li data-name='Selma Almen'>Selma Almen</li>
    <li data-name='Karleen Lamarsh'>Karleen Lamarsh</li>
    <li data-name='Carlton Ence'>Carlton Ence</li>
    <li data-name='Laverna Cassio'>Laverna Cassio</li>
    <li data-name='Veta Oblinski'>Veta Oblinski</li>
    <li data-name='Mariko Oliveros'>Mariko Oliveros</li>
    <li data-name='Lasandra Ellsworth'>Lasandra Ellsworth</li>
    <li data-name='Jose Phinisee'>Jose Phinisee</li>
    <li data-name='Jody Karlson'>Jody Karlson</li>
    <li data-name='Sharice Horst'>Sharice Horst</li>
    <li data-name='Joshua Collar'>Joshua Collar</li>
    <li data-name='Alexander Starnaud'>Alexander Starnaud</li>
    <li data-name='Arthur Bachorski'>Arthur Bachorski</li>
    <li data-name='Ignacio Laubach'>Ignacio Laubach</li>
    <li data-name='Lucrecia Hildago'>Lucrecia Hildago</li>
    <li data-name='Natashia Barton'>Natashia Barton</li>
    <li data-name='Aimee Zumot'>Aimee Zumot</li>
    <li data-name='Ashley Topping'>Ashley Topping</li>
    <li data-name='Ceola Rosebrough'>Ceola Rosebrough</li>
    <li data-name='Steve Wellinghoff'>Steve Wellinghoff</li>
    <li data-name='Brant Bintz'>Brant Bintz</li>
    <li data-name='Enrique Spratley'>Enrique Spratley</li>
    <li data-name='Issac Braylock'>Issac Braylock</li>
    <li data-name='Odis Slingluff'>Odis Slingluff</li>
    <li data-name='Kara Louth'>Kara Louth</li>
    <li data-name='Columbus Delmuro'>Columbus Delmuro</li>
    <li data-name='Jenniffer Moree'>Jenniffer Moree</li>
    <li data-name='Mei Perfecto'>Mei Perfecto</li>
    <li data-name='Terri Buren'>Terri Buren</li>
    <li data-name='Andrea Figurelli'>Andrea Figurelli</li>
    <li data-name='Thersa Everhardt'>Thersa Everhardt</li>
    <li data-name='Raisa Rabuck'>Raisa Rabuck</li>
    <li data-name='Demarcus Bodman'>Demarcus Bodman</li>
    <li data-name='Javier Lovenduski'>Javier Lovenduski</li>
    <li data-name='Jackie Jeck'>Jackie Jeck</li>
    <li data-name='Cyrus Olivid'>Cyrus Olivid</li>
    <li data-name='Timmy Lozoya'>Timmy Lozoya</li>
    <li data-name='Eldridge Elton'>Eldridge Elton</li>
    <li data-name='Noble Abelson'>Noble Abelson</li>
    <li data-name='Marlys Cannell'>Marlys Cannell</li>
    <li data-name='Sylvie Laughery'>Sylvie Laughery</li>
    <li data-name='Bobbie Grahl'>Bobbie Grahl</li>
    <li data-name='Katharine Gillispie'>Katharine Gillispie</li>
    <li data-name='Kena Papik'>Kena Papik</li>
    <li data-name='Gordon Boda'>Gordon Boda</li>
    <li data-name='Dominick Moreida'>Dominick Moreida</li>
    <li data-name='Josue Schellman'>Josue Schellman</li>
    <li data-name='Wallace Bacho'>Wallace Bacho</li>
    <li data-name='Jeffry Griffins'>Jeffry Griffins</li>
    <li data-name='Stacia Corrett'>Stacia Corrett</li>
    <li data-name='Theron Orey'>Theron Orey</li>
    <li data-name='Pete Haering'>Pete Haering</li>
    <li data-name='Stewart Gommer'>Stewart Gommer</li>
    <li data-name='Delbert Thompsom'>Delbert Thompsom</li>
    <li data-name='Johna Dell'>Johna Dell</li>
    <li data-name='Rashad Beckham'>Rashad Beckham</li>
    <li data-name='Colby Callison'>Colby Callison</li>
    <li data-name='Keenan Hegan'>Keenan Hegan</li>
    <li data-name='Nia Rollans'>Nia Rollans</li>
    <li data-name='Marie Kahawai'>Marie Kahawai</li>
    <li data-name='Luz Keib'>Luz Keib</li>
    <li data-name='Yukiko Bohler'>Yukiko Bohler</li>
    <li data-name='Clotilde Golightley'>Clotilde Golightley</li>
    <li data-name='Franklyn Feichter'>Franklyn Feichter</li>
    <li data-name='Irving Kendi'>Irving Kendi</li>
    <li data-name='Willow Debettignies'>Willow Debettignies</li>
    <li data-name='Arnoldo Terzian'>Arnoldo Terzian</li>
    <li data-name='Billie Mancini'>Billie Mancini</li>
    <li data-name='John Vanleer'>John Vanleer</li>
    <li data-name='Jennell Bielke'>Jennell Bielke</li>
    <li data-name='Myong Curie'>Myong Curie</li>
    <li data-name='Tanesha Kirouac'>Tanesha Kirouac</li>
    <li data-name='Jim Conely'>Jim Conely</li>
    <li data-name='Samella Sonnek'>Samella Sonnek</li>
    <li data-name='Emily Golaszewski'>Emily Golaszewski</li>
    <li data-name='Homer Warsing'>Homer Warsing</li>
    <li data-name='Maryalice Scotten'>Maryalice Scotten</li>
    <li data-name='Kacie Seliba'>Kacie Seliba</li>
    <li data-name='Carolee Bordelon'>Carolee Bordelon</li>
    <li data-name='Kurt Moss'>Kurt Moss</li>
    <li data-name='Vanessa Mcquigg'>Vanessa Mcquigg</li>
    <li data-name='Joey Hatridge'>Joey Hatridge</li>
    <li data-name='Brande Pamphile'>Brande Pamphile</li>
    <li data-name='Jacelyn Floris'>Jacelyn Floris</li>
    <li data-name='Christen Brownrigg'>Christen Brownrigg</li>
    <li data-name='Signe Calvani'>Signe Calvani</li>
    <li data-name='Lenard Dela'>Lenard Dela</li>
    <li data-name='Jacob Aina'>Jacob Aina</li>
    <li data-name='Jovan Dozier'>Jovan Dozier</li>
    <li data-name='Alden Einhorn'>Alden Einhorn</li>
    <li data-name='Milagro Moua'>Milagro Moua</li>
    <li data-name='Zoe Blatti'>Zoe Blatti</li>
    <li data-name='Jon Reck'>Jon Reck</li>
    <li data-name='Dennis Katie'>Dennis Katie</li>
    <li data-name='Jenny Dewall'>Jenny Dewall</li>
    <li data-name='Lon Zable'>Lon Zable</li>
    <li data-name='Winfred Rentfro'>Winfred Rentfro</li>
    <li data-name='Lavette Feng'>Lavette Feng</li>
    <li data-name='Stacey Beloff'>Stacey Beloff</li>
    <li data-name='Earnest Hansrote'>Earnest Hansrote</li>
    <li data-name='Faustino Dewaters'>Faustino Dewaters</li>
    <li data-name='Jed Wears'>Jed Wears</li>
    <li data-name='Cassidy Coho'>Cassidy Coho</li>
    <li data-name='Frank Sparkes'>Frank Sparkes</li>
    <li data-name='Ike Hechinger'>Ike Hechinger</li>
    <li data-name='Carissa Labre'>Carissa Labre</li>
    <li data-name='Brain Vanderhoef'>Brain Vanderhoef</li>
    <li data-name='Bula Layel'>Bula Layel</li>
    <li data-name='Joesph Dolman'>Joesph Dolman</li>
    <li data-name='Roseanne Marcucci'>Roseanne Marcucci</li>
    <li data-name='Larissa Carmer'>Larissa Carmer</li>
    <li data-name='Ricki Fronek'>Ricki Fronek</li>
    <li data-name='Al Massing'>Al Massing</li>
    <li data-name='Stephen Baranow'>Stephen Baranow</li>
    <li data-name='Phillip Espinola'>Phillip Espinola</li>
    <li data-name='Emanuel Widmer'>Emanuel Widmer</li>
    <li data-name='Dylan Isassi'>Dylan Isassi</li>
    <li data-name='Daria Mound'>Daria Mound</li>
    <li data-name='Buffy Vokes'>Buffy Vokes</li>
    <li data-name='Hal Kimbril'>Hal Kimbril</li>
    <li data-name='Kiera Merson'>Kiera Merson</li>
    <li data-name='Trent Kravs'>Trent Kravs</li>
    <li data-name='Genaro Browm'>Genaro Browm</li>
    <li data-name='Kimber Reinert'>Kimber Reinert</li>
    <li data-name='Jeremiah Kaduk'>Jeremiah Kaduk</li>
    <li data-name='Nichelle Harney'>Nichelle Harney</li>
    <li data-name='Hyun Divalerio'>Hyun Divalerio</li>
    <li data-name='Ira Burlson'>Ira Burlson</li>
    <li data-name='Kathie Longhenry'>Kathie Longhenry</li>
    <li data-name='Shane Tierney'>Shane Tierney</li>
    <li data-name='Beata Delaplane'>Beata Delaplane</li>
    <li data-name='Ollie Staiger'>Ollie Staiger</li>
    <li data-name='Zane Dittmar'>Zane Dittmar</li>
    <li data-name='Shayne Toft'>Shayne Toft</li>
    <li data-name='Tillie Haeckel'>Tillie Haeckel</li>
    <li data-name='Federico Gilleland'>Federico Gilleland</li>
    <li data-name='Howard Skowronek'>Howard Skowronek</li>
    <li data-name='Franchesca Langley'>Franchesca Langley</li>
    <li data-name='Stacy Elsa'>Stacy Elsa</li>
    <li data-name='Elfreda Mckendrick'>Elfreda Mckendrick</li>
    <li data-name='Madeline Reglin'>Madeline Reglin</li>
    <li data-name='Keesha Mcgoogan'>Keesha Mcgoogan</li>
    <li data-name='Debi Malcom'>Debi Malcom</li>
    <li data-name='Carmine Finnigan'>Carmine Finnigan</li>
    <li data-name='Dannie Fry'>Dannie Fry</li>
    <li data-name='Eulah Skoog'>Eulah Skoog</li>
    <li data-name='Weston Hanzely'>Weston Hanzely</li>
    <li data-name='Jolynn Olpin'>Jolynn Olpin</li>
    <li data-name='Raymundo Gossling'>Raymundo Gossling</li>
    <li data-name='Eve Diflorio'>Eve Diflorio</li>
    <li data-name='Mariano Leal'>Mariano Leal</li>
    <li data-name='Beckie Hoh'>Beckie Hoh</li>
    <li data-name='Danielle Lazenson'>Danielle Lazenson</li>
    <li data-name='Ahmed Bhatti'>Ahmed Bhatti</li>
    <li data-name='Inga Bilek'>Inga Bilek</li>
    <li data-name='Huey Cockrel'>Huey Cockrel</li>
    <li data-name='Tam Mcenery'>Tam Mcenery</li>
    <li data-name='Gary Proietto'>Gary Proietto</li>
    <li data-name='Karol Bussler'>Karol Bussler</li>
    <li data-name='Mckinley Windisch'>Mckinley Windisch</li>
    <li data-name='Celina Schroy'>Celina Schroy</li>
    <li data-name='Dong Suitt'>Dong Suitt</li>
    <li data-name='Jerrell Dermer'>Jerrell Dermer</li>
    <li data-name='Domingo Opsahl'>Domingo Opsahl</li>
    <li data-name='Nigel Nesslein'>Nigel Nesslein</li>
    <li data-name='Toshia Nalty'>Toshia Nalty</li>
    <li data-name='Jonas Intriago'>Jonas Intriago</li>
    <li data-name='Cecila Crivaro'>Cecila Crivaro</li>
    <li data-name='Bea Schulke'>Bea Schulke</li>
    <li data-name='Collene Myatt'>Collene Myatt</li>
    <li data-name='Kena Nepa'>Kena Nepa</li>
    <li data-name='Dalia Burklow'>Dalia Burklow</li>
    <li data-name='Harlan Rotherham'>Harlan Rotherham</li>
    <li data-name='Connie Grosso'>Connie Grosso</li>
    <li data-name='Shelton Brass'>Shelton Brass</li>
    <li data-name='Yvette Hinch'>Yvette Hinch</li>
    <li data-name='Elroy Barriger'>Elroy Barriger</li>
    <li data-name='Earnest Henrickson'>Earnest Henrickson</li>
    <li data-name='Neal Singhisen'>Neal Singhisen</li>
    <li data-name='Kristofer Lunceford'>Kristofer Lunceford</li>
    <li data-name='Dewey Bureau'>Dewey Bureau</li>
    <li data-name='Lennie Cancro'>Lennie Cancro</li>
    <li data-name='Kay Cherubini'>Kay Cherubini</li>
    <li data-name='Moises Brugliera'>Moises Brugliera</li>
    <li data-name='Edgardo Schoenle'>Edgardo Schoenle</li>
    <li data-name='Lance Badena'>Lance Badena</li>
    <li data-name='Floyd Kneedler'>Floyd Kneedler</li>
    <li data-name='Adriana Gschwind'>Adriana Gschwind</li>
    <li data-name='Jon Wzorek'>Jon Wzorek</li>
    <li data-name='Trent Smyer'>Trent Smyer</li>
    <li data-name='Nicholle Sovel'>Nicholle Sovel</li>
    <li data-name='Hilda Maruschak'>Hilda Maruschak</li>
    <li data-name='Jonell Schwartzberg'>Jonell Schwartzberg</li>
    <li data-name='Maricela Sponsler'>Maricela Sponsler</li>
    <li data-name='Janise Kleinert'>Janise Kleinert</li>
    <li data-name='Domingo Atzhorn'>Domingo Atzhorn</li>
    <li data-name='Fabian Talsky'>Fabian Talsky</li>
    <li data-name='Mauro Mursko'>Mauro Mursko</li>
    <li data-name='Arica Salemo'>Arica Salemo</li>
    <li data-name='Simone Reinders'>Simone Reinders</li>
    <li data-name='Desmond Scheperle'>Desmond Scheperle</li>
    <li data-name='Lenora Rouhoff'>Lenora Rouhoff</li>
    <li data-name='Georgette Yagues'>Georgette Yagues</li>
    <li data-name='Mervin Kurkeyerian'>Mervin Kurkeyerian</li>
    <li data-name='Mckinley Legate'>Mckinley Legate</li>
    <li data-name='Argelia Douse'>Argelia Douse</li>
    <li data-name='George Baldrey'>George Baldrey</li>
    <li data-name='Brynn Hobkirk'>Brynn Hobkirk</li>
    <li data-name='Cyrus Milbrodt'>Cyrus Milbrodt</li>
    <li data-name='Terrance Kriete'>Terrance Kriete</li>
    <li data-name='Janiece Ajello'>Janiece Ajello</li>
    <li data-name='Roger Filippides'>Roger Filippides</li>
    <li data-name='Zonia Mcmillion'>Zonia Mcmillion</li>
    <li data-name='Sheba Kenzie'>Sheba Kenzie</li>
    <li data-name='Bea Hauth'>Bea Hauth</li>
    <li data-name='Jude Swets'>Jude Swets</li>
    <li data-name='Queen Simar'>Queen Simar</li>
    <li data-name='Armand Ruter'>Armand Ruter</li>
    <li data-name='Mariana Blogg'>Mariana Blogg</li>
    <li data-name='Lyle Peretti'>Lyle Peretti</li>
    <li data-name='Wilhemina Basila'>Wilhemina Basila</li>
    <li data-name='Kendrick Fennessy'>Kendrick Fennessy</li>
    <li data-name='Lee Dorkin'>Lee Dorkin</li>
    <li data-name='Monte Camba'>Monte Camba</li>
    <li data-name='Lashell Stenz'>Lashell Stenz</li>
    <li data-name='Waltraud Corte'>Waltraud Corte</li>
    <li data-name='Krystle Giancola'>Krystle Giancola</li>
    <li data-name='Raphael Bordwell'>Raphael Bordwell</li>
    <li data-name='Johnny Urtiaga'>Johnny Urtiaga</li>
    <li data-name='Johnie Africa'>Johnie Africa</li>
    <li data-name='Blaine Scibilia'>Blaine Scibilia</li>
    <li data-name='Ruben Pama'>Ruben Pama</li>
    <li data-name='Annamarie Hupp'>Annamarie Hupp</li>
    <li data-name='Dennis Heitland'>Dennis Heitland</li>
    <li data-name='Cindy Peete'>Cindy Peete</li>
    <li data-name='Jefferson Prekker'>Jefferson Prekker</li>
    <li data-name='Maddie Grossnickle'>Maddie Grossnickle</li>
    <li data-name='Ambrose Farahkhan'>Ambrose Farahkhan</li>
    <li data-name='Launa Horrigan'>Launa Horrigan</li>
    <li data-name='Cecil Obremski'>Cecil Obremski</li>
    <li data-name='Delta Mccoy'>Delta Mccoy</li>
    <li data-name='Shantell Bahar'>Shantell Bahar</li>
    <li data-name='Tandra Pigler'>Tandra Pigler</li>
    <li data-name='Lavern Banghart'>Lavern Banghart</li>
    <li data-name='Maple Gramling'>Maple Gramling</li>
    <li data-name='Wilma Seuss'>Wilma Seuss</li>
    <li data-name='Sarita Fesperman'>Sarita Fesperman</li>
    <li data-name='Aurelio Harkrader'>Aurelio Harkrader</li>
    <li data-name='Art Lavezzo'>Art Lavezzo</li>
    <li data-name='Lura Shaff'>Lura Shaff</li>
    <li data-name='Jayme Baumer'>Jayme Baumer</li>
    <li data-name='Adeline Dagraca'>Adeline Dagraca</li>
    <li data-name='Nakia Benell'>Nakia Benell</li>
    <li data-name='Clare Janski'>Clare Janski</li>
    <li data-name='Tanja Boehmer'>Tanja Boehmer</li>
    <li data-name='Eleanora Schwede'>Eleanora Schwede</li>
    <li data-name='Dillon Dorrance'>Dillon Dorrance</li>
    <li data-name='Alisa Kopchick'>Alisa Kopchick</li>
    <li data-name='Leisha Harig'>Leisha Harig</li>
    <li data-name='Dominic Gehrki'>Dominic Gehrki</li>
    <li data-name='Moira Kiritsy'>Moira Kiritsy</li>
    <li data-name='Brendan Avina'>Brendan Avina</li>
    <li data-name='Deena Bejarano'>Deena Bejarano</li>
    <li data-name='Hunter Spallina'>Hunter Spallina</li>
    <li data-name='Jefferey Capes'>Jefferey Capes</li>
    <li data-name='Juanita Creggett'>Juanita Creggett</li>
    <li data-name='Jeffery Bielke'>Jeffery Bielke</li>
    <li data-name='Rayford Klinich'>Rayford Klinich</li>
    <li data-name='Ardell Vanderwege'>Ardell Vanderwege</li>
    <li data-name='Jimmie Aland'>Jimmie Aland</li>
    <li data-name='Junko Develbiss'>Junko Develbiss</li>
    <li data-name='Nakesha Miners'>Nakesha Miners</li>
    <li data-name='Alberto Muhlenkamp'>Alberto Muhlenkamp</li>
    <li data-name='Alexis Vassil'>Alexis Vassil</li>
    <li data-name='Normand Douthett'>Normand Douthett</li>
    <li data-name='Delmar Gumz'>Delmar Gumz</li>
    <li data-name='Emery Didyk'>Emery Didyk</li>
    <li data-name='Marybelle Lagerberg'>Marybelle Lagerberg</li>
    <li data-name='Eliseo Giblin'>Eliseo Giblin</li>
    <li data-name='Ernestina Standre'>Ernestina Standre</li>
    <li data-name='Burt Blanche'>Burt Blanche</li>
    <li data-name='Dorsey Conyers'>Dorsey Conyers</li>
    <li data-name='Edie Spires'>Edie Spires</li>
    <li data-name='Agustin Wendeln'>Agustin Wendeln</li>
    <li data-name='Austin Sasao'>Austin Sasao</li>
    <li data-name='Deidre Otega'>Deidre Otega</li>
    <li data-name='Tatiana Gata'>Tatiana Gata</li>
    <li data-name='Dovie Zimmel'>Dovie Zimmel</li>
    <li data-name='Freda Grzywinski'>Freda Grzywinski</li>
    <li data-name='Solomon Mussell'>Solomon Mussell</li>
    <li data-name='Jarod Canada'>Jarod Canada</li>
    <li data-name='Bernard Missler'>Bernard Missler</li>
    <li data-name='Alonzo Croom'>Alonzo Croom</li>
    <li data-name='Elvin Arflack'>Elvin Arflack</li>
    <li data-name='Suzann Pallazzo'>Suzann Pallazzo</li>
    <li data-name='Shira Elsbury'>Shira Elsbury</li>
    <li data-name='Randell Sterlin'>Randell Sterlin</li>
    <li data-name='Darrick Revolorio'>Darrick Revolorio</li>
    <li data-name='Dorian Mayeux'>Dorian Mayeux</li>
    <li data-name='Cortney Teuteberg'>Cortney Teuteberg</li>
    <li data-name='Eldon Schepis'>Eldon Schepis</li>
    <li data-name='Coleman Chapnick'>Coleman Chapnick</li>
    <li data-name='Bradford Andersson'>Bradford Andersson</li>
    <li data-name='Rob Epperley'>Rob Epperley</li>
    <li data-name='Kieth Lagman'>Kieth Lagman</li>
    <li data-name='Chi Tereska'>Chi Tereska</li>
    <li data-name='Celina Chantler'>Celina Chantler</li>
    <li data-name='Suzanne Aguinaga'>Suzanne Aguinaga</li>
    <li data-name='Madonna Boock'>Madonna Boock</li>
    <li data-name='Rey Gun'>Rey Gun</li>
    <li data-name='Jennie Capata'>Jennie Capata</li>
    <li data-name='Zelma Brunecz'>Zelma Brunecz</li>
    <li data-name='Hubert Yarrito'>Hubert Yarrito</li>
    <li data-name='Ngan Crean'>Ngan Crean</li>
    <li data-name='Claudie Marcou'>Claudie Marcou</li>
    <li data-name='Monte Nicol'>Monte Nicol</li>
    <li data-name='Lane Inacio'>Lane Inacio</li>
    <li data-name='Lenny Alexis'>Lenny Alexis</li>
    <li data-name='Lorene Sistek'>Lorene Sistek</li>
    <li data-name='Brooks Merante'>Brooks Merante</li>
    <li data-name='Rufina Krah'>Rufina Krah</li>
    <li data-name='Bonnie Kieft'>Bonnie Kieft</li>
    <li data-name='Luigi Wahr'>Luigi Wahr</li>
    <li data-name='Brandee Noori'>Brandee Noori</li>
    <li data-name='Gerard Rolson'>Gerard Rolson</li>
    <li data-name='Noriko Buckman'>Noriko Buckman</li>
    <li data-name='Marcella Bathrick'>Marcella Bathrick</li>
    <li data-name='Harlan Michealson'>Harlan Michealson</li>
    <li data-name='Julienne Fuerte'>Julienne Fuerte</li>
    <li data-name='Olivia Ciliberto'>Olivia Ciliberto</li>
    <li data-name='Lorenzo Pollnow'>Lorenzo Pollnow</li>
    <li data-name='Eufemia Crigler'>Eufemia Crigler</li>
    <li data-name='Emogene Tolar'>Emogene Tolar</li>
    <li data-name='Steven Amoriello'>Steven Amoriello</li>
    <li data-name='Stanford Minhas'>Stanford Minhas</li>
    <li data-name='Adolfo Reddick'>Adolfo Reddick</li>
    <li data-name='Michael Flight'>Michael Flight</li>
    <li data-name='Teodora Axtman'>Teodora Axtman</li>
    <li data-name='Takisha Metting'>Takisha Metting</li>
    <li data-name='Johnnie Mullendore'>Johnnie Mullendore</li>
    <li data-name='Dee Prowell'>Dee Prowell</li>
    <li data-name='Joye Skarupa'>Joye Skarupa</li>
    <li data-name='Bernetta Hugel'>Bernetta Hugel</li>
    <li data-name='Jade Capra'>Jade Capra</li>
    <li data-name='Sergio Gieringer'>Sergio Gieringer</li>
    <li data-name='Lorraine Marinez'>Lorraine Marinez</li>
    <li data-name='Eugenia Kreinbring'>Eugenia Kreinbring</li>
    <li data-name='Karin Brackey'>Karin Brackey</li>
    <li data-name='Sona Toothman'>Sona Toothman</li>
    <li data-name='Tresa Sylvester'>Tresa Sylvester</li>
    <li data-name='Emile Mccrate'>Emile Mccrate</li>
    <li data-name='Miranda Coppage'>Miranda Coppage</li>
    <li data-name='Wava Kathan'>Wava Kathan</li>
    <li data-name='Euna Bate'>Euna Bate</li>
    <li data-name='Reina Catalanatto'>Reina Catalanatto</li>
    <li data-name='Jody Barner'>Jody Barner</li>
    <li data-name='Margherita Demopoulos'>Margherita Demopoulos</li>
    <li data-name='Yu Imboden'>Yu Imboden</li>
    <li data-name='Irina Huppenbauer'>Irina Huppenbauer</li>
    <li data-name='Forest Lowenthal'>Forest Lowenthal</li>
    <li data-name='Jamar Loman'>Jamar Loman</li>
    <li data-name='Maurice Kotler'>Maurice Kotler</li>
    <li data-name='Renato Feldstein'>Renato Feldstein</li>
    <li data-name='Dulcie Pinter'>Dulcie Pinter</li>
    <li data-name='Doretta Breiner'>Doretta Breiner</li>
    <li data-name='Mireille Betsinger'>Mireille Betsinger</li>
    <li data-name='Jc Emerton'>Jc Emerton</li>
    <li data-name='Yahaira Klee'>Yahaira Klee</li>
    <li data-name='Glady Annen'>Glady Annen</li>
    <li data-name='Jaime Alicandro'>Jaime Alicandro</li>
    <li data-name='Branda Darnstaedt'>Branda Darnstaedt</li>
    <li data-name='Christiane Kissik'>Christiane Kissik</li>
    <li data-name='Lester Tartamella'>Lester Tartamella</li>
    <li data-name='Nikki Shoaf'>Nikki Shoaf</li>
    <li data-name='Vern Teteak'>Vern Teteak</li>
    <li data-name='Albertha Vankilsdonk'>Albertha Vankilsdonk</li>
    <li data-name='Greg Pesch'>Greg Pesch</li>
    <li data-name='Nam Bahner'>Nam Bahner</li>
    <li data-name='Korey Smit'>Korey Smit</li>
    <li data-name='Brock Arview'>Brock Arview</li>
    <li data-name='Robin Danos'>Robin Danos</li>
    <li data-name='Jonah Shoener'>Jonah Shoener</li>
    <li data-name='Bernardina Michelini'>Bernardina Michelini</li>
    <li data-name='Cody Stachniw'>Cody Stachniw</li>
    <li data-name='Maribeth Benner'>Maribeth Benner</li>
    <li data-name='Louie Codell'>Louie Codell</li>
    <li data-name='Alvera Vallarta'>Alvera Vallarta</li>
    <li data-name='Amy Schmauder'>Amy Schmauder</li>
    <li data-name='Doretha Megee'>Doretha Megee</li>
    <li data-name='Clora Okins'>Clora Okins</li>
    <li data-name='Antoine Colomba'>Antoine Colomba</li>
    <li data-name='Daniell Tramel'>Daniell Tramel</li>
    <li data-name='Marge Sebastian'>Marge Sebastian</li>
    <li data-name='Savannah Ortic'>Savannah Ortic</li>
    <li data-name='Renita Strahan'>Renita Strahan</li>
    <li data-name='Elvia Deerman'>Elvia Deerman</li>
    <li data-name='Kris Bonsal'>Kris Bonsal</li>
    <li data-name='Lili Aulds'>Lili Aulds</li>
    <li data-name='Roman Pessoa'>Roman Pessoa</li>
    <li data-name='Shon Fonsecn'>Shon Fonsecn</li>
    <li data-name='Elmo Mcclain'>Elmo Mcclain</li>
    <li data-name='Brittni Stott'>Brittni Stott</li>
    <li data-name='Byron Syndergaard'>Byron Syndergaard</li>
    <li data-name='Quinn Hach'>Quinn Hach</li>
    <li data-name='Joey Buissereth'>Joey Buissereth</li>
    <li data-name='Benedict Giacobbe'>Benedict Giacobbe</li>
    <li data-name='Merna Ihrke'>Merna Ihrke</li>
    <li data-name='Chase Chryst'>Chase Chryst</li>
    <li data-name='Truman Haroldsen'>Truman Haroldsen</li>
    <li data-name='Carry Elswick'>Carry Elswick</li>
    <li data-name='Raymonde Emrich'>Raymonde Emrich</li>
    <li data-name='Isreal Kieke'>Isreal Kieke</li>
    <li data-name='Fredricka Judy'>Fredricka Judy</li>
    <li data-name='Brendan Brester'>Brendan Brester</li>
    <li data-name='Karin Kitchell'>Karin Kitchell</li>
    <li data-name='Tabitha Han'>Tabitha Han</li>
    <li data-name='Dotty Vandeveer'>Dotty Vandeveer</li>
</ul>
<script src="file:///tmp/s.js"></script>

Basically:

  1. use an attribute to store the value to search within
  2. tailor a custom CSS selector to apply the "display:none" rule
  3. use a bit of JS to feed a "style" tag with your tailored selector and rule

That's it, no more JS hurdle, only CSS doing it's job at lightning speed. Supported in all browsers and you only update 1 hidden element in the page (the "script" tag).

I also have updated your JS fiddle for the example.

查看更多
女痞
4楼-- · 2019-07-18 04:56

As long as you do not query properties that trigger an immediate reflow the browser already batches the updates for you and only relayouts/repaints the page once your javascript is done. You should be able to verify this in the browser devtools.

But there is a trivial optimization for your code: avoid redundant DOM manipulations, especially for elements that are not visible anyway.

The else branch that gets applied for hidden items:

else {
  hideItem(item);
  toPlainText(item);
}

the toPlainText manipulates the DOM even the element will be hidden or already is hidden.

查看更多
一纸荒年 Trace。
5楼-- · 2019-07-18 04:59

Many JS mvvm frameworks such as Reactjs and Vuejs has applied the 'virtual DOM mechanism'.It will batch all DOM updates in one event loop and save you from the penalty of frequent DOM operations.I think you can have a loot at that implementations.

查看更多
ら.Afraid
6楼-- · 2019-07-18 05:08

There's no point in buffering updates to the DOM, the DOM itself does that already just fine before reflowing/rerendering.

What you have to aim for are doing less updates to the DOM, using only cheap interactions, as few interactions as possible (Where "interactions" includes getters). Oh, and never use properties that force a reflow.

500 elements are quite doable, and your first fiddle is already quite responsive for me. In the second, I have identified a few problem zones and possible improvements:

  • innerText is bad. Really bad. It forces a reflow, as it takes into account styling and will not return invisible text (which also did break your fiddle). Use textContent instead.
  • innerHTML is nearly as bad, as it requires the HTML parser to be invoked. 500 times. That can sometimes (for large chunks) be faster than manually updating every part of the DOM, but not here. Instead of destroying and recreating all these tags, keep the elements in the DOM.
  • Debouncing. You're already doing this, but you might want to use requestAnimationFrame instead of a very small setTimeout, so that the DOM is updated only exactly once before it is rendered.
  • Not related to the DOM, but new RegExp is also rather expensive. You only need to call it once, not for every item.
  • Don't query the listItems from the DOM every time the function is called, but cache the array outside of the function like you do for list and search. And you can do even better: Also cache their contents and the style objects, so that you don't have to access them through the DOM.

So once you fix the "Quick hacky way to remove <b>s" (as you documented it yourself), most of the problems should be gone. Here's the gist of my approach:

var search = document.getElementById('s');
var items = Array.from(document.getElementById('l').children, function(li) {
  return {
    text: li.textContent,
    style: li.style,
    pre: li.firstChild, // the text node
    match: li.appendChild(document.createElement("span"))
             .appendChild(document.createTextNode("")),
    post: li.appendChild(document.createTextNode(""))
  };
});

function searchAction() {
  var term = search.value;
  var re = new RegExp(term, 'i'); // case insensitive

  for (var {text, style, pre, match, post} of items) {
    var m = text.match(re);
    if (m) {
      pre.nodeValue = text.slice(0, m.index);
      match.nodeValue = m[0];
      post.nodeValue = text.slice(m.index + m[0].length);
      show(style);
    } else {
      hide(style);
    }
  }
}

See updated fiddle.

查看更多
登录 后发表回答